光栅图形学之直线段扫描算法(DDA)

来源:互联网 发布:关爱八卦成长协会知乎 编辑:程序博客网 时间:2024/05/16 11:37

说明:本文章系作者学习资料整理,不完善的地方请大家指正,谢谢!

摘自《计算机图形学基础教程》清华大学出版社 孙家广 胡事民

 

 

我们知道利用任何画图工具,知道两个点之后,便可以在窗口画出一条直线,其计算机内部原理,便是利用了光栅化。计算机屏幕可以看作是有几行几列的单位正方形组成,在数学中线是没有宽度的。当线与正方形的边有交点时,我们需要判定选取正方形的哪个顶点作为线上的一个点。这便引出了图形扫描转换的算法。

 

1概念

   图形扫描转换或光栅化:确定最佳逼近图形的像素集合,并用指定属性写像素的过程。

 

  我们将直角坐标系看作屏幕,用单元网格划分。

2直线段扫描算法

 (1)DDA算法-----digital differential analyzer 数值微分算法

      其核心思想是在确定选取正方形的哪个顶点作为直线上的点时,采用了四舍五入的方法。由已知两点P1(x0,y0) 和P2(x1,y1) ,可以由直线方程 y=k*x+b 确定,

其中k=(y1-y0)/(x1-x0)  ,b也可以确定。当|k|< = 1,我们沿着x轴的方向进行计算,x每次加一个x的增量,在这里我们认为是增量是1。因为x的值已知,通过直线方程我们可以得到y值,然而y值未必是整数,在此算法中对y值进行四舍五入运算。而当|k|>1,我们沿着y轴的方向进行计算,y每次加1,由y值计算x的值,并对x值进行四舍五入运算。

 

当|k|<=1时,由迭代公式yi+1=k*xi+1+b    推出 yi+1=k*(xi+1)+b  ; yi+1=k*xi+b+k

   所以yi+1=yi+k;

当|k|>1时,由以上迭代公式推出 xi+1=(yi+1-b)/k ; xi+1=(yi+1-b)/k ; xi+1=(yi-b)/k+ 1/k;

 所以 xi+1=xi+1/k;

 

 伪代码如下:

     void DDALine(int x0,int y0,int x1,int y1) {

       float k;

       int dx= x1-x0 ,dy=y1-y0;

       float k=dy/dx;

       if (k >= -1&&k <= 1)  {

       int x;

       float y;

       for(x=x0;x < x1;x++)

       {

        drawpixel(x,int(y+0.5),color);  //利用不同的软件,此画点的命令有所不同

        y=y+k;

       }

       }

      else {

      int y;

      float x;

      for(y=y0;y<y1;y++) 

      {

           drawpixel(int(x+0.5),y,color)

            x = x + 1/k;

       }

      }

}

注:int(x+0.5)与round(x)的功能一样,都是进行四舍五入运算。

 

缺陷:存在浮点数以及除法运算,计算速度慢。