详述 Bresenham 线生成算法

给定直线的起始点和结束点,在显示设备上绘制该线段是计算机图形学中最基本的操作之一。本文将介绍的 Bresenham Line Drawing Algorithm 即为执行该操作的其中一个较为优化的算法。

计算机显示设备是由一个个像素组成的,该算法的目的即为“点亮”由起始像素点 ( x 0 , x 0 ) (x_0, x_0) (x0,x0) 至结束像素点 ( x 1 , y 1 ) (x_1, y_1) (x1,y1) 的线段上的像素点,当分辨率足够大,像素点足够小,看起来就会像一条直线。

举例:

example

为简化后续讨论,设置如下限定条件:

  1. 起始点在结束点左下方;
  2. x 0 < x 1 x_0 < x_1 x0<x1 y 0 < = y 1 y_0 <= y_1 y0<=y1
  3. 线段的斜率 0 ≤ k ≤ 1 0\le k\le 1 0k1
  4. 对于区间 [ x 0 , x 1 ] [x_0,x_1] [x0,x1] 内的所有 x x x ,该位置仅存在一个像素点。

设置以上限定条件之后,我们可以得到一个十分粗糙的算法:

def easyway(x0,y0,x1,y1):
  m = (y2-y1)/(x2-x1)
  for x in range(x0, x1+1, 1):
    # find y (integer)
    y = round(mx+b)
    colorify(x,y)

该算法是可行的,但在循环的每一步都需要计算 m x + b mx+b mx+b,执行速度较慢,因此,我们需要寻找一个快速得到 y y y 值的方法。

推导

由于线段的斜率在0到1之间,因此对于点 ( x k , y k ) (x_k,y_k) (xk,yk) ,下个点只可能是 ( x k + 1 , y k ) (x_k+1,y_k) (xk+1,yk) ( x k + 1 , y k + 1 ) (x_k+1,y_k+1) (xk+1,yk+1) ,其中 k k k 表示横坐标 x x x 移动的次数,如图所示。

next point

因此,我们需要从 y k y_k yk y k + 1 y_k+1 yk+1 中获取离线段较近的值,假设直线方程为 y = m x + b y = mx + b y=mx+b ,设 y y y 为直线上实际的值, d 1 ( k ) d_1(k) d1(k) d 2 ( k ) d_2(k) d2(k) 分别为距离 y k y_k yk y k + 1 y_k+1 yk+1 的距离,则有:

y = m ( x k + 1 ) + b y= m(x_k+1)+b y=m(xk+1)+b

d 1 ( k ) = y − y k d_1(k) = y-y_k d1(k)=yyk

d 2 ( k ) = ( y k + 1 ) − y d_2(k) = (y_k+1) - y d2(k)=(yk+1)y

比较 d 1 ( k ) d_1(k) d1(k) d 2 ( k ) d_2(k) d2(k) 的值,即可判断下个点的具体位置:

  1. d 1 ( k ) ≤ d 2 ( k ) d_1(k) \le d_2(k) d1(k)d2(k) ,认为下个点应为 ( x k + 1 , y k
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值