您的位置:电脑爱好者网 » 任庆亮--first » 日志
直线的Bresenham算法
上一篇 / 下一篇 2007-04-07 10:40:13 / 个人分类:还电脑一片纯洁
2.1.2 直线的Bresenham算法
本算法由Bresenham在1965年提出。设直线从起点(x1, y1)到终点(x2, y2)。直线可表示为方程y=mx+b。其中
X8E$MPUPH`0b = y1 - m * x1, 电脑爱好者网 ] p'I.u-es'V
m =![]()
我们的讨论先将直线方向限于1a象限(图2.1.1)在这种情况下,当直线光栅化时,x每次都增加1个单元,即
H\(J)b!|K0xi+1=xi+1
6\$z1h8~+m;Y0而y的相应增加应当小于1。为了光栅化,yi+1只可能选择如下两种位置之一(图2.1.2)。电脑爱好者网z,F(o/rEz:y-i P h*^ X
电脑爱好者网lE#I+y E.V*@5p#e
图2.1.2
.Y*dr&vj-z0vrN4z)o!@:i0
图2.1.2 yi+1的位置选择yi-1=yi 或者 yi+1=yi+1电脑爱好者网$cm(xPL
u(VU|D n/G Y}V)x0选择的原则是看精确值y与yi及yi+1的距离d1及d2的大小而定。计算式为:电脑爱好者网l Vd)UI!j z2S(O
y=m(xi+1)+b (2.1.1)电脑爱好者网J2Ac0O0Z6B.VKs
d1=y-yi (2.1.2)
T3Ed5`;a&KDq+n0d2=yi+1-y (2.1.3)电脑爱好者网YOn0Yw"Z%oZ
如果d1-d2>0,则yi+1=yi+1,否则yi+1=yi。因此算法的关键在于简便地求出d1-d2的符号。将式(2.1.1)、(2.1.2)、(2.1.3)代入d1-d2,得电脑爱好者网s*~F,Tp UL6[5Y.Dk
d1-d2=2y-2yi-1=2
(xi+1)-2yi+2b-1电脑爱好者网1]x0}^9zL0f
用dx乘等式两边,并以Pi=dx(d1-d2)代入上述等式,得电脑爱好者网J w;Ba$J
Pi=2xidy-2yidx+2dy+dx(2b-1) (2.1.4)电脑爱好者网s Z6}0I1lfgo.u^
d1-d2是我们用以判断符号的误差。由于在1a象限,dx总大于0,所以Pi仍旧可以用作判断符号的误差。Pi-1为:
q+Z ll#FoZT0Pi+1=Pi+2dy-2dx(yi+1-yi) (2.1.5)
wu[ c0EXD m0误差的初值P1,可将x1, y1,和b代入式(2.1.4)中的xi, yi而得到:电脑爱好者网0S;}-PtS)}E cw
P1=2dy-dx
Oc6l1L$H@L0综述上面的推导,第1a象限内的直线Bresenham算法思想如下:电脑爱好者网(@E}~(Z+xd-N3I jB
_7}9qQ l0q&@N6y8U0
1、画点(x1, y2); dx=x2-x1; dy=y2-y1;
itC]}y5c1~0计算误差初值P1=2dy-dx; i=1;电脑爱好者网r u$\/Bi*T#\
2、求直线的下一点位置:电脑爱好者网Qz7h|7sEW'[
xi+1=xi+1;电脑爱好者网+WR1L$^]q_l
if Pi>0 则yi+1=yi+1;
6I-\e3H2M7_6Y0否则yi+1=yi;电脑爱好者网+dz? p?
3、画点(xi+1, yi-1);电脑爱好者网5GzA#\aB3E5I:j(c
4、求下一个误差Pi+1;电脑爱好者网fv?C%s"z:W'[
if Pi>0 则Pi+1=Pi+2dy-2dx;电脑爱好者网)N0R'yeq8q&_4Y8pH
否则Pi+1=Pi+2dy;
q#A(E0t.g2a#J0U@L05、i=i+1; if i<dx+1则转2;否则end。
l wnG_i6{(sD0
Bresenham算法的优点是:电脑爱好者网U#n+K,Yk6w4p
1、不必计算直线之斜率,因此不做除法;电脑爱好者网4Sd7DQKC
2、不用浮点数,只用整数;电脑爱好者网1U3\C6G@F {T`&P
3、只做整数加减法和乘2运算,而乘2运算可以用硬件移位实现。
"y H)Iccw&l9Q"lG0Bresenham算法速度很快,并适于用硬件实现。电脑爱好者网6p:zl `1aE
电脑爱好者网1y A(I9[]1L!k
由上述算法思想编制的程序如程序2.1.2。这个程序适用于所有8个方向的直线(图2.1.1)的生成。程序用色彩C画出一条端点为(x1, y1)和(x2, y2)的直线。其中变量的含义是:P是误差;const1和const2,是误差的逐点变化量;inc是y的单位递变量,值为1或-1;tmp是用作象限变换时的临时变量。程序以判断|dx|>|dy|为分支,并分别将2a, 3a象限的直线和3b, 4b象限的直线变换到1a, 4a和2b, 1b方向去,以求得程序处理的简洁。电脑爱好者网 hLZ!j&iQo-bR^
void line (x1, y1, x2, y2, c)电脑爱好者网Ln#Ah9{B.F*Fc#G/~y
int x1, y1, x2, y2, c;
w)fXQ/V C j0{电脑爱好者网(R#DeT)ov&O$E
int dx;电脑爱好者网{X VsKfO,C
int dy;
Ed%JBf,v#Wq$D;\ _0int x;电脑爱好者网(Egi^Gw |E~2~&Rv
int y;
%K uxde3b6U0int p;
!DG-Cz q8wD0int const1;电脑爱好者网 P~%[;N5{;@3K,lh
int const2;电脑爱好者网@n un"Y7W}&Jd
int inc;电脑爱好者网/ps#\&mr~
int tmp;
i sz3R9R$\Wa#u*V0dx=x2-x1;
wY)[ L'?x K\0dy=y2-y1;电脑爱好者网N U L/pPv
if (dx*dy>=0) /*准备x或y的单位递变值。*/
$Q1w)?4?Q+tC0inc=1;
.h0f.I v(Z'Hx*T]0else电脑爱好者网0BfF&T&DY2I
inc=-1;电脑爱好者网DX8Lla8R N
if (abs(dx)>abs(dy)){
c Hm6O3tXQU9v0if(dx<0){电脑爱好者网j3i`E2D+U {!l(yt
tmp=x1; /*将2a, 3a象限方向*/电脑爱好者网s4l*q!J8N'\)Nw GHV7H
x1=x2; /*的直线变换到1a, 4a*/电脑爱好者网jhG9X$x9S({x
x2=tmp;电脑爱好者网K'h5E9C:? I^H
tmp=y1; /*象限方向去*/
#nX8A ^jYO0y1=y2;