Участник:Kabanov
Триангуляция полигона — декомпозиция многоугольника
на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет . В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.
Теорема о существовании триангуляции
Простым многоугольником является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.
Теорема (О существовании триангуляции многоугольника): |
У любого простого -вершинного многоугольника всегда существует триангуляция, причём количество треугольников в ней независимо от самой триангуляции. |
Доказательство: |
Доказательство ведётся индуктивно по Докажем, что триангуляция . При теорема тривиальна. Рассмотрим случай при и предположим, что теорема выполняется при всех . Докажем существование диагонали в многоугольнике . Возьмём самую левую по оси вершину многоугольника и две смежных с ней вершины и . Если отрезок принадлежит внутренней области — мы нашли диагональ. В противном случае, во внутренней области треугольника или на самом отрезке содержится одна или несколько вершин . Выберем из них наиболее удалённую от вершину . Отрезок, соединяющий и не может пересекать ребро , поскольку в противном случае одна из вершин этого ребра будет располагаться дальше от , чем . Это противоречит условию выбора . В итоге получаем, что — диагональ. Любая диагональ делит на два многоугольника и . За и обозначим количество вершин в и соответственно. и , поэтому по предположению индукции у и существует триангуляция, следовательно и у она существует. состоит из треугольников. Рассмотрим произвольную диагональ в триангуляции . делит на два многоугольника и , количество вершин в которых и соответственно. Каждая вершина встречается только в одном из двух многоугольников и , за исключением тех, которые являются концами , поэтому справедливо следующее: . По индукции, любая триангуляция состоит из треугольников, откуда следует, что . состоит из треугольников. |
Ушной метод
Определение: |
Вершина | называется ухом, если диагональ лежит строго во внутренней области многоугольника
Теорема (О существовании двух ушей многоугольника): |
У любого простого -вершинного многоугольника всегда существует два не пересекающихся между собой уха. |
Доказательство: |
Доказательство будем вести по индукции. Базовый случай: . Предположим для всех многоугольников, количество вершин в которых не больше , теорема верна. Рассмотрим многоугольник , в котором вершина. Далее возможны два случая:
|
Идея
Рассмотрим все вершины многоугольника
, и где возможно, будем отрезать уши до тех пор, пока не станет треугольником.Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю
, т.е. и . Если вершина является ухом, построим диагональ и отрежем треугольник от . В противном случае переходим к следующей вершине в порядке обхода.Алгоритм
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись левым поворотом. "Ушную" проверку вершины будем осуществлять алгоритмом принадлежности точки -угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.
Псевдокод
DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL DCEL D2 Construct(D1); Construct(D2); vertex v = random_vertex_of(D1); while size_of(D1)3 if IsConvex(v) //проверка на выпуклость for each Vertex v_i in D1 if v_i v, v.prev(), v.next() //проверка всех вершин на and v_i Triangle(v, v.prev(), v.next())//принадлежность треугольнику, //одной из вершин которого //является потенциальное ухо v. edge e = new edge(v.prev, v.next) Insert e in D2; v = v.next Delete v.prev from D1
Корректность
При нахождении каждого уха от многоугольника
отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.Оценка работы
Изначально в многоугольнике содержится
ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами . Итого общее количество ушей будет . Определить, является ли вершина ухом можно за , поскольку используется алгоритм определения принадлежности точки треугольнику — это . Таким образом общий процесс отрезания ушей займёт . Невыпуклых вершин всего , каждая из них обрабатывается за константу, поэтому общее время для их обработки . Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время . Поскольку храним только два списка — память линейная.