在光栅显示器的荧光屏上生成一个对象,实质上是往帧缓存寄存器的相应单元中填入数据。画一条从(x1, y1)到(x2, y2)的直线,实质上是一个发现最佳逼近直线的象素序列,并填入色彩数据的过程。这个过程也称为直线光栅化。
直线的DDA算法
DDA是数字微分分析式(Digital Differential Analyzer)的缩写。设直线之起点为(x1,y1),终点为(x2,y2),则斜率m为:
m = (y2-y1)/(x2-x1)=dy/dx
直线中的每一点坐标都可以由前一点坐标变化一个增量(Dx, Dy)而得到,即表示为递归式:
xi+1=xi+Dx
yi+1=yi+Dy
并有关系:Dy = m · Dx
递归式的初值为直线的起点(x1, y1),这样,就可以用加法来生成一条直线。具体方法是:
图
表
象限
|
|dx|>|dy|?
|
D x
|
D y
|
1b
2b
3b
4b
|
Ö
´
Ö
´
Ö
´
Ö
´
|
1
1/m
-1
-1/m
-1
-1/m
1
1/m
|
m
1
m
1
-m
-1
-m
-1
|
按照直线从(x1,y1)到(x2,y2)的方向不同,分为8个象限(图
研究表中的数据,可以发现两个规律:
1、当|dx|>|dy|时
|D x|=1, |D y|=m;
否则:
Dx=1/m,|Dy|=1
2、Dx, Dy的符号与dx, dy的符号相同。
这两条规律可以导致程序的简化。由上述方法写成的程序如程序
使用DDA算法,每生成一条直线做两次除法,每画线中一点做两次加法。因此,用DDA法生成直线的速度是相当快的。
直线的Bresenham算法
本算法由Bresenham在1965年提出。设直线从起点(x1, y1)到终点(x2, y2)。直线可表示为方程y=mx+b。其中
b = y1 - m * x1,
m = (y2-y1)/(x2-x1)=dy/dx
我们的讨论先将直线方向限于
xi+1=xi+1。而y的相应增加应当小于1。为了光栅化,yi+1只可能选择如下两种位置之一。
yi+1的位置选择yi+1=yi 或者 yi+1=yi+1。选择的原则是看精确值y与yi及yi+1的距离d1及d2的大小而定。计算式为:
y=m(xi+1)+b (
d1=y-yi (
d2=yi+1-y (
如果d1-d2>0,则yi+1=yi+1,否则yi+1=yi。因此算法的关键在于简便地求出d1-d2的符号。将式(
d1-d2=2y-2yi-1=2(dy/dx) (xi+1)-2yi+2b-1
用dx乘等式两边,并以Pi=dx(d1-d2)代入上述等式,得
Pi=2xidy-2yidx+2dy+dx(2b-1) (
d1-d2是我们用以判断符号的误差。由于在
Pi+1=Pi+2dy-2dx(yi+1-yi) (
误差的初值P1,可将x1, y1,和b代入式(
P1=2dy-dx
综述上面的推导,第1a象限内的直线Bresenham算法思想如下:
1、画点(x1, y2); dx=x2-x1; dy=y2-y1;
计算误差初值P1=2dy-dx; i=1;
2、求直线的下一点位置:
xi+1=xi+1;
if Pi>0 则yi+1=yi+1;
否则yi+1=yi;
3、画点(xi+1, yi-1);
4、求下一个误差Pi+1;
if Pi>0 则Pi+1=Pi+2dy-2dx;
否则Pi+1=Pi+2dy;
5、i=i+1; if i<dx+1则转2;否则end。
Bresenham算法的优点是:
1、不必计算直线之斜率,因此不做除法;
2、不用浮点数,只用整数;
3、只做整数加减法和乘2运算,而乘2运算可以用硬件移位实现。
Bresenham算法速度很快,并适于用硬件实现。
由上述算法思想编制的程序如程序