我是靠谱客的博主 闪闪柚子,这篇文章主要介绍计算机图形学-抛物线的中点Bresenham算法抛物线 f ( x ) = a x ,现在分享给大家,希望可以做个参考。

抛物线 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)=yax2(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)=xF(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.5a(xi+1)2
d l i ≥ 0 d_{li}ge 0 dli0,中点在抛物线上方,应选取 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 dli0时,应计算:
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.5a(xi+2)2=dli+a[(xi+1)2(xi+2)2]=dli2axi3a
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.5a(xi+2)2=dli2axi3a+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.5a(x0+1)2=0.5a

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+1a(xi+0.5)2
d r i ≥ 0 d_{ri}ge 0 dri0,中点在抛物线(左)上方,应选取 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 dri0时,应计算:
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+2a(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+2a(xi+1.5)2=dri2axi2a+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+1a(x0+0.5)2=1a2a10.25a

算法代码(matlab)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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

运行情况:

测试代码:

复制代码
1
2
3
4
5
6
7
8
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算法抛物线 内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部