直线中点算法

中点算法是基于隐函数方程设计的,使用像素网格中点来判断如何选取距离理想直线最近的像素点,直线的中点算法不仅与 Bresenham 算法产生同样的像素点集,二期还可以推广到圆和椭圆。

原理

直线的隐函数表示

F ( x , y ) = y − k x − b = 0 F(x, y) = y -kx -b = 0 F(x,y)=ykxb=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.5k(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+1yidi<0di0

中点误差项的递推公式

  • 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+2yi+1.5) , 中点的误差项的递推公式为

在这里插入图片描述
d i + 1 = d i + 1 − k d_{i+1} = d_{i} + 1 - k di+1=di+1k

上一步选择 P u P_u Pu 后,中点误差项的增量为 1 − k 1-k 1k

  • d i ≥ 0 d_i \geq 0 di0 时,下一步进行判断的中点为 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=dik
上一步选择 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.5k

算法

  • 设置像素点的颜色
  • 读入直线的两个端点坐标
  • 计算中点误差项的初始值 d d d
  • d < 0 d <0 d<0 时, d d d 的增量为 1 − k 1-k 1k, 当 d ≥ 0 d \geq 0 d0 时, 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; 
		}
	}  	
}

总结

中点算法是一种浮点数算法,现在的计算机做浮点数运算和整数运算一样快
中点算法设计巧妙,不需要取证操作
中点算法同样适用于绘制圆和椭圆

参考 《计算几何算法与实现》孔令德

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值