Мне больше нравится это решение на основе 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)
).
person
senderle
schedule
15.07.2012