计算机图形与OpenGL学习四(1.画线算法)

画线算法

要在光栅监视器上显示一条线段,图形系统必须先将两端点投影到整数屏幕坐标,并确定离两端点间的直线路径最近的像素位置。接下来将颜色值装入帧缓存相应的像素坐标处。这一过程将一条线段数字化为一组离散的整数位置,图形学画线算法就是研究如何高效处理这个过程。

【DDA算法】

DDA算法又叫数值微分法,基于以下的数值推导过程:


算法步骤

①输入线段两个端点的像素位置。端点间水平和垂直差值赋给dx和dy。

②dx和dy中绝对值较大一个赋给参数steps,该值是这条直线段的像素数目

③先绘制起始位置(x0,y0),再调整每一步的x和y,逐一绘制余下像素。

【代码】

inlineint round(constfloat a)

{

    returnint (a+0.5);

}

void lineDDA(int x0,inty0,int xend,intyend)

{

   intdx=xend-x0;

   intdy=yend-y0;

   intk;

   floatxincrement,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画线算法】

过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。

核心思想:
假设:k=dy/dx。因为直线的起始点在象素中心,所以误差项d的初值d0=0。
X下标每增加1,d的值相应递增直线的斜率值k,即d=d+k。一旦d≥1,就把它减去1,这样保证d在0、1之间。
当d≥0.5时,最接近于当前象素的右上方象素(x+1,y+1)
而当d<0.5时,更接近于右方象素(x+1,y)

为方便计算,令e=d-0.5,
e的初值为-0.5,增量为k。
当e≥0时,取当前象素(xi,yi)的右上方象素(x+1,y+1)
而当e<0时,更接近于右方象素(x+1,y)
可以改用整数以避免除法。由于算法中只用到误差项的符号,因此可作如下替换:
e1 = 2*e*dx

代码

voidBresenhamline (int x0,int y0,int x1, int y1,int color)
{ 
 int x, y, dx, dy;
 float k, e;
 dx = x1-x0, dy = y1- y0, k=dy/dx;
 e=-0.5, x=x0, y=y0;
 for (i=0; i<=dx; i++)
 {    drawpixel (x, y, color);
 x=x+1,e=e+k;
 if (e>=0)
 { y++, e=e-1;}
 }
}
//或者将e扩大2dx倍;

voidBresenhamline (int x0,int y0,int x1, int y1,int color)
{
int x, y, dx, dy;
float k, e;
dx = x1-x0, dy = y1- y0, k=dy/dx;
e=-dx, x=x0, y=y0;
for (i=0; i<=dx; i++)
{ drawpixel (x, y, color);
x=x+1,e=e+2dy;
if (e>=0)
{ y++, e=e-2dx;}
}
}

猜你喜欢

转载自blog.csdn.net/lhs322/article/details/79844527