私はむしろこの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)
)の順序で値を格納することをお勧めします。