Найти ближайшую точку в сетке matlab
драсте
Я пытаюсь запрограммировать умный способ найти ближайшие точки сетки к точкам вдоль контура.
сетка представляет собой 2-мерную сетку, хранящуюся в x
и y
(которые содержат позиции X и y километров ячеек сетки).
контур представляет собой линию, состоящую из X и y местоположений, не обязательно равномерно расположенных.
это показано ниже-красные точки являются сеткой, а синие точки являются точками на контур. Как найти индексы красной точки, ближайшей к каждой синей точке?
Edit-я должен упомянуть, что сетка представляет собой сетку широты/долготы области, довольно близкой к Южному полюсу. Таким образом, точки (красные точки) - это положение в метрах от южного полюса (с использованием полярного стереографического представления). Поскольку сетка является географической сеткой, существует неравное расстояние между сетками-с немного разными фигурными ячейками (где красные точки определить вершины ячеек) из-за искажений на высоких широтах.
В результате я не могу просто найти, какая строка / столбец x
и y
матрица соответствует ближайшим к входным координатам точек-в отличие от обычной сетки из meshgrid
значения в строках и столбцы различаются...
Ура Дэйв!--6-->
4 ответов
обычный метод состоит в том, чтобы пойти:
for every blue point {
for every red point {
is this the closest so far
}
}
но лучший способ-поместить красные данные в дерево kd. Это дерево, которое разбивает данные по среднему значению, затем разбивает два набора данных по среднему значению и т. д., пока они не будут разделены на древовидную структуру.
это изменит вашу эффективность поиска от O(n*m)
to O(log(n)*m)
здесь-библиотека:
http://www.mathworks.com.au/matlabcentral/fileexchange/4586-k-d-tree
эта библиотека предоставит вам средства, чтобы легко сделать дерево kd из данных и искать ближайшую точку в нем.
В качестве альтернативы вы можете использовать quadtree, не так просто, но та же идея. (возможно, для этого вам придется написать собственную библиотеку)
убедитесь, что самый большой набор данных (в этом случае ваши красные точки) входит в дерево, как это будет обеспечивает наибольшее сокращение времени.
Я думаю, что я нашел способ сделать это с помощью nearest
флаг griddata
.
я делаю матрицу того же размера, что и сетка x
и y
матрицы, но заполняется линейными индексами соответствующего матричного элемента. Это формируется путем изменения вектора (который является 1:size(x,1)*size(x,2)
) до тех же размеров, что и x
.
я тогда использую griddata
и nearest
флаг, чтобы найти линейный индекс точки, ближайшей к каждой точке моего контура (синие точки). Затем просто преобразуйте обратно в нотацию индекса с помощью ind2sub
оставляет меня с векторами строк 2, описывающими матричные индексы для точек, ближайших к каждой точке контура с синими точками.
на этом графике ниже показаны контур (синие точки), сетка (красные точки) и ближайшие точки сетки (зеленые точки).
это фрагмент кода, который я использовал:
index_matrix1 = 1:size(x,1)*size(x,2);
index_matrix1 = reshape(index_matrix1,size(x));
lin_ind = griddata(x,y,index_matrix1,CX,CY,'nearest'); % where CX and CY are the coords of the contour
[sub_ind(1,:),sub_ind(2,:)] = ind2sub(size(x),lin_ind);
я полагаю, что в стереографическом представлении ваши точки образуют аккуратную сетку в r
-theta
координаты. (Я не слишком знаком с этим, поэтому поправьте меня, если я ошибаюсь. Мое предложение все еще может применяться).
для построения графика вы конвертируете из стереографического в широту-долготу, которая искажает сетку. Однако для нахождения ближайшей точки рассмотрим преобразование широты-долготы точек синего контура в стереографические координаты, где легко определите ячейку для каждой точки, используя ее r
и theta
значения.
если вы можете индексировать ячейку в стереографическом представлении, индекс будет таким же при преобразовании в другое представление.
основное требование заключается в том, что при некотором преобразовании точки сетки определяются двумя векторами, X
и Y
, так что для любой x
на X
и y
на Y
, (x, y)
точка сетки. Затем преобразуйте как сетку, так и контур указывает на это преобразование. Тогда задана произвольная точка (x1, y1)
, мы можем найти соответствующую ячейку, найдя ближайший x
to x1
и ближайший y
to y1
. Преобразуйте назад, чтобы получить точки в нужной системе координат.
dsearchn
: N-D поиск ближайшей точки.
[k, d] = dsearchn(A,B)
: возвращает расстояния, d, до ближайших точек. d-вектор столбца длины p.
http://au.mathworks.com/help/matlab/ref/dsearchn.html?s_tid=gn_loc_drop