概述
抛物线 f ( x ) = a x 2 f(x)=ax^2 f(x)=ax2的中点Bresenham算法
语言:matlab
画图:plot
1 抛物线的特征
通常定义抛物线为到一条直线(准线)和直线外一点(焦点)距离相等的点的集合。这里只讨论顶点为原点,沿纵坐标轴对称且开口向上的情况。而对于其他情况可以通过图形的平移和旋转等线性变换得到。其描述方程如下:
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<x<frac {1}{2a} 0<x<2a1时,最大位移方向为 x x x方向; 1 2 a < x < x m frac {1}{2a}<x<xm 2a1<x<xm时,最大位移方向为 y y y方向。
2 算法推导过程
假定当前与抛物线距离最近者已确定为 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)。仍然使用中点进行判别候选点。
2.1 推导前半部分的抛物线绘制公式
对于
0
<
x
<
1
2
a
0<x<frac {1}{2a}
0<x<2a1:构造判别式
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
2.2 推导后半部分的抛物线绘制公式
对于
1
2
a
<
x
<
x
m
frac {1}{2a}<x<xm
2a1<x<xm:构造判别式
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-alceil frac{1}{2a} rceil-0.25a
dr0=y0+1−a(x0+0.5)2=1−a⌈2a1⌉−0.25a
算法代码(matlab)
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<div
tmp=-2*a*x-3*a;
x++;
if d_pre<0
y++;
d_pre=d_pre+tmp+1;
else
d_pre=d_pre+tmp;
endif
else
tmp=-2*a*x-2*a+1;
y++;
if d_post<0
d_post=d_post+1;
else
d_post=d_post+tmp;
x++;
endif
endif
endwhile
end
运行情况:
测试代码:
a=0.01;
xm=100;
DrawBresenhamCurve(a,xm);
X=linspace(-xm,xm,1000);
Y=a.*X.^2.;
plot(X,Y);
grid on;
运行结果(点为算法生成的点集,曲线为所拟合的实际曲线):
最后
以上就是闪闪柚子为你收集整理的计算机图形学-抛物线的中点Bresenham算法抛物线 f ( x ) = a x 的全部内容,希望文章能够帮你解决计算机图形学-抛物线的中点Bresenham算法抛物线 f ( x ) = a x 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复