计算机图形学笔记-三种画线算法

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
#include
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大于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
#include
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(xif(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
#include
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(x0if(d0>=0)
    {
        setPixel(x0++,y0);
        d0+=a;
    }
    else if(d0<0)
    {
    setPixel(x0++,y0++);
    d0+=a+b;
}
}
}

你可能感兴趣的:(算法)