【计算机图形学】中点画线法实现任意斜率直线的绘制
一、中点画线法原理简介
1.建立基础
- 中点画线法的建立基础是数值微分画线法(DDA),其作为改进算法,沿用了DDA算法的增量思想,针对影响DDA算法效率的两点:(1)采用了浮点加法(2)浮点数在显示输出时需要取整;进行了改进,即中点画线法直接采用了整数的加法、比较。
2.具体分析
-
这里具体分析直线斜率 k ∈[0,1] 的情况,其他情况可以类推。
对于起始点(x0,y0)、结束点(x1,y1),有A=y0-y1、B=x1-x0、C=(x1-x0)(x0-x1)、k=(y1-y0)/(x1-x0)
设函数F(x,y) = Ax+By+C,则F(x,y)将平面分为三部分:
1)F(x,y) = 0,点在直线上
2)F(x,y) > 0,点在直线的上方
3)F(x,y) < 0,点在直线的下方 -
在画线过程中,对于每个当前像素点(xi,yi),每次在最大位移方向,即x方向上前进一步,在y方向上是否前进取决于前一格中点和直线的位置关系。
如上图所示,可判断中点Mid和直线的位置关系,来确定下一点的选取,令d为判别式:
1)d=F(xi+1,yi+0.5) = 0,Mid在直线上,可选取Pu/Pd,这里我们统一规定选取Pd
2)d=F(xi+1,yi+0.5) > 0,Mid在直线的上方,直线离Pd较近,选取Pd,则下一点y方向上不变
3)d=F(xi+1,yi+0.5) < 0,Mid在直线的下方,直线离Pu较近,选取Pu,则下一点y方向上前进 -
利用增量思想,每下一步的d的判别可以基于本步d的正负情况,分本步d<0和d>=0两种情况讨论。
1)d < 0: 本步选取Pu(xi+1,yi+1),则下一步中点(xi+2,yi+1.5):
dnew=F(xi+2,yi+1.5)
dnew=A(xi+2)+B(yi+1.5)+C
dnew=[A(xi+1)+B(yi+0.5)+C]+A+B
dnew=d+A+B
2)d >= 0: 本步选取Pd(xi+1,yi),则下一步中点(xi+2,yi+0.5):
dnew=F(xi+2,yi+0.5)
dnew=A(xi+2)+B(yi+0.5)+C
dnew=[A(xi+1)+B(yi+0.5)+C]+A
dnew=d+A -
在画线过程中每一点的情况都分析完了,也易得结束画线的条件。接下来只要确定初始值就能顺利地画线了。对于起始点(x0,y0),下一步中点为(x0+1,y0+0.5):
d0=F(x0+1,y0+0.5)
d0=A(x0+1)+B(y0+0.5)+C
d0=[Ax0+By0+C]+A+0.5B
d0=A+0.5B -
可以发现d0的计算中涉及到了浮点数0.5,为了改进我们可以用2d0代替d0,因为后续计算中只考虑d的正负,则扩大两倍不会对结果有所影响。此时的新d0为:
d0=2F(x0+1,y0+0.5)
d0=2A(x0+1)+2B(y0+0.5)+2C
d0=2[Ax0+By0+C]+2A+B
d0=2A+B对于k值的其他情况也可以照此分析,注意在k>1和k<-1时,每一步的最大位移方向是y方向,即每次在y方向上前进一步,在x方向上需要判断中点和直线关系。
3.分析总结
k∈[0,1] | k ∈(1,+∞) | k∈[-1,0) | k∈(-∞,-1) |
---|---|---|---|
d0=2A+B | d0=A+2B | d0=2A-B | d0=A-2B |
d<0:d+=2(A+B);x+=1;y+=1; | d<0:d+=2B;y+=1; | d<0:d+=2A;x+=1; | d<0:d+=2(A-B);y-=1;x+=1; |
d>=0:d+=2A;x+=1; | d>=0:d+=2(A+B);y+=1;x+=1 | d>=0:d+=2(A-B);x+=1;y-=1; | d>=0:d-=2B;y-=1; |
二、代码实现
/*
程序:中点画线法画任意斜率直线
编译环境:Visual C++ 6.0 EasyX_20200109(beta)
作者ID:weixin_43536824
邮箱:changye303@163.com
*/
#include <easyx.h>
#include <graphics.h>
#include <conio.h>