Поскольку наивный подход не работает из-за появления новых ребер и вершин в объединении (см. Старый ответ и комментарии), нам потребуется использовать более сложную структуру данных.
Идея состоит в том, чтобы идентифицировать ребро во входном наборе, которое содержит ребро выходного набора. Под «содержит» я подразумеваю, что обе вершины ребра из выходного набора должны находиться на ребре из входного набора. Итак, нам нужно найти входной набор ребер, который содержит отрезок, который проходит через обе вершины рассматриваемого ребра.
Простой способ отфильтровать большое количество ребер, заданных для поиска, - это использовать ограничивающие прямоугольники: если проверяемая вершина не лежит внутри ограничивающего прямоугольника, образованного двумя вершинами ребра, то мы могу исключить это. Основной алгоритм, то есть:
INPUT: край выходного многоугольника E1 с конечными точками V1 и V2.
ВЫХОД: ребро из входных полигонов, где оба ребра V1 и V2 находятся на ребре.
- Получить набор ребер из входного набора, ограничивающие прямоугольники которого содержат как V1, так и V2 (или, другими словами, ограничивающий прямоугольник, образованный V1, V2)
- Поиск грубой силы для ребра, на котором лежат оба V1 и V2.
Второй шаг очевиден. Есть несколько мест, чтобы посмотреть на первое. Дерево K-D (объемный объект) выглядит так, как будто бы оно решило проблему. Или, может быть, R-дерево. Также проверьте stackoverflow для похожих вопросов . К сожалению, я не очень разбираюсь в пространственных алгоритмах, чтобы предложить подходящий.
СТАРЫЙ ОТВЕТ:
Я не думаю, что вам нужны какие-то причудливые структуры данных для обработки дела. Я предполагаю, что координаты вершин в объединении идентичны координатам в вашем исходном наборе. Таким образом, вы можете сделать что-то вроде: создать список вершин для ваших входных данных, где каждая вершина записывает полигон (ы), которому она принадлежит. Сделайте их легко доступными для поиска: наивным подходом будет отсортировать их сначала по одной координате, а затем по другой. Таким образом, вы можете найти любую вершину в O (log n).
Теперь для любого заданного ребра многоугольника объединения найдите первую вершину ребра, а затем найдите другую. Возьмите пересечение множеств полигонов, которым они принадлежат, и вы получите оригинальный многоугольник. Чтобы ускорить поиск второй вершины, вы также можете добавить список связанных вершин в исходный список, чтобы не выполнять повторный полный поиск.
Окончательной оптимизацией является предварительный расчет: просто запустите приведенный выше алгоритм и запишите результаты для каждого ребра, а затем избавьтесь от всех таблиц вершин и ребер. Если вам не нужна предварительно вычисленная таблица, вы можете отфильтровать исходный набор вершин для вершин, которые не отображаются в объединении.