从开始(X,Y)到目的地(X,Y)画一条线

时间:2014-01-27 09:34:40

标签: python debugging path line

我正在努力用一个世界地图制作一个简单的游戏,玩家可以使用点击并一直沿线的方式移动。为此,我试图制作一个简单的函数来计算玩家要经过的像素XY列表。

大部分工作正常,但我遇到问题,只要目的地X和Y不相等,就会将其中一个结果乘以2。我很难对这个问题进行故障排除,如果有人知道如何改进或修复它 - 我会非常感激。

import math

def linePath(start, finish):
    if start[0] == finish[0]:
        a = 1
    else:
        a = (finish[1] - start[1]) / float((finish[0] - start[0]))
    b = start[1] - (a * start[0])
    if abs(a) >= 1:
        rng = xrange(start[1], finish[1] + 1) or reversed(xrange(finish[1], start[1] + 1))
    else:
        rng = xrange(start[0], finish[0] + 1) or reversed(xrange(finish[0], start[0] + 1))
    for i in rng:
        if abs(a) >= 1:
            y = i
            x = int(math.ceil((y - b)/ a))
        else:
            x, y = i, start[1] + int(math.ceil(a * i + b))
        if start[0] != finish[0]:
            yield x, y
        else:
            yield start[0], y

start = (10, 10)
destination = (15, 15)

print list(linePath(start, destination))

#Bugs:   when start[0] > start[1] and start > destination (eg. destination = (16, 15))
        #when start[0] < start[1] and start < destination (eg. destination = (5, 6))

1 个答案:

答案 0 :(得分:0)

幸运的是,杰克埃尔顿布雷森汉姆为你解决了这个问题。

以下是在Bresenham's line algorithm找到的Roguebashin的实施:

def get_line(x1, y1, x2, y2):
    points = []
    issteep = abs(y2-y1) > abs(x2-x1)
    if issteep:
        x1, y1 = y1, x1
        x2, y2 = y2, x2
    rev = False
    if x1 > x2:
        x1, x2 = x2, x1
        y1, y2 = y2, y1
        rev = True
    deltax = x2 - x1
    deltay = abs(y2-y1)
    error = int(deltax / 2)
    y = y1
    ystep = None
    if y1 < y2:
        ystep = 1
    else:
        ystep = -1
    for x in range(x1, x2 + 1):
        if issteep:
            points.append((y, x))
        else:
            points.append((x, y))
        error -= deltay
        if error < 0:
            y += ystep
            error += deltax
    # Reverse the list if the coordinates were reversed
    if rev:
        points.reverse()
    return points

start = (10, 10)
destination = (16, 15)

print list(get_line(start[0], start[1], destination[0], destination[1]))

输出:

[(10, 10), (11, 11), (12, 12), (13, 12), (14, 13), (15, 14), (16, 15)]