Преобразование из треугольной полосы в многоугольник - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть несколько областей, которые содержат 1 или более полигонов.Каждый многоугольник представлен в формате GL_TRIANGLE_STRIP, где каждая вершина является парой (широта, долгота).Есть ли способ получить контуры местности?

Некоторые характеристики:

  • Контуры должны быть в порядке против часовой стрелки.
  • Любые 2 полигона могут иметь один общий край.
  • Полигоны могут бытьвогнутый
  • У многоугольника может быть максимум 1 «пробел» внутри него, который будет представлен другим контуром по часовой стрелке.

Я ищу алгоритм, сложность котороговокруг O (N * logN), где N = количество вершин.

РЕДАКТИРОВАТЬ: я пробовал решения, такие как идти 2 на 2, пока я не достигну конца набора данных, а затем идти назад, но этот алгоритм работает плохона многоугольниках с пробелами, например этот многоугольник , где ввод равен: A B C D E F G H I J, где I = A и J = B, при этом вывод будет A C E G I J H F D B, и это должно быть A C E G иB H F G (порядок инвертирован, потому что его было проще рисовать таким образом).

Другое решение заключалось в рассмотрении точек ненаправленного графа и ребер между ними (согласно формату GL_TRIANGLE_STRIP), где я применил DFS длявне связиmponents.После этого я вычислил площадь каждого компонента и рассмотрел многоугольник максимальной площади как контур против часовой стрелки, а остальные - как контур по часовой стрелке.Это не работает, потому что список смежности требует некоторой сортировки, которая сделает алгоритм неэффективным.

Другое решение, которое я попробовал, было немного измененным выпуклым корпусом, но выпуклый корпус все еще является выпуклым корпусом и не работал на вогнутых многоугольниках.

Я также читал о вогнутом корпусе, но, похоже, это не всегда дает точные результаты.

Спасибо за ваши ответы!

1 Ответ

1 голос
/ 25 сентября 2019

Давайте начнем с преобразования полосы треугольника в многоугольник.В качестве примера мы берем следующую полосу:

Triangle Strip (Предоставлено Wikimedia Commons)

Ваше определение полосы будет выглядеть следующим образом:

A B C D E F

Преобразование этого в многоугольникэто очень просто.Просто пройдите по списку и используйте каждую вторую вершину.Когда вы в конце, вернитесь назад и используйте другие вершины.В этом случае:

A C E (reached the end, now return) F D B

Это можно сделать в O (N) , где N - количество вершин полосы.Будет ли это по часовой стрелке или против часовой стрелки, зависит от ориентации полосы.

Итак, мы можем превратить каждую полосу в многоугольник.Осталось только удалить общие ребра.Допустим, у нас есть два многоугольника

A C E F D B
W X E C Y Z

Обратите внимание, что любое общее ребро (в данном случае C E) будет появляться в противоположных направлениях (C E в первом многоугольнике, E C во второмодин).Чтобы найти контур области, нам просто нужно найти совпадающие ребра и объединить два многоугольника.

Чтобы найти совпадающие ребра, достаточно записать все ребра многоугольника в хеш-карту (сохраните, к какому многоугольнику они принадлежати где они находятся в многоугольнике).Это можно сделать в O (E) , где E - общее количество ребер многоугольника.

Чтобы окончательно объединить многоугольники, на самом деле проще создать новыйиз них.Модификация определенно возможна, но немного более тонкая.Для этого нам просто нужно пройтись по краям нашего многоугольника.Пока мы находимся на ребре, обратная сторона которого отсутствует в хэш-карте, тогда запишите это ребро в выходной многоугольник.Если это так, игнорируйте его и переходите к другому многоугольнику.Отметьте края, которые вы посетили, и остановитесь, как только вернетесь к краю, который вы посетили раньше.Делайте это до тех пор, пока не будут посещены все ребра (или оба направления находятся на хэш-карте).Весь этот процесс может быть выполнен в O (E) , где E - общее количество ребер многоугольника.

Вот как это будет выглядеть в нашем примере:

Start at polygon 1
Start at edge (A, C)
(A, C) is neither visited nor is its inverse in the hash map
Create new output area = [A, C]
the inverse of (C, E) is in the hash map, continue to polygon 2
(C, Y) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y]
(Y, Z) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z]
(Z, W) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W]
(W, X) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X]
(X, E) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E]
the inverse of (E, C) is in the hash map, continue to polygon 1
(E, F) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F]
(F, D) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F, D]
(D, B) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F, D, B]
(B, A) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F, D, B, A]
(A, C) is already visited
Close the area contour, continue to check other unvisited edges

Если вы хотите, вы можете также сгруппировать сгенерированные контуры по полигонам, из которых они были созданы, чтобы найти связанные области, которыеограничены несколькими контурами. несвязный набор над полигонами будет полезен для этой задачи.Если вам нужно, вы также можете попытаться классифицировать контуры на отверстия и внешние контуры.Но имейте в виду, что это понятие весьма неоднозначно для сферы (представьте себе сферу и область, которая является полосой вдоль экватора - какой из двух контуров является дырой, а какой снаружи?) Для сравнительно небольших областей вы могли бы использоватьобласть для этой классификации.

...