Bresenham算法


一 Bresenham 繪直線

    使用 Bresenham 算法,可以在顯示器上繪制一直線段。該算法主要思想如下:

    1 給出直線段上兩個端點 ,根據端點求出直線在X,Y方向上變化速率 

    2 當 時,X 方向上變化速率快於 Y 方向上變化速率,選擇在 X 方向上迭代,在每次迭代中計算 Y 軸上變化;

       當  時,Y 方向上變化速率快於 X 方向上變化速率,選擇在 Y 方向上迭代,在每次迭代中計算 X 軸上變化;

    3 現在僅考慮  情形,在  情況下僅需要交換變量即可。直線斜率 ,當 d = 0 時,為一條水平直線,當 d > 0 或 d < 0 時,需要分開討論,如下圖:

       

 

二 Bresenham 繪圓

    使用 Bresenham 繪制圓形,只需要繪制四分之一圓即可,其他部分通過翻轉圖形即可得到。假設圓心位於 (0, 0) 點,半徑為  R,繪制第一象限四分之一圓形,如下圖:

      

    根據圖形可知,從  出發,下一個可能的選擇分別為:

    1)水平方向上  

    2)對角方向上 

    3)垂直方向上 

    下面計算,根據差值可判斷大致圓弧位置:

 

    1)當  時,圓環落在  與  之間,進一步計算圓弧到  與  的距離以判斷應該落在哪個點上;

    2)

         由於 ,上式可化簡為,

         ,將  改寫為  得:

         

        已知 ,可根據上式快速求解出 ,當 時,下一點落在  上,當  時,下一點落在  上;

    3)當  時,圓環落在  與  之間,進一步計算圓弧到  的距離以判斷應該落在哪個點上;

    4),可化簡為:

         ,將  改寫為  得:

        

       已知 ,可根據上式快速求解出 ,當 時,下一點落在 上,當  時,下一點落在  上;

    5)以上推導中,已知  可以快速求解 ,同時,已知  也可以快速推導出 ,以下分類討論:

         a. 當 時,有:

             ,進一步整理得:

            

        b. 當  時,有:

            ,進一步整理得:

          

       c. 當  時,有:

           ,進一步整理得:

           

    以下給出 Bresenham 繪圓實現:

      

 1     void Bresenham_Circle(PairS center, int radius, std::vector<PairS>& circle)
 2     {
 3         PairS start(0, radius);
 4         int Delta = (start.x + 1) * (start.x + 1) +
 5             (start.y - 1) * (start.y - 1) - radius * radius;
 6 
 7         std::vector<PairS> tmp;
 8         tmp.push_back(start);
 9 
10         while (start.y > 0)
11         {
12             int state = -1;
13 
14             if (Delta < 0)
15             {
16                 int delta = (Delta + start.y) * 2 - 1;
17                 if (delta < 0)
18                 {
19                     start.x += 1;
20                     state = 0;
21                 }
22                 else
23                 {
24                     start.x += 1;
25                     start.y -= 1;
26                     state = 1;
27                 }
28             }
29             else
30             {
31                 int delta = (Delta - start.x) * 2 - 1;
32                 if (delta < 0)
33                 {
34                     start.x += 1;
35                     start.y -= 1;
36                     state = 1;
37                 }
38                 else
39                 {
40                     start.y -= 1;
41                     state = 2;
42                 }
43             }
44 
45             if (state == 0)
46                 Delta = Delta + start.x * 2 + 1;
47             else if (state == 1)
48                 Delta = Delta + start.x * 2 - start.y * 2, +2;
49             else if (state == 2)
50                 Delta = Delta - start.y * 2 + 1;
51             else
52                 break;
53 
54             tmp.push_back(start);
55         }
56 
57         std::vector<PairS> tmp2;
58         for (int i = 0; i < tmp.size(); ++i)
59         {
60             PairS p(tmp[i].x, tmp[i].y);
61             tmp2.push_back(p);
62         }
63         for (int i = tmp.size() - 1; i >= 0; --i)
64         {
65             PairS p(tmp[i].x, -tmp[i].y);
66             tmp2.push_back(p);
67         }
68         for (int i = 0; i < tmp2.size(); ++i)
69         {
70             PairS p(tmp2[i].x, tmp2[i].y);
71             circle.push_back(p);
72         }
73 
74         for (int i = tmp2.size() - 1; i >= 0; --i)
75         {
76             PairS p(-tmp2[i].x, tmp2[i].y);
77             circle.push_back(p);
78         }
79 
80         for (int i = 0; i < circle.size(); ++i)
81         {
82             circle[i].x += center.x;
83             circle[i].y += center.y;
84         }
85     }

 

 

    參考資料 計算機圖形學得算法基礎    David E Rogers


免責聲明!

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



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