我们知道,计算机屏幕是由一个个像素整齐排列而成,想要在屏幕上绘制一条直线,我们只能通过点亮屏幕中
理想直线
附近的像素点,来尽可能拟合这条直线。DDA 直线算法
可以帮我们计算出到底需要点亮哪些像素点。
DDA 算法介绍
DDA ( Digital Differential Analyzer ), 基于直线的微分方程来生成直线,典型性的光栅显示器生成算法。
假设一条直线的两端点分别为:A(x0,y0)
,B(x1,y1)
。
则直线的斜率和方程为:
对于直线上(A,B之间)的任意一点
X (x0 + Δx, y0 + Δy)
来说,
即
在计算机屏幕绘制直线时,由于是点亮对应位置的像素点,所以
Δx
和 Δy
都必须为整数,即若计算出的值为小数时,需要四舍五入(或者向上/向下取整)。
- 当直线的斜率小于 1 时,x 变化幅度要大于 y 的变化,导致 Δx 增加 n 个单位,Δy 增加 1 个单位;
- 而当直线的斜率大于 1 时,y 变化幅度要大于 x 的变化,使得 Δx 每增加 1 个单位,Δy 增加 n 个单位。
所以这两种情况需要分别考虑:
-
当斜率小于等于
1
的时候,可通过计算x
方向上的增量Δx
(1
个像素)引起y
的改变来生成直线(x
每次增加1
,y增加 1
或者不增加
)。 -
而当斜率大于
1
的时候,可通过计算y
方向上的增量Δy
(1
个像素)引起x
的改变来生成直线(让y
每次递增1
,x
每次增加 1
或者不增加
)。
关键代码
void lineDDA(int x0, int y0, int xEnd, int yEnd)
{
int steps,k;
int dx = xEnd-x0, dy = yEnd-y0;
float xIncrement,yIncrement, x=x0,y=y0;
//判断斜率是否大于 1,
//steps 为增量计算的次数,也是绘制的像素点数
if (fabs(dx)>fabs(dy))
steps = fabs(dx);
else
steps = fabs(dy);
//计算 x 和 y 方向上的增量
xIncrement = float(dx)/float(steps);
yIncrement = float(dy)/float(steps);
//将坐标四舍五入为整数,然后点亮对应位置的像素点
setPixel(round(x),round(y));
for (k=0;k<steps;k++)
{
x = x+ xIncrement;
y = y+ yIncrement;
setPixel(round(x),round(y));
}
}
运行结果示例
本文由 机灵鹤 SmartCrane 创作
本站文章所有原创文章, 转载前请务必署名
最后编辑时间为: 2018-09-23 22:17