直线中点算法
中点算法是基于隐函数方程设计的,使用像素网格中点来判断如何选取距离理想直线最近的像素点,直线的中点算法不仅与 Bresenham 算法产生同样的像素点集,二期还可以推广到圆和椭圆。
原理
直线的隐函数表示
F
(
x
,
y
)
=
y
?
k
x
?
b
=
0
F(x, y) = y -kx -b = 0
F(x,y)=y?kx?b=0
理想直线将平面划分成三个区域
对于直线上的点, $F(x, y) = 0 $
对于直线上方的点,
F
(
x
,
y
)
>
0
F(x, y) >0
F(x,y)>0
对于直线下方的点,
F
(
x
,
y
)
<
0
F(x, y) <0
F(x,y)<0
中点误差项
d i = F ( x i + 1 , y i + 0.5 ) = y i + 0.5 ? k ( x i + 1 ) ? b d_i = F(x_i + 1, y_i + 0.5) = y_i + 0.5 - k(x_i + 1) -b di?=F(xi?+1,yi?+0.5)=yi?+0.5?k(xi?+1)?b
y i + 1 = { y i + 1 d i < 0 y i d i ≥ 0 y_{i+1} = \begin{cases} y_i + 1 & d_i < 0 \\ y_i & d_i \geq 0 \end{cases} yi+1?={yi?+1yi??di?<0di?≥0?
中点误差项的递推公式
- 当 d i < 0 d_i < 0 di?<0 , 下一步进行判断的中点为 M u ( x i + 2 , y i + 1.5 ) M_u(x_i +2,y_i+ 1.5) Mu?(xi?+2,yi?+1.5) , 中点的误差项的递推公式为
d
i
+
1
=
d
i
+
1
?
k
d_{i+1} = d_{i} + 1 - k
di+1?=di?+1?k
上一步选择 P u P_u Pu? 后,中点误差项的增量为 1 ? k 1-k 1?k
- 当
d
i
≥
0
d_i \geq 0
di?≥0 时,下一步进行判断的中点为
M
d
(
x
i
+
2
,
y
i
+
0.5
)
M_d(x_i + 2, y_{i} + 0.5)
Md?(xi?+2,yi?+0.5) 中点的误差项的递推公式为
d
i
+
1
=
d
i
?
k
d_{i+1} = d_i - k
di+1?=di??k
上一步选择
P
d
P_d
Pd? 后,中点误差项的增量为
?
k
-k
?k
中点误差项的初始值
直线的起点坐标扫描转换后的像素为 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0?(x0?,y0?) .从像素 P 0 P_0 P0? 出发沿着主位移 x x x 方向的递增一个单位,第一个参与判断的中点是 M ( x 0 + 1 , y 0 + 0.5 ) M(x_0+1, y_0 + 0.5) M(x0?+1,y0?+0.5)。 代入中点误差项计算公式, d d d 的初始值为
d 0 = 0.5 ? k d_0 = 0.5 - k d0?=0.5?k
算法
- 设置像素点的颜色
- 读入直线的两个端点坐标
- 计算中点误差项的初始值 d d d
- 当 d < 0 d <0 d<0 时, d d d 的增量为 1 ? k 1-k 1?k, 当 d ≥ 0 d \geq 0 d≥0 时, d 的增量为 ? k d 的增量为 -k d的增量为?k
- 根据每一步中点误差项的值,选择像素点并绘制出来
void MidPointLine(CDC* pDC, CPoint P0, CPoint P1) {
COLORREF crColor = RGB(0, 0, 0);
double k, d;
int dx = P1.x - P0.x;
int dy = P1.y - P1.y;
k = double (dy) / dx;
d = 0.5 -k;
double inColorUp = 1 - k;
double inColorDown = -k;
for (int x=P0.x, y= P0.y; x <P1.x; x++) {
pDC->SetPixelV(x, y, crColor)
if (d <0) {
y++;
d += inColorUp;
}
else {
d += inColorDown;
}
}
}
总结
中点算法是一种浮点数算法,现在的计算机做浮点数运算和整数运算一样快
中点算法设计巧妙,不需要取证操作
中点算法同样适用于绘制圆和椭圆
参考 《计算几何算法与实现》孔令德
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!