一、數字微分分析儀(digital differential analyzer, DDA)方法是一種線段掃描轉換算法。在一個坐標軸上以單位間隔對線段取樣,從而確定另一個坐標軸上最靠近線路徑的對應整數值。主要是根據直線公式y = kx + b來推導出來的,其關鍵之處在於如何設定單位步進,即一個方向的步進為單位步進,另一個方向的步進必然是小於1。
算法過程:
輸入線段兩個端點的像素位置,端點位置間的水平和垂直差賦給參數dx和dy。絕對值大的參數確定steps的值。從像素位置(xBegin,yBegin)開始,確定沿線段生成下一個像素位置的每一步所需的偏移量,並循環上述過程setps次。假如dx的絕對值大於dy的絕對值,且xBegin小於xEnd,那么x和y方向的增量值分別為1和m。假如x方向的變化較大,但xBegin大於xEnd,那么就采用減量-1和-m來生成線段上的每個點。在其他情況下,y方向使用單位增量(或減量),x方向使用1/m的增量(或減量)。
1 inline int Round(const float a) { return static_cast<int>(a + 0.5); } 2 3 void LineDDA(int xBegin, int yBegin, int xEnd, int yEnd) 4 { 5 int dx = xEnd - xBegin; 6 int dy = yEnd - yBegin; 7 int steps, k; 8 9 float xIncrement, yIncrement; 10 float x = static_cast<int>(xBegin); 11 float y = static_cast<int>(yBegin); 12 13 if (fabs(dx) > fabs(dy)) { 14 steps = fabs(dx); 15 } 16 else { 17 steps = fabs(dy); 18 } 19 20 xIncrement = static_cast<float>(dx) / static_cast<float>(steps); 21 yIncrement = static_cast<float>(dy) / static_cast<float>(steps); 22 23 glBegin(GL_POINTS); 24 25 for (k = 0; k < steps; ++k) { 26 x += xIncrement; 27 y += yIncrement; 28 glVertex2i(round(x), round(y)); 29 } 30 glEnd(); 31 }
二、Bresenham畫線算法是一種精確而有效的光柵線生成算法,該算法僅僅使用了增量整數計算。

在取樣位置
,用
和
來標識兩個像素與數學上線路徑的垂直偏移。在像素列位置
處的直線上的
坐標可計算為

那么

和
要確定兩像素中哪一個更接近線路徑,需測試兩個像素偏移的差:

令 

則 
相減可得到

因 
算法過程:
時的Bresenham畫線算法:
1.輸入線段的兩個端點,並將左端點存儲在(xBegin, yBegin)中;
2.將(xBegin, yBegin)裝入幀緩存,畫出第一個點;
3.計算常量
、
、
和
,並得到決策參數的第一個值:

4.從
開始,在沿線路徑的每個
處,進行下列檢測:
如果
,下一個要繪制的點是
,並且

否則,下一個要繪制的點是
,並且

5.重讀步驟4,共次
;
1 void LineBresenham(int xBegin, int yBegin, int xEnd, int yEnd) 2 { 3 int dx = fabs(xEnd - xBegin); 4 int dy = fabs(yEnd - yBegin); 5 6 7 int p = 2 * dy - dx; 8 int two_dy = 2 * dy; 9 int two_dy_minus_dx = 2 * (dy - dx); 10 int x, y; 11 int yName; 12 13 if (xBegin > xEnd) { 14 yName = yBegin - yEnd; 15 x = xEnd; 16 y = yEnd; 17 xEnd = xBegin; 18 } 19 else { 20 yName = yEnd - yBegin; 21 x = xBegin; 22 y = yBegin; 23 } 24 while (x <= xEnd) { 25 glBegin(GL_POINTS); 26 glVertex2i(x, y); 27 glEnd(); 28 29 if (dx == 0 && y < yEnd) { 30 y++; 31 continue; 32 } 33 if (p < 0) { 34 x++; 35 p += two_dy; 36 } 37 else if (yName > 0) { 38 y++; 39 x++; 40 p += two_dy_minus_dx; 41 } 42 else if (yName < 0) { 43 y--; 44 x++; 45 p += two_dy_minus_dx; 46 } 47 } 48 }
