2012-07-15 56 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))順序。