2

これは Python と Pygame で実装されていますが、かなり一般的なプログラミングの問題です (つまり、実装に依存しません)。

入力として x と y の整数を取り、隣接する点 (x と y を含む) の 3x3 グリッドを生成する関数があります。

注: 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になります)。したがって、radius 値 2 を渡すと、上記の方法はすぐに面倒になります。より一般的な方法はありますか?

4

2 に答える 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
于 2012-07-15T21:32:25.600 に答える
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))の順序で値を格納することをお勧めします。

于 2012-07-15T21:54:30.690 に答える