Bresenham直线算法

17 Mar 2025 | 6 分钟阅读

此算法用于扫描转换一条线。它由Bresenham开发。这是一种有效的方法,因为它只涉及整数加法、减法和乘法运算。这些运算可以非常快速地执行,因此可以快速生成线条。

在这个方法中,下一个选择的像素是距离真实线最近的像素。

该方法的工作原理如下

假设一个像素P1'(x1',y1'),然后选择后续像素,当我们从左到右工作时,一次一个像素位置在水平方向朝向P2'(x2',y2')。

在任何步骤中选择一个像素后

下一个像素是

  1. 要么是它右边的那个(线的下界)
  2. 要么是它右上方的那个(线的上界)

该线最好由那些与P1'和P2'之间的路径距离最小的像素来近似。

Bresenham's Line Algorithm

为了选择底部像素S和顶部像素T之间的下一个像素。
            如果选择S
            那么 xi+1=xi+1       并且       yi+1=yi
            如果选择T
            那么 xi+1=xi+1       并且       yi+1=yi+1

在x = xi+1处,线的实际y坐标为
            y=mxi+1+b

Bresenham's Line Algorithm

从S到y方向上实际线的距离
            s = y-yi

从T到y方向上实际线的距离
            t = (yi+1)-y

现在考虑这两个距离值之间的差异
            s - t

当 (s-t) <0 ⟹ s < t

最接近的像素是S

当 (s-t) ≥0 ⟹ s < t

最接近的像素是T

这个差异是
            s-t = (y-yi)-[(yi+1)-y]
                    = 2y - 2yi -1

            Bresenham's Line Algorithm

Bresenham's Line Algorithm代替m并引入决策变量
                di=△x (s-t)
                di=△x (2 Bresenham's Line Algorithm (xi+1)+2b-2yi-1)
                        =2△xyi-2△y-1△x.2b-2yi△x-△x
                di=2△y.xi-2△x.yi+c

其中 c= 2△y+△x (2b-1)

我们可以写出下一个滑动上的决策变量di+1
                di+1=2△y.xi+1-2△x.yi+1+c
                di+1-di=2△y.(xi+1-xi)- 2△x(yi+1-yi)

由于x_(i+1)=xi+1,我们有
                di+1+di=2△y.(xi+1-xi)- 2△x(yi+1-yi)

特殊情况

如果选择的像素在顶部像素T (i.e., di≥0)⟹ yi+1=yi+1
                di+1=di+2△y-2△x

如果选择的像素在底部像素T (i.e., di<0)⟹ yi+1=yi
                di+1=di+2△y

最后,我们计算d1
                d1=△x[2m(x1+1)+2b-2y1-1]
                d1=△x[2(mx1+b-y1)+2m-1]

Since mx1+b-yi=0 and m = Bresenham's Line Algorithm, we have
                d1=2△y-△x

优点

1. 它只涉及整数运算,因此很简单。

2. 它避免了重复点的生成。

3. 它可以使用硬件实现,因为它不使用乘法和除法。

4. 与DDA(数字微分分析器)相比,它更快,因为它不涉及像DDA算法这样的浮点计算。

缺点

1. 此算法仅适用于基本直线绘制。初始化不是Bresenham直线算法的一部分。因此,要绘制平滑的线条,您应该考虑使用不同的算法。

Bresenham直线算法

步骤1: 开始算法

步骤2: 声明变量 x1,x2,y1,y2,d,i1,i2,dx,dy

步骤3: 输入x1,y1,x2,y2的值
                其中x1,y1是起始点的坐标
                并且x2,y2是结束点的坐标

步骤4: 计算 dx = x2-x1
                计算 dy = y2-y1
                计算 i1=2*dy
                计算 i2=2*(dy-dx)
                计算 d=i1-dx

步骤5: 将(x, y)视为起点,xend视为x的最大可能值。
                如果 dx < 0
                        那么 x = x2
                        y = y2
                          xend=x1
                如果 dx > 0
                    那么 x = x1
                y = y1
                        xend=x2

步骤6: 在(x,y)坐标处生成点。

步骤7: 检查是否生成了整条线。
                如果 x > = xend
                停止。

步骤8: 计算下一个像素的坐标
                如果 d < 0
                    那么 d = d + i1
                如果 d ≥ 0
            那么 d = d + i2
                递增 y = y + 1

步骤9: 递增 x = x + 1

步骤10: 绘制最新(x, y)坐标的点

步骤11: 转到步骤 7

步骤12: 算法结束

示例: 线的起始和结束位置是 (1, 1) 和 (8, 5)。找到中间点。

解决方案: x1=1
                y1=1
                x2=8
                y2=5
                dx= x2-x1=8-1=7
                dy=y2-y1=5-1=4
                I1=2* ∆y=2*4=8
                I2=2*(∆y-∆x)=2*(4-7)=-6
                d = I1-∆x=8-7=1

xyd=d+I1 或 I2
11d+I2=1+(-6)=-5
22d+I1=-5+8=3
32d+I2=3+(-6)=-3
43d+I1=-3+8=5
53d+I2=5+(-6)=-1
64d+I1=-1+8=7
74d+I2=7+(-6)=1
85
Bresenham's Line Algorithm

实现Bresenham直线绘制算法的程序

输出

Bresenham's Line Algorithm

区分DDA算法和Bresenham直线算法

DDA算法Bresenham直线算法
1. DDA算法使用浮点数,即实数运算。1. Bresenham直线算法使用定点数,即整数运算。
2. DDA算法在其运算中使用乘法和除法2.Bresenham直线算法在其运算中仅使用减法和加法
3. DDA算法在线绘制中比Bresenham直线算法慢,因为它使用实数运算(浮点运算)3. Bresenham算法比DDA算法在线绘制中更快,因为它在其计算中仅涉及加法和减法,并且仅使用整数运算。
4. DDA算法不如Bresenham直线算法准确和高效。4. Bresenham直线算法比DDA算法更准确和高效。
5.DDA算法可以绘制圆和曲线,但不像Bresenham直线算法那么准确5. Bresenham直线算法可以绘制圆和曲线,比DDA算法更准确。

下一个主题定义一个圆