電腦圖形學之掃描轉換直線-DDA,Bresenham,中點畫線演算法

來源:互聯網
上載者:User

標籤:while   順序   a演算法   class   假設   來替   content   void   different   

1.DDA演算法

DDA(Digital Differential Analyer):數字微分法

DDA演算法思想:增量思想

公式推導:

效率:採用了浮點加法和浮點顯示是需要取整

代碼:

void lineDDA(int x0, int y0, int x1, int y1, int color){    int x;    float dy, dx, y, m;    dx = x1 - x0;    dy = y1 - y0;    m = dy / dx;    y = y0;    for (x = x0; x <= x1; x++){        putpixel(x, (int)(y + 0.5), color);        y += m;    }}

2.中點畫線法

採用了直線的一般式:Ax+By+C=0

當k在(0,1]中時,每次在x方向上加1,y方向上加1或不變:

當Q在M上方時,取Pu點;

當Q在M下方時,取Pd點。

接下來:

然後中點畫線的計算:

di需要兩個乘法和四個加法算,比DDA差的多,但是di可以用增量法求

當d<0時

當d>=0時

d的初始值d0:

中點演算法計算為:

如果將d換成2d,就只有整數運算,優於DDA演算法。

最終公式:

代碼:

void lineMidPoint(int x0, int y0, int x1, int y1, int color){    int x = x0, y = y0;    int a = y0 - y1, b = x1 - x0;    int cx = (b >= 0 ? 1 : (b = -b, -1));    int cy = (a <= 0 ? 1 : (a = -a, -1));    putpixel(x, y, color);    int d, d1, d2;    if (-a <= b)     // 斜率絕對值 <= 1      {        d = 2 * a + b;        d1 = 2 * a;        d2 = 2 * (a + b);        while (x != x1)        {            if (d < 0)                y += cy, d += d2;            else                d += d1;            x += cx;            putpixel(x, y, color);        }    }    else                // 斜率絕對值 > 1      {        d = 2 * b + a;        d1 = 2 * b;        d2 = 2 * (a + b);        while (y != y1)        {            if (d < 0)                d += d1;            else                x += cx, d += d2;            y += cy;            putpixel(x, y, color);        }    }}

3.Bresenham演算法

DDA使畫直線每步只有一個加法。

中點畫線法使畫直線每步只有一個整數加法。

Bresenham演算法提供一個更一般的演算法,使適用範圍增大。

該演算法的思想是通過各行、各列像素中心構造一組虛擬網格線,按照直線起點到終點的順序,計算直線與各垂直網格線的交點,然後根據誤差項的符號確定該列象素中與此交點最近的象素。

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

誤差項d的初值d 0=0,d=d+k,一旦d≥1,就把它減去1,保證d的相對性,且在0、1之間。

然後有下面計算公式:

怎麼提升到整數演算法?

答案是讓e=d-0.5

e0=-0.5

每迴圈一次:e = e+k
if (e>0) then e = e-1

e+k這還是一個浮點加法

因為k=△y/△x

因為用誤差項的符號,可以用e*2*△x來替換 e:

e0=-△x

每迴圈一次:e = e+2△y
if (e>0) then e = e-2△x

這已經變成為整數加法

演算法步驟:

演算法步驟為:
1.輸入直線的兩端點P 0(x 0,y 0)和P 1(x 1,y 1)。
2.計算初始值△x、△y、 e=-△x、x=x 0、y=y 0。
3.繪製點(x,y)。
4.e更新為 e+2△y,判斷e的符號。若e>0,則(x,y)更新為
(x+1,y+1),同時將e更新為 e-2△x;否則(x,y)更新為
(x+1,y)。
5.當直線沒有畫完時,重複步驟3和4。否則結束。

代碼:

void lineBresenham1(int x0, int y0, int x1, int y1, long color){    int dx = abs(x1 - x0);    int dy = abs(y1 - y0);    int x = x0;    int y = y0;    int stepX = 1;    int stepY = 1;    if (x0 > x1)  //從右向左畫          stepX = -1;    if (y0 > y1)        stepY = -1;    if (dx > dy)  //沿著最長的那個軸前進      {        int e = dy * 2 - dx;        for (int i = 0; i <= dx; i++)        {            putpixel(x, y, color);            x += stepX;            e += dy;            if (e >= 0)            {                y += stepY;                e -= dx;            }        }    }    else    {        int e = 2 * dx - dy;        for (int i = 0; i <= dy; i++)        {            putpixel(x, y, color);            y += stepY;            e += dx;            if (e >= 0)            {                x += stepX;                e -= dy;            }        }    }}

電腦圖形學之掃描轉換直線-DDA,Bresenham,中點畫線演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.