1 算法原理
基本原理從某處摘得:設直線方程為yi+1=yi+k(xi+1-xi)+k。假設列坐標象素已經確定為xi,其行坐標為yi。那么下一個象素的列坐標為xi+1,而行坐標要么為yi,要么遞增1為yi+1。是否增1取決於誤差項d的值。誤差項d的初值d0=0,x坐標每增加1,d的值相應遞增直線的斜率值k,即d=d+k。一旦d≥1,就把它減去1,這樣保證d在0、1之間。當d≥0.5時,直線與垂線x=xi+1交點最接近於當前象素(xi,yi)的右上方象素(xi+1,yi+1);而當d<0.5時,更接近於右方象素(xi+1,yi)。為方便計算,令e=d-0.5,e的初值為-0.5,增量為k。當e≥0時,取當前象素(xi,yi)的右上方象素(xi+1,yi+1);而當e<0時,取(xi,yi)右方象素(xi+1,yi)。
由於顯示直線的像素點只能取整數值坐標,可以假設直線上第i個像素點的坐標為(Xi,Yi),它是直線上點(Xi,Yi)最佳近似,並且Xi=Xi(假設m<1),如下圖所示.那么直線上下一個像素點的可能位置是(Xi+1,Yi)或者(Xi+1,Yi+1).
由圖可知:在x=Xi+1處,直線上的點y的值是:y=m(Xi+1)+b,該點離像素點(Xi+1,Yi)和像素點(Xi+1,Yi+1)的距離分別為d1和d2。
d1 = Y - Yi = m(Xi+1)+b - Yi; (1)
d2 = (Yi+1) - Y = (Yi+1) - m(Xi+1) - b; (2)
兩個距離的差是:
d1-d2 = 2m(Xi+1) - 2Yi + 2b -1; (3)
對於公式(3):
a:當此值為正時,d1>d2,說明直線上理論點離(Xi+1,Yi+1)像素較近,下一個像素點應取(Xi+1,Yi+1);
b:當此值為負時,d1<d2,說明直線上理論點離(Xi+1,Yi)像素較近,下一個像素點贏取(Xi+1,Yi);
c:當此值為零時,d1=d2,說明直線上理論點離上、下兩個像素點的距離相等,取那個點都行,假設算法規定這種情況下取(Xi+1,Yi+1)作為下一個像素點。
因此只要利用(d1-d2)的符號就可以決定下一個像素點的選擇。需進一步定義一個判別式:
Pi = △X × (d1-d2) = 2△Y·Xi - 2△X·Yi + c (4)
其中△X=(X2-X1)>0,因此Pi與(d1-d2)有相同的符號;
△Y=Y2-Y1;m=△Y/△X;c=2△Y+△X(2b-1)
對(4)進一步處理得出誤差判別遞推公式並消除常數c;
將(4)中的下標i改為i+1,得到:
Pi+1 = △X × (d1-d2) = 2△Y·Xi+1 - 2△X·Yi+1 + c (5)
假設直線的初始端點恰好是其像素點的坐標,即滿足:
Y1 = mX1 + b ; (6)
由公式(4)和(6)得到p1的初始值:
P1 = 2△Y - △X; (7)
/*推導過程*/ Pi = △X × (d1-d2) = 2△Y·Xi - 2△X·Yi + c (4) Y1 = mX1 + b (6) P1 = 2△Y·X1 - 2△X·Y1 + c = 2△Y·X1 - 2△X·(△Y/△X·X1+b) + c = 2△Y·X1 - 2△Y·X1 - 2△X·b + c = c - 2△X·b = 2△Y+△X(2b-1) - 2△X·b = 2△Y - △X
所以可以用誤差判別變量,得到如下算法表示:
初始:P1 = 2△Y - △X (8)
當Pi>=0時:Yi+1 = Yi + 1,Xi+1 = Xi + 1,Pi+1 = Pi + 2(△Y-△X)[根據公式(4)和(5)得出];
/*推導過程*/ Pi = △X × (d1-d2) = 2△Y·Xi - 2△X·Yi + c (4) Pi+1 = △X × (d1-d2) = 2△Y·Xi+1 - 2△X·Yi+1 + c (5) (4)-(5)得: Pi+1 = Pi + (2△Y·Xi+1)-2△Y·Xi - (2△X·Yi+1)+2△X·Yi ∵ Pi>0 時 Yi+1 = Yi + 1,Xi+1 = Xi + 1 ∴ Pi+1 = Pi + (2△Y·(Xi + 1))-2△Y·Xi - (2△X·(Yi + 1))+2△X·Yi = Pi + 2(△Y-△X)
否則:Yi+1 = Yi,Xi+1=Xi + 1,Pi+1=Pi+2△y[根據公式(4)和(5)得出]
/*推導過程*/ Pi = △X × (d1-d2) = 2△Y·Xi - 2△X·Yi + c (4) Pi+1 = △X × (d1-d2) = 2△Y·Xi+1 - 2△X·Y(i+1) + c (5) (4)-(5)得: Pi+1 = Pi + (2△Y·Xi+1)-2△Y·Xi - (2△X·Yi+1)+2△X·Yi ∵ Pi>0 時 Yi+1 = Yi,Xi+1 = Xi + 1 ∴ Pi+1 = Pi + (2△Y·(Xi + 1))-2△Y·Xi - (2△X·(Yi))+2△X·Yi = Pi + 2△Y
從(8)式可以看出,第i+1步的判別變量Pi+1僅與第i步的判別變量Pi、直線的兩個端點坐標分量差△X和△Y有關,運算中只含有整數相加和乘2運算,而乘2可利用算術左移一位來完成,因此這個算法速度快並易於硬件實現。