计算机图形学 之 直线段的扫描转换算法

数值微分法(Digital Differential Analyzer, DDA)

虽然像素是整数,但是线段位置点可以是浮点数,这里就需要取整,仅仅如此,但我这里也是整数,但是斜率往往是小数,跑不掉的,因此位置点是浮点数也没什么大不了的,x首先四舍五入成整数,然后y+k就是如此,然后y+0.5再取整就是四舍五入,就酱,包含两次浮点数加法

通过直线的斜截式计算出斜率 k, 即可只通过两次浮点数加法(包括四舍五入的)得出下一个点的坐标

中点分割法

但是k值太大就没用了,应该按照45度变换x,y这样。

该算法利用直线的一般式, 完全使用整数加法.
设 F(x, y) = Ax + By + C, 根据直线的一般式可得: 若点位于直线上方, 则 F(x, y) > 0  若点位于直线上, 则 F(x, y) = 0 ,若点位于直线下方, 则 F(x, y) < 0

每次向最大位移方向上累加一个单元, 通过中点误差项判断是否往另一个方向累加一个单元. 若 0 <= |k| <= 1, 即|Δx| > |Δy|, 每次循环时 x 坐标累加 1, y 坐标是否累加 1 取决于线段与 x = x(变量) 交点 Q 的位置, 离点 Pd(x + 1, y) 更近还是点 Pu(x + 1, y + 1). 这将通过把这两点的中点 M 带入 F(x, y) 后判断其正负性. 若 F(x, y) < 0, 则表示中点位于交点 Q 的下方, 即交点 Q 位于中点 M 上方, 更接近于点 (x, y + 1). 

不过上面的实现明显并不适用于斜率大于 1 的线段, 因为每次循环 x 累加 1, 却只会调用一次 drawPoint. 如果强行使用这类实现绘制斜率大于 1 的线段, 将会发现绘制出的线段在 y 轴方向上不连续. 若要实现可绘制各种线段的, 可以参考 DDA 部分的解决方案.

Bresenham 算法

 

由 Figure-1 可以看出 d 的计算方法为:

d += k;
if(d >= 1) d--;直线扫描转换算法

算法思想:通过各行、各列象素中心构造一组虚拟网格线,按照直线起点到终点的顺序,计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。这个距离最大误差为0.5。

Bresenham算法很像DDA算法,都是加斜率

但DDA算法是每次求一个新的y以后取整来画,

而Bresenham算法是判断符号来决定上下两个点。

所以Bresenham算法集中了DDA和中点两个算法的优点,而且应用范围广泛。

因此也没办法划斜率大于1的,需要用算法搞定,只不过效率更高一点而已。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值