DDA與Bresenham畫線算法


一、數字微分分析儀(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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM