Bresenham快速畫直線算法

轉載博文原址:http://www.cnblogs.com/pheye/archive/2010/08/14/1799803.html

算法原理的詳細描述及部分實現可參考:

http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html

    Fig. 1

   假設以(x, y)爲繪製起點,一般情況下的直觀想法是先求m = dy /dx(即x每增加1 y的增量),然後逐步遞增x, 設新的點爲x1 = x + j, y1 = round(y + j * m)。可以看到,這個過程涉及大量的浮點運算,效率上是比較低的(特別是在嵌入式應用中,DSP可以一週期內完成2次乘法,一次浮點卻要上百個週期)。

       下面,我們來看一下Bresenham算法,如Fig. 1,(x, y +ε)的下一個點爲(x, y + ε + m),這裏ε爲累加誤差。可以看出,當ε+m < 0.5時,繪製(x + 1, y)點,否則繪製(x + 1, y + 1)點。每次繪製後,ε將更新爲新值:

            ε = ε + m ,如果(ε + m) <0.5 (或表示爲2*(ε + m) < 1)

            ε = ε + m – 1, 

其他情況將上述公式都乘以dx, 並將ε*dx用新符號ξ表示,可得

            ξ = ξ + dy, 如果2*(ξ + dy) < dx

            ξ = ξ + dy – dx, 其他情況

可以看到,此時運算已經全變爲整數了。以下爲算法的僞代碼:

            ξ ← 0, y ← y1

            For x ← x1 to x2 do

                Plot Point at (x, y)

                If (2(ξ + dy) < dx)

                    ξ ←ξ + dy

                Else

                    y ← y + 1,ξ ←ξ + dy – dx

                End If

            End For

二、             算法的注意點:

Fig. 2

在實際應用中,我們會發現,當dy > dx或出現Fig.2 右圖情況時時,便得不到想要的結果,這是由於我們只考慮dx > dy x, y的增量均爲正的情況所致。經過分析,需要考慮8種不同的情況,如Fig. 3所示:

        

(Fig. 3)

當然,如果直接在算法中對8種情況分別枚舉, 那重複代碼便會顯得十分臃腫,因此在設計算法時必須充分考慮上述各種情況的共性,後面將給出考慮了所有情況的實現代碼。

三、             算法的實現

以下代碼的測試是利用Opencv 2.0進行的,根據需要,只要稍微修改代碼便能適應不同環境

    void DrawLine(IplImage *img, int x1, int y1, int x2, int y2)
{
     int dx = x2 - x1;
     int dy = y2 - y1;
     int ux = ((dx > 0) << 1) - 1;//x的增量方向,取或-1
     int uy = ((dy > 0) << 1) - 1;//y的增量方向,取或-1
     int x = x1, y = y1, eps;//eps爲累加誤差

     eps = 0;dx = abs(dx); dy = abs(dy); 
     if (dx > dy) 
     {
         for (x = x1; x != x2; x += ux)
         {
              SetPixel(img, x, y);
              eps += dy;
              if ((eps << 1) >= dx)
              {
                   y += uy; eps -= dx;
              }
         }
     }
     else
     {
         for (y = y1; y != y2; y += uy)
         {
              SetPixel(img, x, y);
              eps += dx;
              if ((eps << 1) >= dy)
              {
                   x += ux; eps -= dy;
              }
         }
     }             
}

發佈了35 篇原創文章 · 獲贊 25 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章