2012-07-15 115 views
2

这是用Python和Pygame实现的,但它是一个相当普遍的编程问题(意思是独立于实现)。Python/Pygame - 网格上最近的坐标

我有一个函数,它需要输入一个x和y的整数,并应该生成一个3x3的相邻点(包括x和y)的网格。

注意:0,0原点从左上角开始。 x向右移动时增加,y向下移动时增加。

例如,

def nearest_grid(x, y): 
    return [[(x-1,y-1),(x,y-1),(x+1,y-1)],[(x-1,y)(x,y),(x+1,y)],[(x-1,y+1),(x,y+1),(x+1,y+1)]] 

所以,对于一个网格,一个点(标有P),它返回以下为3只列出一个清单:

x x x 
x p x 
x x x 

这是在Python做到这一点的最有效/易读的方式?

编辑:假设我想传递一个半径值(其中上述半径值为1)。所以,如果我通过的半径值为2,那么上述方法很快就会变得令人厌烦。有更通用的方法吗?

回答

5
def nearby_grid_points(x, y, r=1): 
    res = [] 
    for dy in xrange(-r, r+1): 
     res.append([(x+dx, y+dy) for dx in xrange(-r, r+1)]) 
    return res 
+1

对于xrange(-r,r + 1)中dy的xrange(-r,r + 1)中的dx,您还可以使用更紧凑的版本:[(x + dx,y + dy)] – pmoleri 2012-07-16 14:38:59

+0

我道歉花了这么长时间来接受这个答案。 – sdasdadas 2012-08-10 16:10:10

2

我比较喜欢这个numpy为基础的解决方案:

>>> import numpy 
>>> def nearest_grid(x, y, radius=1): 
...  X, Y = numpy.mgrid[-radius:radius + 1, -radius:radius + 1] 
...  return numpy.dstack((X + x, Y + y)) 
... 
>>> nearest_grid(1, 2) 
array([[[0, 1], 
     [0, 2], 
     [0, 3]], 

     [[1, 1], 
     [1, 2], 
     [1, 3]], 

     [[2, 1], 
     [2, 2], 
     [2, 3]]]) 

这里有一个高度概括的版本,接受任意数量的坐标。这不会将退货清单分成网格;它只是返回一个简单的邻居列表。

>>> def nearest_grid(*dims, **kwargs): 
...  radius = kwargs.get('radius', 1) 
...  width = radius * 2 + 1 
...  dims = (d - radius for d in dims) 
...  return list(itertools.product(*(xrange(d, d + width) for d in dims))) 
... 
>>> nearest_grid(1, 2, 3, radius=1) 
[(0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 2), (0, 2, 3), (0, 2, 4), 
(0, 3, 2), (0, 3, 3), (0, 3, 4), (1, 1, 2), (1, 1, 3), (1, 1, 4), 
(1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 3), (1, 3, 4), 
(2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 2), (2, 2, 3), (2, 2, 4), 
(2, 3, 2), (2, 3, 3), (2, 3, 4)] 

请注意,这些都以您请求的相反顺序返回索引。从表面上看,这仅仅意味着您只需要颠倒参数的顺序 - 即通过(y, x)(z, y, x)而不是(x, y)(x, y, z)。我可以为你做这个,但是用这种方法观察问题。

>>> def nearest_grid(x, y, radius=1): 
...  X, Y = numpy.mgrid[-radius:radius + 1, -radius:radius + 1] 
...  return numpy.dstack((Y + y, X + x)) 
... 
>>> grid 
array([[[0, 0], 
     [1, 0], 
     [2, 0]], 

     [[0, 1], 
     [1, 1], 
     [2, 1]], 

     [[0, 2], 
     [1, 2], 
     [2, 2]]]) 

现在我们有一个网格,其中的值以[x, y]的顺序存储。当我们将它们用作grid的索引时会发生什么?

>>> grid = nearest_grid(1, 1) 
>>> x, y = 0, 2 
>>> grid[x][y] 
array([2, 0]) 

我们没有得到我们预期的细胞!这是因为与布局,像这样的网格:

grid = [[(x, y), (x, y), (x, y)], 
     [(x, y), (x, y), (x, y)], 
     [(x, y), (x, y), (x, y)]] 

grid[0]给我们的第一行,即y = 0行。所以,现在我们要颠倒顺序:

>>> grid[y][x] 
array([0, 2]) 

更好的存储值行主((y, x))顺序。