Це дуже гарне запитання. Я реалізував той самий алгоритм на c # деякий час тому. Алгоритм будує загальний контур з двох багатокутників (тобто будує об’єднання без дірок). Ось.
Крок 1. Створіть графік, що описує багатокутники.
Вхідні дані: перший багатокутник (n очок), другий багатокутник (m очок). Вихід: графік. Вершина - точка багатокутника точки перетину.
Ми повинні знайти перехрестя. Перегляньте всі сторони багатокутника в обох багатокутниках [O (n * m)] і знайдіть будь-які перехрестя.
Якщо перетину не знайдено, просто додайте вершини і з’єднайте їх з ребром.
Якщо знайдені перехрестя, відсортуйте їх за довжиною до початкової точки, додайте всі вершини (початок, кінець та перехрещення) та з’єднайте (вже в сортованому порядку) з ребром.
Крок 2. Перевірте побудований графік
Якщо ми не знайшли жодної точки перетину під час побудови графіка, ми маємо одну з таких умов:
- Багатокутник1 містить багатокутник2 - повернутий багатокутник1
- Багатокутник2 містить багатокутник1 - повернутий багатокутник2
- Багатокутник1 і багатокутник2 не перетинаються. Повернути багатокутник1 І багатокутник2.
Крок 3. Знайдіть ліву нижню вершину.
Знайдіть мінімальні координати x та y (minx, miny). Потім знайдіть мінімальну відстань між (minx, miny) та точками багатокутника. Ця точка буде лівою нижньою точкою.
Крок 4. Побудуйте загальний контур.
Ми починаємо обводити графік з лівої нижньої точки і продовжуємо, поки не повернемось до нього. На початку ми позначаємо всі краї як невидимі. На кожній ітерації слід вибрати наступний пункт і позначити його як відвіданий.
Щоб вибрати наступну точку, виберіть ребро з максимальним внутрішнім кутом у напрямку проти годинникової стрілки.
Я обчислюю два вектори: вектор1 для поточного ребра та вектор2 для кожного наступного невідвіданого ребра (як показано на малюнку).
Для векторів я обчислюю:
- Скалярний виріб (крапковий виріб). Він повертає значення, пов'язане з кутом між векторами.
- Векторний продукт (перехресний продукт). Він повертає новий вектор. Якщо z-координата цього вектора позитивна, скалярний добуток дає мені прямий кут у напрямку проти годинникової стрілки. В іншому випадку (z-координата від'ємна), я обчислюю отримати кут між векторами як 360 - кут від скалярного добутку.
В результаті я отримую ребро (і відповідну йому наступну вершину) з максимальним кутом.
Я додаю до списку результатів кожну передану вершину. Список результатів - багатокутник об'єднання.
Зауваження
- Цей алгоритм дозволяє об’єднати множину багатокутників - ітеративно застосовувати до пар полігонів.
- Якщо у вас є шлях, який складається з безлічі кривих і ліній Без'є, вам слід спочатку згладити цей шлях.