语言:matlab
画图:plot
通常定义抛物线为到一条直线(准线)和直线外一点(焦点)距离相等的点的集合。这里只讨论顶点为原点,沿纵坐标轴对称且开口向上的情况。而对于其他情况可以通过图形的平移和旋转等线性变换得到。其描述方程如下:
F ( x , y ) = y − a x 2 ( a > 0 ) F(x,y)=y-ax^2(a>0) F(x,y)=y−ax2(a>0)
与椭圆不同,抛物线是无边界的非封闭图形,若要在屏幕上绘制,必须给定坐标范围,以绘制指定抛物线的一个片段。可以在函数中设置参数 x m xm xm,则横坐标约束其范围为 [ − x m , x m ] [-xm,xm] [−xm,xm]。
抛物线关于纵坐标轴对称,故只需绘制其第一象限内的点,第二象限中的点可以通过对称得到。
为确定最大位移方向,考虑抛物线的斜率范围。在第一象限,其上一点 ( x , y ) (x,y) (x,y)处的斜率为:
k ( x ) = ∂ F ( x , y ) ∂ x = 2 a x ∈ [ 0 , + ∞ ) k(x)=\frac{\partial F(x,y)}{\partial x}=2ax \in [0,+\infty) k(x)=∂x∂F(x,y)=2ax∈[0,+∞)
又由于斜率的变化率为:
d k ( x ) d x = d ( 2 a x ) d x = 2 a > 0 \frac {dk(x)}{dx}=\frac {d(2ax)}{dx}=2a>0 dxdk(x)=dxd(2ax)=2a>0
所以在第一象限内,抛物线斜率从0开始随 x x x递增至正无穷。用斜率为1的点对图形进行划分。容易解出,当斜率为1时, x = 1 2 a x=\frac {1}{2a} x=2a1。只需沿 x x x轴绘制图形,其 0 < x < 1 2 a 0
假定当前与抛物线距离最近者已确定为 P ( x i , y i ) P(x_i,y_i) P(xi,yi)那么在抛物线前部分时,下一候选点是 P d ( x i + 1 , y i ) P_d(x_i+1,y_i) Pd(xi+1,yi)和 P d ( x i + 1 , y i + 1 ) P_d(x_i+1,y_i+1) Pd(xi+1,yi+1);而在抛物线的后半部分时,下一候选点是 P l ( x i , y i + 1 ) P_l(x_i,y_i+1) Pl(xi,yi+1)和 P r ( x i + 1 , y i + 1 ) P_r(x_i+1,y_i+1) Pr(xi+1,yi+1)。仍然使用中点进行判别候选点。
对于 0 < x < 1 2 a 0
d l i = F ( x i + 1 , y i + 0.5 ) = y i + 0.5 − a ( x i + 1 ) 2 d_{li}=F(x_i+1,y_i+0.5)=y_i+0.5-a(x_i+1)^2 dli=F(xi+1,yi+0.5)=yi+0.5−a(xi+1)2
若 d l i ≥ 0 d_{li}\ge 0 dli≥0,中点在抛物线上方,应选取 P d ( x i + 1 , y i ) P_d(x_i+1,y_i) Pd(xi+1,yi),反之选取 P u ( x i + 1 , y i + 1 ) P_u(x_i+1,y_i+1) Pu(xi+1,yi+1)。
误差项递推:
在 d l i ≥ 0 d_{li}\ge 0 dli≥0时,应计算:
d l ( i + 1 ) = F ( x i + 2 , y i + 0.5 ) = y i + 0.5 − a ( x i + 2 ) 2 = d l i + a [ ( x i + 1 ) 2 − ( x i + 2 ) 2 ] = d l i − 2 a x i − 3 a d_{l(i+1)}=F(x_i+2,y_i+0.5)\\ =y_i+0.5-a(x_i+2)^2\\ =d_{li}+a[(x_i+1)^2-(x_i+2)^2]\\ =d_{li}-2ax_i-3a\\ dl(i+1)=F(xi+2,yi+0.5)=yi+0.5−a(xi+2)2=dli+a[(xi+1)2−(xi+2)2]=dli−2axi−3a
在 d l i < 0 d_{li}< 0 dli<0时,应计算:
d l ( i + 1 ) = F ( x i + 2 , y i + 1.5 ) = y i + 1.5 − a ( x i + 2 ) 2 = d l i − 2 a x i − 3 a + 1 d_{l(i+1)}=F(x_i+2,y_i+1.5)\\ =y_i+1.5-a(x_i+2)^2\\ =d_{li}-2ax_i-3a+1\\ dl(i+1)=F(xi+2,yi+1.5)=yi+1.5−a(xi+2)2=dli−2axi−3a+1
计算判别式的初始值。弧起点为 ( 0 , 0 ) (0,0) (0,0),因此第一个中点为 ( 1 , 0.5 ) (1,0.5) (1,0.5),对应的判别式为:
d l 0 = y 0 + 0.5 − a ( x 0 + 1 ) 2 = 0.5 − a d_{l0}=y_0+0.5-a(x_0+1)^2=0.5-a dl0=y0+0.5−a(x0+1)2=0.5−a
对于 1 2 a < x < x m \frac {1}{2a}
d r i = F ( x i + 0.5 , y i + 1 ) = y i + 1 − a ( x i + 0.5 ) 2 d_{ri}=F(x_i+0.5,y_i+1)=y_i+1-a(x_i+0.5)^2 dri=F(xi+0.5,yi+1)=yi+1−a(xi+0.5)2
若 d r i ≥ 0 d_{ri}\ge 0 dri≥0,中点在抛物线(左)上方,应选取 P l ( x i , y i + 1 ) P_l(x_i,y_i+1) Pl(xi,yi+1),反之选取 P r ( x i + 1 , y i + 1 ) P_r(x_i+1,y_i+1) Pr(xi+1,yi+1)。
误差项递推:
在 d r i ≥ 0 d_{ri}\ge 0 dri≥0时,应计算:
d r ( i + 1 ) = F ( x i + 0.5 , y i + 2 ) = y i + 2 − a ( x i + 0.5 ) 2 = d r i + 1 d_{r(i+1)}=F(x_i+0.5,y_i+2)\\ =y_i+2-a(x_i+0.5)^2\\ =d_{ri}+1\\ dr(i+1)=F(xi+0.5,yi+2)=yi+2−a(xi+0.5)2=dri+1
在 d r i < 0 d_{ri}< 0 dri<0时,应计算:
d r ( i + 1 ) = F ( x i + 1.5 , y i + 2 ) = y i + 2 − a ( x i + 1.5 ) 2 = d r i − 2 a x i − 2 a + 1 d_{r(i+1)} =F(x_i+1.5,y_i+2)\\ =y_i+2-a(x_i+1.5)^2\\ =d_{ri}-2ax_i-2a+1\\ dr(i+1)=F(xi+1.5,yi+2)=yi+2−a(xi+1.5)2=dri−2axi−2a+1
计算判别式的初始值。弧起点横坐标为 ⌈ 1 2 a ⌉ \lceil \frac{1}{2a} \rceil ⌈2a1⌉,对应的判别式为:
d r 0 = y 0 + 1 − a ( x 0 + 0.5 ) 2 = 1 − a ⌈ 1 2 a ⌉ − 0.25 a d_{r0}=y_0+1-a(x_0+0.5)^2=1-a\lceil \frac{1}{2a} \rceil-0.25a dr0=y0+1−a(x0+0.5)2=1−a⌈2a1⌉−0.25a
function DrawBresenhamCurve(a,xm)
div=0.5/a;
x=0,y=0;
d_pre=0.5-a;
d_post=1-a*ceil(0.5/a)-0.25*a;
while x<=xm
plot(x,y);
hold on;
plot(-x,y);
hold on;
if x