我在Python中编写了Bresenham算法的实现(遵循Wikipedia article),除了某些角度的线条外,它的工作正常。应该在45度和90度之间或者在135度和270度之间延伸的所有线将沿着线y = x延伸。
这是我的代码:
def bresenham(origin, dest):
# debug code
print origin
print dest
# end debug code
x0 = origin[0]; y0 = origin[1]
x1 = dest[0]; y1 = dest[1]
steep = abs(y1 - y0) > abs(x1 - x0)
backward = x0 > x1
if steep:
x0, y0 = y0, x0
x1, y1 = y1, x1
if backward:
x0, x1 = x1, x0
y0, y1 = y1, y0
dx = x1 - x0
dy = abs(y1 - y0)
error = dx / 2
y = y0
if y0 < y1: ystep = 1
else: ystep = -1
result = []
#if x0 > x1: xstep = -1
#else: xstep = 1
# debug code
print "x0 = %d" % (x0)
print "x1 = %d" % (x1)
print "y0 = %d" % (y0)
print "y1 = %d" % (y1)
for x in range(x0, x1):
if steep: result.append((y,x))
else: result.append((x,y))
error -= dy
if error < 0:
y += ystep
error += dx
# ensure the line extends from the starting point to the destination
# and not vice-versa
if backward: result.reverse()
print result
return result
任何人都能看到我搞砸了什么?
编辑:
我在函数中添加了一些打印代码。
(0,0)位于显示屏的左上角。
我的测试框架非常简单。这是一个独立的功能,所以我只给它两点:
origin =(416,384)
dest =(440,347)
布雷森汉姆(origin,dest)
(416,384)
(440,347)
x0 = 384
x1 = 347
y0 = 416
y1 = 440
[]
答案 0 :(得分:4)
我不知道你为什么要使用xstep变量。你真的不需要使用你正在使用的算法。
@Gabe:xstep是必需的,因为没有它,如果x0&gt; x1,然后for循环将立即终止,因为Python for循环的默认步骤是1。
你不需要xstep变量的原因是因为,如果它向后移动,坐标已经被切换(在开头的if backward:
条件中),所以终点现在是开始 - 点,反之亦然,这样我们现在仍然从左到右。
你只需要这个:
result = []
for x in range(x0, x1):
if steep: result.append((y, x))
else: result.append((x, y))
error -= dy
if error < 0:
y += ystep
error += dx
return result
如果您想要从开始到结束点的顺序列表,那么您可以在结尾处进行检查:
if backward: return result.reverse()
else: return result
编辑:问题是{<1}}布尔值在需要之前正在评估。如果backward
条件执行,则值会更改,但到那时您的steep
条件会有所不同。要解决此问题,请将其设置为显式表达式,而不是使用backward
布尔值:
backward
然后,再次,因为你最后使用布尔值,你可以在条件之前定义它:
if x0 > x1:
# swapping here
答案 1 :(得分:4)
问题是您在交换x0 > x1
和x
之前计算y
。
而不是:
backward = x0 > x1
if steep:
x0, y0 = y0, x0
x1, y1 = y1, x1
if backward:
x0, x1 = x1, x0
y0, y1 = y1, y0
你应该:
if steep:
x0, y0 = y0, x0
x1, y1 = y1, x1
backward = x0 > x1
if backward:
x0, x1 = x1, x0
y0, y1 = y1, y0