Python/Pygame-网格上最近的坐标

Python/Pygame-网格上最近的坐标,python,grid,pygame,Python,Grid,Pygame,这是用Python和Pygame实现的,但这是一个相当普遍的编程问题(意味着独立于实现) 我有一个函数,它以一个x和y整数作为输入,应该生成一个3x3的相邻点网格(包括x和y) 注意:0,0原点从左上角开始。x随着向右移动而增加,y随着向下移动而增加 例如 因此,给定一个网格和一个点(标记为p),它返回以下3个列表: x x x x p x x x x 在Python中,这是最有效/易读的方法吗 编辑:假设我想要传递一个半径值(上面的半径值是1)。因此,如果我通过半径值2,那么上述

这是用Python和Pygame实现的,但这是一个相当普遍的编程问题(意味着独立于实现)

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

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

例如

因此,给定一个网格和一个点(标记为p),它返回以下3个列表:

x  x  x
x  p  x
x  x  x
在Python中,这是最有效/易读的方法吗


编辑:假设我想要传递一个半径值(上面的半径值是1)。因此,如果我通过半径值2,那么上述方法将很快变得令人厌烦。有更通用的方法吗?

我更喜欢这种基于
numpy
的解决方案:

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
>>> 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 = 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)
)顺序存储值

您还可以使用更紧凑的版本:[(x+dx,y+dy)表示xrange中的dx(-r,r+1)表示xrange中的dy(-r,r+1)]
>>> grid[y][x]
array([0, 2])