声明:此文是作者学习计算机图形学的学习记录,欢迎对计算机图形学感兴趣的朋友交流经验。另外此文在写作过程中借鉴以下链接的文章:点击打开链接。转载请注明出处。
数值微分法即DDA法(Digital Differential Analyzer),是一种基于直线的微分方程来生成直线的方法。
一、直线DDA算法描述:
设(x1,y1)和(x2,y2)分别为所求直线的起点和终点坐标,由直线的微分方程得
可通过计算由x方向的增量△x引起y的改变来生成直线:
也可通过计算由y方向的增量△y引起x的改变来生成直线:
式(2-2)至(2-5)是递推的。
二、直线DDA算法思想:
选定x2-x1和y2-y1中较大者作为步进方向(假设x2-x1较大),取该方向上的增量为一个象素单位(△x=1),然后利用式(2-1)计算另一个方向的增量(△y=△x·K=K)。通过递推公式(2-2)至(2-5),把每次计算出的(xi+1,yi+1)经取整后送到显示器输出,则得到扫描转换后的直线。
之所以取x2-x1和y2-y1中较大者作为步进方向,是考虑沿着线段分布的象素应均匀。
另外,算法实现中还应注意直线的生成方向,以决定Δx及Δy是取正值还是负值。
三、直线DDA算法实现:
1、已知直线的两端点坐标:(x1,y1),(x2,y2)
2、已知画线的颜色:color(取值范围0 ---- 255)
3、计算两个方向的变化量:dx=x2-x1
dy=y2-y1
4、求出两个方向最大变化量的绝对值:
steps=max(|dx|,|dy|)
5、计算两个方向的增量(考虑了生成方向):
xin=dx/steps
yin=dy/steps
6、设置初始象素坐标:x=x1,y=y1
7、用循环实现直线的绘制:
for(i=1;i<=steps;i++)
{ SetPixel(HDC,x,y,color);/*在(x,y)处,以color色画点*/
x=x+xin;
y=y+yin;
}
四、直线DDA算法特点:
该算法简单,实现容易,但由于在循环中涉及实型数的运算,因此生成直线的速度较慢。
五、直线DDA算法的实现程序:
我是在VS2010上利用MFC对话框实现的。
void CDDALineDlg::DDA_Line(int x1, int y1, int x2, int y2, int color)
{
CPaintDC dc(this); //获得窗口句柄
float increX,increY; //x,y方向的增量
float x,y;
int steps; //循环次数,即画的点数
steps = max(abs(x2-x1),abs(y2-y1));//选较大者作为步进方向
increX = (float)(x2-x1)/steps;//x方向增量
increY=(float)(y2-y1)/steps;//y方向增量
x=x1;
y=y1;
for(int i=1;i<=steps;i++){
SetPixel(dc,x,y,color); //在(x,y)处,以color色画点
x+=increX;
y+=increY;
}
}
在OnPaint()函数中调用函数,这样就可以在对话框上画线了。
void CDDALineDlg::OnPaint()
{
DDA_Line(10,10,20,180,255);
}
MFC对话框程序的创建过程:
打开VS2010,选择新建项目,选择“MFC应用程序”,命名为DDA-Line,如下图![](https://img-blog.csdn.net/20140322114400265?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlxaWFuY2Fv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
点确定,在弹出的窗口点“下一步”,出现下图,选择“基于对话框”,然后点击“完成”![](https://img-blog.csdn.net/20140322114603406?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlxaWFuY2Fv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
对话框建完了,再把对话框上不用的东西点右键删掉,在对话框上显示的东西都是在OnPaint()函数里控制的,刚建好时,此函数里有一些系统自动生成的代码,我们可以把它删掉,不会影响程序的运行。在“类视图”页面选中CDDAlineDlg,右键选择添加,点添加函数,![](https://img-blog.csdn.net/20140322120955031?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlxaWFuY2Fv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
为程序添加DDA_Line(int x1, int y1, int x2, int y2, int color)函数,然后在OnPaint()函数中调用函数。