Триангуляция многоугольников на плоскости

В настоящее время наиболее практичные алгоритмы триангуляции многоугольников состоят из двух этапов. На первом этапе исходный многоугольник разбивается на монотонные многоугольники, а на втором этапе полученные многоугольники триангулируются за линейное время.

Функция trianSweepLine использует на первом этапе алгоритм "заметающей прямой". В книге Майкла Ласло "Вычислительная геометрия и компьютерная графика на С++" есть описание двухпроходного алгоритма, и сначала я сделал похожий, но в 2018 году придумал однопроходной, к тому же я обобщил его на случай многоугольников с дырками:

SuiteRef<Set3<nat>> & trianSweepLine ( CCArrRef<Vector2d> & vert, SuiteRef<Set3<nat> > & res );
SuiteRef<Set3<nat>> & trianSweepLine ( CCArrRef<nat> & cntr, 
                                       CCArrRef<Vector2d> & vert, SuiteRef<Set3<nat> > & res );
Здесь cntr - это количества вершин многоугольников, vert - общий массив всех вершин, res - треугольники. Внешний многоугольник должен иметь обход вершин против часовой стрелки, а внутренние - по часовой. Порядок перечисления многоугольников произвольный.

Функция trianSeidel использует на первом этапе алгоритм Зейделя:

SuiteRef<Set3<nat>> & trianSeidel ( CCArrRef<Vector2d> & vert, SuiteRef<Set3<nat> > & res );
SuiteRef<Set3<nat>> & trianSeidel ( CCArrRef<nat> & cntr, 
                                    CCArrRef<Vector2d> & vert, SuiteRef<Set3<nat> > & res );

В моих экспериментах функция trianSweepLine работала быстрее функции trianSeidel в среднем в 6 раз.

В результате построения триангуляции этими алгоритмами могут появляться очень узкие треугольники. Чтобы избавится от них можно применить функцию rebuildDelauney, которая получает на входе какую-то триангуляцию и переделывает её в триангуляцию Делоне для многоугольников:

ArrRef<Set3<nat>> & rebuildDelauney ( CCArrRef<Vector2d> & vert, ArrRef<Set3<nat> > & res )

Эта функция использует шаблон maxL1. В моих экспериментах функция rebuildDelauney работала медленее функции trianSweepLine в среднем в 3 раза.

Описание класса Vector2d смотрите в разделе Вектора на плоскости.
Описание шаблонов классов CCArrRef, ArrRef и SuiteRef находится здесь.
Описание шаблона Set3 находится здесь.
Исходники алгоритмов находятся в файле trian2d.cpp.

Наверх