布雷森汉姆线算法错误
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 >= y1
而不是你写的内容 (y <= y1
)。
hasNext
必须泛化以处理任一方向。一个聪明的方法是,
def hasNext = (sx*x <= sx*x1 && sy*y <= sy*y1)
之所以有效,是因为sx
和sy
不为零,它们的符号决定了步骤的方向。
【讨论】:
非常感谢! @jeela 的答案似乎是最漂亮和最简单的(乘法很重),但我得到了除最后一个以外的所有分数。你的答案既正确又好。【参考方案2】:***代码的直译是:
def hasNext = (!(x==x1 && y==y1))
【讨论】:
以上是关于布雷森汉姆线算法错误的主要内容,如果未能解决你的问题,请参考以下文章