布雷森汉姆线算法错误

Posted

技术标签:

【中文标题】布雷森汉姆线算法错误【英文标题】:bresenham's line algorithm error 【发布时间】:2011-08-16 18:02:29 【问题描述】:

我有下面的bresenham's algorithm 代码,代表适应Scala Java 代码。

def bresenham(x0: Int, y0: Int, x1: Int, y1: Int) = 
    import scala.math.abs

    val dx = abs(x1 - x0)
    val dy = abs(y1 - y0)

    val sx = if (x0 < x1) 1 else -1
    val sy = if (y0 < y1) 1 else -1

    new Iterator[(Int, Int)] 
      var (x, y) = (x0, y0)
      var err = dx - dy

      def next = 
        val omitted = (x, y)
        val e2 = 2 * err
        if (e2 > -dy) 
          err -= dy
          x += sx
        
        if (e2 < dx) 
          err += dx
          y += sy
        
        omitted
      

      def hasNext = (x <= x1 && y <= y1)
    
  

几乎所有线条都很好,但是当我尝试从上到下计算垂直线时(即 (0,3) -> (0,0) )我一无所获。 我觉得我自己很愚蠢,因为问题并不那么难,在于hasNext 上面的案例nope)。 我已经通过交换积分来解决这个问题,但这显然是一个糟糕的解决方案。 有人可以帮我概括算法吗?

【问题讨论】:

不幸的是,您的方法会导致 `ThrowableException: Java heap space`(这是因为 hasNext 大多变为 true,而实际上不应该这样,并且行会无限大)。 顺便说一句,我在这段代码中发现了另一个错误——相同点之间的线(例如 (0,0) -> (0,0))会产生无限循环 【参考方案1】:

在失败的情况下,您尝试从 y0 = 3 转到 y1 = 0。所以这一步将是负数,sy = -1。继续 hasNext 的条件应该取决于 y &gt;= y1 而不是你写的内容 (y &lt;= y1)。

hasNext 必须泛化以处理任一方向。一个聪明的方法是,

def hasNext = (sx*x <= sx*x1 && sy*y <= sy*y1)

之所以有效,是因为sxsy 不为零,它们的符号决定了步骤的方向。

【讨论】:

非常感谢! @jeela 的答案似乎是最漂亮和最简单的(乘法很重),但我得到了除最后一个以外的所有分数。你的答案既正确又好。【参考方案2】:

***代码的直译是:

def hasNext = (!(x==x1 && y==y1))

【讨论】:

以上是关于布雷森汉姆线算法错误的主要内容,如果未能解决你的问题,请参考以下文章

图像重建基于matlab布雷格曼迭代算法集合ART算法CT图像重建含Matlab源码 1905期

Bresenham 线算法错误

分治算法练习

Bresenham画线算法

通道布线狗腿算法

[noip模拟赛]午餐