計算機圖形學----DDA、Bresenham直線演算法

ljheee發表於2017-06-14

一、DDA演算法原理

      DDA(數值微分演算法)演算法是一個增量演算法。增量演算法:在一個迭代演算法中,每一步的x、y值是用前一步的值加上一個增量來獲得。

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

DDA需要考慮所畫直線的斜率k:

當 |k|<1 , x每增加1,y 增加k。

當 |k|>1 , y每增加1,x增加1/k。

程式設計實現直線的DDA演算法程式;

void CMyView::OnDdaline()
{
    CDC *pDC=GetDC();              // 獲得裝置指標
    intx0=100,y0=100,x1=300,y1=200,c=RGB(255,0,0);  //定義直線兩端點和直線顏色(紅色)
    float x,y,i;
    float dx,dy,k;
    dx=(float)(x1-x0);
    dy=(float)(y1-y0);
    k=dy/dx;//計算斜率
    y=y0; x=x0;
    if(abs(k)<1)
    {   for(;x<=x1;x++)
        {pDC->SetPixel(x,int(y+0.5),c);
        y=y+k;}//x自增,y=y+k
    }
    if(abs(k)>=1)
    {
      for(;y<=y1;y++)
      {pDC->SetPixel(int(x+0.5),y,c);
      x=x+1/k;}
    }
    ReleaseDC(pDC);      //釋放裝置指標
}

二、Bresenham演算法原理

        Bresenham演算法是計算機圖形學領域使用最廣泛的直線掃描轉換方法。

        其原理是:過各行、各列畫素中心構造一組虛擬網格線,按直線從起點到終點的順序計算直線各垂直網格線的交點,然後確定該列畫素中與此交點最近的畫素。

       該演算法的優點在於可以採用增量計算,使得對於每一列,只要檢查一個誤差項的符號,就可以確定該列所求的畫素。



直線的Bresenham演算法實現:

void CTestView::OnBresenhamline()
{
    CDC*pDC=GetDC();
    intx1=100,y1=200,x2=600,y2=800,color=RGB(0,0,255);
    inti,x,y,dx,dy;
    float k,e;
    dx=x2-x1;
    dy=y2-y1;
    k=dy/dx;
    e=-0.5;  x=x1; y=y1;//e初值d0-0.5
    for(i=0;i<=dx;i++)
    {   pDC->SetPixel(x,y,color);
       x++;
       e=e+k;
       if(e>=0)  { y++; e=e-1;}
    }
}

三、Bresenham改進演算法

          上述bresenham演算法在計算直線斜率與誤差項時用到了小數與除法可以改用整數以避免除法。由於演算法中用到誤差項的符號,因此可以做如下替換:e'=2*e*dx.

直線的整數Bresenham演算法實現

void CTestView::OnBresenhamline()
{
    CDC *pDC=GetDC();
    int x0=100,y0=100,x1=500,y1=600,color=RGB(0,0,255);int i,x,y,dx,dy;
    float k,e;
    dx=x1-x0;
    dy=y1-y0;
    e=-dx;
    x=x0; y=y0;
    for(i=0;i<=dx;i++)
     { pDC->SetPixel(x,y,color);
        x++;
        e+=2*dy;
    if(e>=0)
     {y++;e=e-2*dx;} }
     ReleaseDC(pDC);
}


http://download.csdn.net/detail/ljheee/9870382

相關文章