1. 程式人生 > >計算機圖形學筆記-三種畫線演算法

計算機圖形學筆記-三種畫線演算法

1.DDA:在一個座標軸上以單位間隔對線段取樣,從而確定另一個座標軸上最靠近路線的整數點。
如果斜率m<=1,則以單位X間隔取樣,逐步計算y值 y(k+1)=y(k)+m
如果斜率m>1,則以單位Y間隔取樣,逐步計算X值 x(k+1)=x(k)+1/m

這個演算法可以概括為以下過程:首先輸入兩個端點的座標,計算端點之間的水平和垂直差值分別賦值給dx,dy
他們絕對值大的作為確定引數K的值。在這個絕對值大的座標軸上進行間隔取樣。

#include<iostream>
#include<math.h>
using namespace std;
inline
int round(const float a) { return int (a+0.5); } void lineDDA(int x0,int y0,int xend,int yend) { int dx=xend-x0; int dy=yend-y0; int k; float xincrement,yincrement; if(fabs(dx)>fabs(dy)) k=fabs(dx); else k=fabs(dy); xincrement=float(dx)/float(k); yincrement=flaot(dy)/float
(k); setPixel(round(x),round(y)) for(int i=0;i<k;i++) { x+=xincrement; y+=yincrement; setPixel(round(x),round(y));//只有座標軸上增加斜率K大於0.5時才會在座標軸上加1 } }

Bresenham:和DDA一樣需要通過斜率來判斷是對X軸上進行取樣,還是Y軸上進行取樣,假設K<=1;則在X軸上取樣,然後下一步確定在x(k+1)=x(k)+1上繪製yk,還是yk+1;這裡用d(upper)與d(lower)來標識兩個畫素與數學上路徑的垂直偏移。在畫素Xk +1處的直線上的y座標可以計算為y=m(xk+1)+b
所以,d(lower)=y-yk=m(xk+1)+b-yk d(upper)=yk+1-y=yk=1-m(xk+1)+b
要確定兩個畫素中更靠近路徑的點,需計算d(lower)-d(upper)=2m(xk+1)-2yk+2b-1
m=dy/dx,所以上式子可以轉化為 pk=2dy*xk-2dx*yk+c,c為常量等於2dy+dx(2b-1)
所以,p(k+1)=pk+2dy-2dx(y(k+1)-yk)
因為p0=2dy-dx
若pk=0則需要規定一直取上方或者下方的點

#include<iostream>
#include<math.h>
using namespace std;
void LineBres(int x0,int y0,int xend,int yend)
{
    int dx=fabs(xend-x0);
    int dy=fabs(yend-y0);
    int p0=2dy-dx;
    int towdy=2*dy;
    int towdyminusdx=2*(dy-dx);
    if(x0>xend)
    {
    x=xend;
    y=yend;
    xend=x0;
}
else
{
  x=x0;
  y=y0;
}
setPixel(x,y);
//下面是斜率k<=1的情況,如果k>=1算式中的dy,dx需要對調位置即可
    while(x<xend)
        {
          x++;
          if(p<0)
          p+=twody;
          else
          {
          y++;
          p+=towdyminusdx;
}
setPixel(x,y);
}


}

中點畫線演算法:假定直線斜率k在0~1之間,當前象素點為(xp,yp),則下一個象素點有兩種可選擇點P1(xp+1,yp)或P2(xp+1,yp+1)。若P1與P2的中點(xp+1,yp+0.5)稱為M,Q為理想直線與x=xp+1垂線的交點。當M在Q的下方時,則取P2應為下一個象素點;當M在Q的上方時,則取P1為下一個象素點。這就是中點畫線法的基本原理。
d=F(M)=F(xp+1, yp+0.5)=a(xp+1)+b(yp+0.5)+c
當d<0時,M在L(Q點)下方,取P2為下一個象素;
當d>0時,M在L(Q點)上方,取P1為下一個象素;
當d=0時,選P1或P2均可,約定取P1為下一個象素
若當前象素處於d>0情況,則取正右方象素P1(xp+1, yp),要判下一個象素位置,應計算d1=F(xp+2,yp+0.5)=a(xp+2)+b(yp+0.5)=d+a,增量為a。
若d<0時,則取右上方象素P2(xp+1,yp+1)。要判斷再下一象素,則要計算d2=F(xp+2,yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b,增量為a+b。
d的初值d0=a+0.5b。

#inlcude<iostream>
#include<math.h>
using namespace std;
void middlePoint(int x0,int y0,int xend,int yend)
{
    int b=xend-x0;
    int a=y-yend;
    float d0=a+b/2.0;
    //斜率小於等於1的情況下,大於1同理可以推匯出
    setPixel(x0,y0);
    while(x0<xend)
{
    if(d0>=0)
    {
        setPixel(x0++,y0);
        d0+=a;
    }
    else if(d0<0)
    {
    setPixel(x0++,y0++);
    d0+=a+b;
}
}
}