計算機圖形學學習記錄(三)Breseham畫線演算法
阿新 • • 發佈:2019-02-15
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提供了一個更一般的演算法。該演算法不僅有好的效率,而且有更廣泛的適用範圍。
本演算法的主要思想是通過將各行、各列畫素中心構造成一組虛擬網格線,按照直線七點到終點的順序,計算直線與各垂直網格線的交點,然後根據誤差項的符號確定該列畫素中與此交點最近的元素。
假設每次都有 , 的遞增(減)量為0 或者 1, 它取決於實際直線與最近光柵網格點的距離,這個距離的最大誤差為0.5。
誤差項d的初值
一旦有就把它減去1,保證的相對性,且在0、1之間。
可以得到:
那麼問題的關鍵變成了,如何將現在的Breseham演算法提高到整數加法。
我們令 就有:
, 方向遞增1;,方向不遞增。時,可以任意去上、下光柵點顯示。
每走一步有
,
由於演算法中只用到誤差項的符號,於是可以利用來代替
每走一步有