設(x1,y1)和(x2,y2)分別爲所求直線的起點和終點座標,由直線的微分方程得
= m =直線的斜率 | (2-1) |
可通過計算由x方向的增量△x引起y的改變來生成直線:
xi+1=xi+△x | (2-2) |
yi+1=yi+△y=yi+△x·m | (2-3) |
也可通過計算由y方向的增量△y引起x的改變來生成直線:
yi+1=yi+△y | (2-4) |
xi+1=xi+△x=xi+△y/m | (2-5) |
式(2-2)至(2-5)是遞推的。
選定x2-x1和y2-y1中較大者作爲步進方向(假設x2-x1較大),取該方向上的增量爲一個象素單位(△x=1),然後利用式(2-1)計算另一個方向的增量(△y=△x·m=m)。通過遞推公式(2-2)至(2-5),把每次計算出的(xi+1,yi+1)經取整後送到顯示器輸出,則得到掃描轉換後的直線。
之所以取x2-x1和y2-y1中較大者作爲步進方向,是考慮沿着線段分佈的象素應均勻,這在下圖中可看出。
另外,算法實現中還應注意直線的生成方向,以決定Δx及Δy是取正值還是負值。
1、已知直線的兩端點座標:(x1,y1),(x2,y2)
2、已知畫線的顏色:color
3、計算兩個方向的變化量:dx=x2-x1
dy=y2-y1
4、求出兩個方向最大變化量的絕對值:
steps=max(|dx|,|dy|)
5、計算兩個方向的增量(考慮了生成方向):
xin=dx/steps
yin=dy/steps
6、設置初始象素座標:x=x1,y=y1
7、用循環實現直線的繪製:
for(i=1;i<=steps;i++)
{ putpixel(x,y,color);/*在(x,y)處,以color色畫點*/
x=x+xin;
y=y+yin;
}
該算法簡單,實現容易,但由於在循環中涉及實型數的運算,因此生成直線的速度較慢。
下面給出考慮不同斜率、不同方向直線的DDA畫線算法程序:
#include <math.h> void DDALine(int x1, int y1, int x2, int y2, int color) { float increx,increy,x,y; int steps,i; if(abs(x2-x1)>abs(y2-y1)) steps= abs(x2-x1); else steps= abs(y2-y1); increx=(float)(x2-x1)/steps; increy=(float)(y2-y1)/steps; x=x1; y=y1; for(i=1;i<=steps;i++) { putpixel(x,y,color); //在(x,y)處,以color色畫點 x+=increx; y+=increy; } } |