Рассмотрим 2-D (широта, долгота) множество точек. Точки в наборе равны (приблизительно) с взаимным расстоянием 0,1 градуса\раз 0,1 градуса. Каждая точка в множестве - это центр квадратной сетки с длиной стороны 0,1 градуса (т.е. Точка пересечения двух диагоналей квадрата). Каждый квадрат находится рядом с соседними квадратами.
Наша цель - получить координаты многоугольника контура, образованного граничными гранями квадратных сеток с заданным направлением (будет проиллюстрировано рисунком). Этот полигон не имеет отверстия внутри.
Рассмотрим примерный набор данных размера 10 (набор точек).
lat_x <- c(21.00749, 21.02675, 21.00396, 21.04602, 21.02317,
21.06524, 21.00008, 21.04247, 21.08454, 21.0192)
а также
lon_y <- c(88.21993, 88.25369, 88.31292, 88.28740, 88.34669,
88.32118, 88.40608, 88.38045, 88.35494, 88.43984)
Вот приблизительный график вышеупомянутых точек, за которым следует некоторая иллюстрация,
Черными точками являются (lat, lon) точки в приведенном выше образце.
Синие квадратные квадраты представляют собой квадратную сетку.
Данные направления (\ theta) квадратов составляют $ theta $ = 50 градусов.
Наша цель - получить упорядоченные (по часовой стрелке или против часовой стрелки) координаты контура полигона (желтого цвета).
Примечание. Этот вопрос очень похож на этот вопрос с хорошим ответом, данным @laune. Цель состоит в том, чтобы получить контурный полигон без направления (или направление 0 градусов). Но в нынешней настройке мне нужно включить направление (ненулевое), рисуя квадратные сетки и полученный многоугольник.
Я с благодарностью буду благодарен за любые предложения, java или R-коды или полезную ссылку, данную кем-либо, кто решает вышеуказанную проблему.
Я бы сделал это так:
может быть какая-то 2D-группировка точек массива в соответствии с сеткой
что должно ускорить выполнение всех следующих операций.
вычислить средние размеры сетки (img1 слева)
как два вектора
создать синие точки (img2)
as: gray_point (+ / -) 0.5*blue_vector
создать красные точки (img3)
как: blue_point (+ / -) 0.5*red_vector
создать список серых линий (img4)
возьмите все 2 оригинальные (серые) точки с расстоянием, близким к среднему расстоянию сетки, и добавьте для них линию
создать список красных линий (img4)
возьмите все 2 оригинальные (серые) точки с расстоянием, близким к среднему расстоянию сетки, и добавьте для них линию, если она не пересекает ни одну линию от серой линии
переупорядочить точки линии для соответствия полигональной обмотке...
угол
вычислить угол красного вектора (через atan2)
вычислить угол синего вектора (через atan2)
вернуть значение с меньшей абсолютной величиной
[edit1] ответ на комментарии
размер сетки
найдите несколько точек, которые ближе всего друг к другу, поэтому выберите любую точку и найдите все ближайшие точки к ней. Возможные расстояния должны быть рядом:
sqrt(1.0)*d,sqrt(1+1)*d,sqrt(1+2)*d,sqrt(2+2)*d,...
где d
- размер сетки, поэтому вычислите d
для нескольких выбранных точек. Помните о первом наименьшем d
найденном и выбрасывайте все, что не похоже на самое маленькое. Сделайте средний из них и позвоните ему d
сетчатые векторы
Возьмите любую точку A
и найдите ближайшую точку B
к ней с расстоянием вблизи d
. Например, сравнение + / -10%
: |(|AB|-d)|<=0.1*d
Теперь вектор сетки (BA)
. Найдите несколько из них (выберите разные A,B
) и сгруппируйте их по знаку x,y
координат в 4 группы.
Затем объедините группы отрицательного направления, отменив один групповой векторы, так что у вас будет 2 списка векторов (красное, синее направление) и сделайте из них средние векторы (красные, синие векторы)
точки переключения
Вы берете любую точку A
и добавляете или вычитаете половину красного или синего вектора (например, не его размер !!!):
A.x+=0.5*red_vector.x;
A.y+=0.5*red_vector.y;
списки строк
Сделайте 2 вложенных for
каждую 2-точечную комбинацию A,B
(оригинал для серых линий, смещенные красные для красных линий линии) и добавьте условие для расстояния
|(|A-B|-d)|<=0.1*d
если это true
добавьте строку (A,B)
в список. Здесь pseudo C++ пример:
int i,j,N=?; // N is number of input points in pnt[]
double x,y,d=?,dd=d*d,de=0.1*d; // d is the avg grid size
double pnt[N][2]=?; // your 2D points
for (i=0;i<N;i++) // i - all points
for (j=i+1;j<N;j++) // j - just the rest no need to test already tested combinations
{
x=pnt[i][0]-pnt[j][0];
y=pnt[i][1]-pnt[j][1];
if (fabs((x*x)+(y*y)-dd)<=de) ... // add line pnt[i],pnt[j] to the list...
}