【计算机图形学|直线生成算法】Bresenham画法详解

概述

Bresenham画法是一种用于计算计算机图形中线条的算法,其原理是沿着所需绘制的线段中的像素点进行递增或递减,来进行准确的点阵绘制。

实现该算法的关键在于确定像素在基准线上的位置,以及在每次迭代时进行相应的调整。该算法比传统的直线算法更快且更准确,在低速处理器和低效内存设备上尤其适用。

Bresenham画法的思想可以拓展到曲线绘制、圆形绘制等其他图像绘制领域。

一、判别式推导

假设直线的表达式为 y = m x + b y = mx + b y=mx+b,并且线段 A D AD AD 与线段 T S TS TS 相交于点 M M M T M TM TM 的长度为 t t t M S MS MS 的长度为 s s s。实现算法需要计算 s s s t t t 的大小关系来确定选择上点或者下点。

在这里插入图片描述
对于M点以及s与t的大小关系分析得出:

如果给定点 ( x i , y i ) (x_i, y_i) (xi,yi) 和点 ( x i + 1 , y i + 1 ) (x_{i+1}, y_{i+1}) (xi+1,yi+1),使用直线方程式 y = m x + b y = mx + b y=mx+b。那么,点 ( x i + 1 , y i + 1 ) (x_{i+1}, y_{i+1}) (xi+1,yi+1) 的坐标可以表示为:

x i + 1 = x i + 1 y i + 1 = m ( x i + 1 ) + b x_{i+1} = x_i + 1 \\ y_{i+1} = m(x_i + 1) + b xi+1=xi+1yi+1=m(xi+1)+b

此时,点 P P P 的坐标为 ( x i , y i ) (x_i, y_i) (xi,yi),点 S S S 的坐标为 ( x i , y i + 1 ) (x_i, y_i+1) (xi,yi+1),点 T T T 的坐标为 ( x i + 1 , y i + 1 ) (x_i+1, y_i+1) (xi+1,yi+1)

我们需要计算 s s s t t t 的值来判断绘制线段的方向

首先, s s s 的值为:

s = y i + 1 − y i = m ( x i + 1 ) + b − ( m x i + b ) = m s = y_{i+1} - y_i = m(x_i + 1) + b - (mx_i + b) = m s=yi+1yi=m(xi+1)+b(mxi+b)=m

其次, t t t 的值为:

t = 2 y i + 1 − 2 y i + 2 = 2 ( m ( x i + 1 ) + b ) − 2 ( m x i + b ) + 2 = 2 m ( x i + 1 − x i ) + 2 = 2 m + 2 \begin{aligned} t &= 2y_{i+1} - 2y_i + 2 \\ &= 2(m(x_i + 1) + b) - 2(mx_i + b) + 2 \\ &= 2m(x_i + 1 - x_i) + 2 \\ &= 2m + 2 \end{aligned} t=2yi+12yi+2=2(m(xi+1)+b)2(mxi+b)+2=2m(xi+1xi)+2=2m+2

假设 T M TM TM 的长度为 t t t S M SM SM 的长度为 s s s,那么 s − t s - t st 的值为

s − t = ( m x i + b + 1 ) − y i − ( y i + 1 − m x i − b ) = 2 ( m x i + 1 − y i ) s - t = (mx_i + b + 1) - y_i - (y_i + 1 - mx_i - b) = 2(mx_i + 1 - y_i) st=(mxi+b+1)yi(yi+1mxib)=2(mxi+1yi)

因此,我们可以按照下列规则判断绘制线段的方向:

  • 如果 s − t > 0 s - t > 0 st>0,根据 M 点在 T 点下面,我们可以得出 M 点到 T 点的距离大于至 S 点的距离。因此,下一个要绘制的点为 T 点
  • 如果 s − t < 0 s - t < 0 st<0根据 M 点在 T 点上面,我们可以得出 M 点到 T 点的距离小于至 S 点的距离。因此,下一个要绘制的点为 S 点
  • 如果 s − t = 0 s - t = 0 st=0,根据 M 点到 T 和 S 点的距离相等,我们可以随机选择 T 或 S 点作为下一个要绘制的点。

这样,我们就可以根据直线方程和点 ( x i , y i ) (x_i, y_i) (xi,yi) 来计算 ( x i + 1 , y i + 1 ) (x_{i+1}, y_{i+1}) (xi+1,yi+1) 的坐标,并根据 M 点的位置和距离来确定绘制线段的方向。

二、迭代推导

对于给定的两个点 ( x 1 , y 1 ) (x_1, y_1) (x1,y1) ( x 2 , y 2 ) (x_2, y_2) (x2,y2),我们可以通过计算以这两个点为端点的直线的斜率和截距来计算点 ( x 1 + 1 , y 1 ) (x_1+1, y_1) (x1+1,y1) 对应的 B r e s e n h a m Bresenham Bresenham 算法中的决策参数 d i + 1 d_{i+1} di+1,以便确定下一个点的位置。具体来说,计算方法如下:

( x 1 , y 1 ) (x_1, y_1) (x1,y1) ( x 2 , y 2 ) (x_2, y_2) (x2,y2) 视为直线上的两个点,我们有:

Δ x = x 2 − x 1 Δ y = y 2 − y 1 m = Δ y Δ x \begin{aligned} \Delta x &= x_2 - x_1\\ \Delta y &= y_2 - y_1\\ m &= {\Delta y \over \Delta x}\\ \end{aligned} ΔxΔym=x2x1=y2y1=ΔxΔy

接下来,计算 s − t s-t st 的值:

s − t = 2 Δ y ( x 1 + 1 2 ) + 2 b − 2 y 1 − 1 = 2 Δ y ( x 1 + 1 2 ) − 2 Δ x ( y 1 + 1 2 ) + 2 b − 1 s-t = 2\Delta y(x_1+{1\over 2}) + 2b - 2y_1 - 1 = 2\Delta y(x_1+{1\over 2}) - 2\Delta x(y_1+{1\over 2})+2b-1 st=y(x1+21)+2b2y11=y(x1+21)x(y1+21)+2b1

将式子两边乘以 Δ x \Delta x Δx,得到:

Δ x ( s − t ) = 2 Δ y Δ x i − 2 Δ x y i + 2 b Δ x − Δ x \Delta x(s-t) = 2\Delta y\Delta xi-2\Delta xy_i+2b\Delta x-\Delta x Δx(st)=yΔxixyi+2bΔxΔx

d i = Δ x ( s − t ) di = \Delta x(s-t) di=Δx(st),我们可以写成:

d i = 2 Δ y i − 2 Δ x y i + C , C = 2 b Δ x − Δ x + 1 di = 2\Delta yi - 2\Delta xy_{i} + C, \qquad C=2b\Delta x - \Delta x+1 di=yixyi+C,C=2bΔxΔx+1

这个时候,我们需要计算 d i + 1 d_{i+1} di+1 d i d_{i} di 的差值。可以通过 C C C 带来的影响来计算。 x i + 1 x_{i+1} xi+1 的变化量为 1 1 1,那么显然有:

d i + 1 = 2 Δ y ( x i + 1 ) − 2 Δ x y i + 2 b Δ x − Δ x + 1 = 2 Δ y ( x i + 1 ) − 2 Δ x y i + 2 Δ y − 2 Δ x y i + C = d i + 2 Δ y − 2 Δ x y i + C \begin{aligned} di+1 &= 2\Delta y(x_{i+1})-2\Delta x y_i+2b\Delta x - \Delta x + 1\\ &= 2\Delta y(x_i+1)-2\Delta xy_i + 2\Delta y - 2\Delta xy_i + C\\ &= di+2\Delta y - 2\Delta xy_i+ C \end{aligned} di+1=y(xi+1)xyi+2bΔxΔx+1=y(xi+1)xyi+yxyi+C=di+yxyi+C

因此,

d i + 1 − d i = 2 Δ y − 2 Δ x ( y i + 1 − y i ) di+1 - di = 2\Delta y - 2\Delta x(y_{i+1}-y_i) di+1di=yx(yi+1yi)

至此,我们可以根据 d i + 1 − d i di+1 - di di+1di 的大小关系,来确定绘制线段的方向:

  • d i + 1 − d i ≥ 0 di+1-di \geq 0 di+1di0 时,取上点 T ′ T' T,即 y i + 1 = y i + 1 y_{i+1}=y_i+1 yi+1=yi+1
  • d i + 1 − d i < 0 di+1-di < 0 di+1di<0 时,取下点 S ′ S' S,即 y i + 1 = y i y_{i+1}=y_i yi+1=yi

这样,我们就可以根据两个点的坐标,计算出 B r e s e n h a m Bresenham Bresenham 算法中的决策参数 d i + 1 d_{i+1} di+1,并根据 d i + 1 − d i di+1-di di+1di 的大小关系确定 绘制线段的方向了。

s t 关系图解

三、计算初值

假设初值为 ( x 0 , y 0 ) (x_0, y_0) (x0,y0),根据直线方程 y = m x + b y=mx+b y=mx+b,可以得到 m x 0 + b − y 0 = 0 mx_0+b-y_0=0 mx0+by0=0
将此式代入 d 0 = Δ x ( s − t ) = Δ x ( 2 m ( x 0 + 1 ) + 2 b − 2 y 0 − 1 ) d_0=\Delta x(s-t)=\Delta x(2m(x_0+1)+2b-2y_0-1) d0=Δx(st)=Δx(2m(x0+1)+2b2y01) 中,得到
d 0 = Δ x ( 2 m x 0 + 2 b − 2 y 0 + 2 m − 1 ) = Δ x ( 2 m − 1 ) d_0=\Delta x(2mx_0+2b-2y_0+2m-1)=\Delta x(2m-1) d0=Δx(2mx0+2b2y0+2m1)=Δx(2m1)。其中, m = Δ y Δ x m=\frac{\Delta y}{\Delta x} m=ΔxΔy,表示直线的斜率。

最终,我们可以使用公式 d 0 = 2 Δ y − Δ x d_0=2\Delta y-\Delta x d0=yΔx 来计算直线上初值 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 对应的位置。

四、总结

初始值 d 0 = 2 Δ y − Δ x d_0=2\Delta y-\Delta x d0=yΔx。根据直线方程 y = m x + b y=mx+b y=mx+b,得到下面的公式:

  • d i ≥ 0 d_i\geq 0 di0 时,取上点 T T T,则 d i + 1 = d i + 2 Δ y − 2 Δ x d_{i+1}=d_i+2\Delta y-2\Delta x di+1=di+yx

  • 如果 d i < 0 d_i<0 di<0,取下点 S S S,则 d i + 1 = d i + 2 Δ y d_{i+1}=d_i+2\Delta y di+1=di+y

其中,
Δ x = x 2 − x 1 Δ y = y 2 − y 1 \begin{aligned} \Delta x &= x_2 - x_1\\ \Delta y &= y_2 - y_1\\ \end{aligned} ΔxΔy=x2x1=y2y1

仅个人学习记录,欢迎大家交流,

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱喝冰红茶的方舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值