2015-08-08 2 views
0

Учитывая список точек obstacles (заданные в виде списка row, column матричных координат, в ndarray формы (n, 2)), возвращает карту размера size (где size является формой массив 2D NumPy), в котором значение r, c является евклидовым расстоянием до ближайшего «препятствия».вычисление карты минимального расстояния до числа точек

def gen_distgrid(size, obstacles): 
    n_obstacles = obstacles.shape[0] 
    distgrids = np.zeros((n_obstacles + 4, size[0], size[1])) 
    for layer in range(n_obstacles): 
     for i in range(size[0]): 
      for j in range(size[1]): 
       distgrids[layer, i, j] = np.linalg.norm(obstacles[layer,:] - [i,j]) 
    for i in range(size[0]): 
      for j in range(size[1]): 
       distgrids[n_obstacles + 0, i, j] = i 
       distgrids[n_obstacles + 1, i, j] = (size[0] - i) 
       distgrids[n_obstacles + 2, i, j] = j 
       distgrids[n_obstacles + 3, i, j] = (size[1] - j) 
    distgrid = np.min(distgrids, axis=0) 
    return distgrid 

Мой метод очень медленный, и я чувствую, что должен быть лучший.

+0

Извините, что такое 'r' и' c'? – mgilson

+0

@mgilson: строка и столбец, или вы можете сказать 'i, j'. –

+0

Итак, для каждого препятствия вы хотите узнать, какое другое препятствие является самым близким? – mgilson

ответ

0

В итоге я использовал a KD-tree от SciPy. Он имеет очень легкую функцию расстояния.

from scipy.spatial import cKDTree as KDTree 
def gen_distgrid(obstacles): 
    n_obstacles = obstacles.shape[0] 
    obstacles = np.vstack((obstacles, [0,0], [0, size[1] - 1], [size[0] - 1, 0], [size[0] - 1, size[1] - 1])) 

    distgrid = np.zeros((size[0], size[1])) 
    obs_tree = KDTree(data=obstacles) 

    i_v = np.arange(size[0]) 
    j_v = np.arange(size[1]) 

    coordmat = np.dstack(np.meshgrid(i_v, j_v, indexing='ij')) 
    obs_dists, obs_locs = obs_tree.query(coordmat) 

    top_dists = np.repeat(i_v, size[1]).reshape(size) 
    bottom_dists = np.repeat(size[0] - i_v, size[1]).reshape(size) 
    left_dists = np.repeat(j_v, size[0]).reshape(np.transpose(size)).T 
    right_dists = np.repeat(size[1] - j_v, size[0]).reshape(np.transpose(size)).T 

    dists = np.min([obs_dists, top_dists, bottom_dists, left_dists, right_dists], axis=0) 
    return dists 
+0

Это не лучший теоретик, но это потрясающе быстро, как есть. –

0

Here - решение аналогичной проблемы с использованием KD-дерева с Numpy и SciPy. Просто вставьте свои препятствия в KD-дерево и запросите дерево для каждой точки сетки, чтобы получить ближайшего соседа.

Смежные вопросы