1. 程式人生 > >計算機圖形學學習記錄(三)Breseham畫線演算法

計算機圖形學學習記錄(三)Breseham畫線演算法

Breseham演算法

首先為了方便直接看演算法程式碼的朋友直接看核心程式碼和結果,在這裡直接貼出演算法程式碼。

void DDADrawLine::BreasehamDrawLine(int x0, int y0, int x1, int y1)
{
    int iTag = 0;
    int dx, dy, tx, ty, inc1, inc2, d, curx, cury;
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_POINTS);
    glVertex2i(x0, y0);
    glEnd();
    if (x0 == x1 && y0 == y1)
    {
        return
; } dy = abs(y1 - y0); dx = abs(x1 - x0); if (dx < dy) { iTag = 1; Swap(x0, x1); Swap(x1, y1); Swap(dx, dy); } tx = ((x1 - x0) > 0) ? 1 : -1; ty = ((y1 - y0) > 0) ? 1 : -1; curx = x0; cury = y0; inc1 = 2 * dy; inc2 = 2 * (dy - dx); d = inc1 - dx; while
(curx != x1) { curx += tx; if (d < 0) { d += inc1; } else { cury += ty; d += inc2; } if (iTag) { glBegin(GL_POINTS); glVertex2i(cury, curx); glEnd(); } else
{ glBegin(GL_POINTS); glVertex2i(curx, cury); glEnd(); } } }

相關獲得的結果是:

這裡寫圖片描述

演算法原理

DDA把演算法效率提高到每步只做一個加法。
中點演算法進一步把效率提高到每步只做一個整數加法。
Bresenham提供了一個更一般的演算法。該演算法不僅有好的效率,而且有更廣泛的適用範圍。

這裡寫圖片描述

本演算法的主要思想是通過將各行、各列畫素中心構造成一組虛擬網格線,按照直線七點到終點的順序,計算直線與各垂直網格線的交點,然後根據誤差項的符號確定該列畫素中與此交點最近的元素。
這裡寫圖片描述

假設每次都有x+1y 的遞增(減)量為0 或者 1, 它取決於實際直線與最近光柵網格點的距離,這個距離的最大誤差為0.5。
誤差項d的初值d0=0

d=d+k

一旦有d1就把它減去1,保證d的相對性,且在0、1之間。
這裡寫圖片描述
可以得到:

{xi+1=xi+1yi+1={yi+1ifd>0.5yiifd0.5

那麼問題的關鍵變成了,如何將現在的Breseham演算法提高到整數加法。
我們令 e=d0.5 就有:

{xi+1=xi+1yi+1={yi+1ife>0yiife0

e>0 , y方向遞增1;e<0y方向不遞增。e=0時,可以任意去上、下光柵點顯示。

e=0.5
每走一步有e=e+k
if(e>0)
e=e1
e=0.5 , k=dydx
由於演算法中只用到誤差項的符號,於是可以利用e2Δx來代替e
e=Δx
每走一步有e=e+2Δy
if(e>0)
e=e2Δx