В этом разделе представлены алгоритмы триангуляции многоугольников, которые работают только с индексами вершин, а тип вершин и размерность пространства может быть произвольной. При этом среди множества различных вариантов триангуляции ищется в некотором смысле лучшая. Дело в том, что два соседних треугольника образуют четырёхугольник, у которого можно поменять диагональ. При этом качество триангуляции может улучшиться или ухудшиться. Шаблон функций maxL1 осуществляет локальную оптимизацию уже существующей триангуляции:template <class F, class A1, class A2=A1> class Func2a // Функция двух аргументов { public: virtual F operator () ( A1 a1, A2 a2 ) const = 0; }; template <F, class A1, class A2=A1, class A3=A2> class Func3a // Функция трёх аргументов { public: virtual F operator () ( A1 a1, A2 a2, A3 a3 ) const = 0; }; struct SemiRib { unsigned int next; unsigned int twin; unsigned int vert; }; template <class T> void maxL1 ( const Func3a<T,nat> & quality, const Func2a<T,T> & merge, ArrRef<SemiRib> & rib ) ... Исходными данными являются: функтор качества треугольника, функтор слияния качеств,
количество рёбер, ссылка на массив с рёбрами. В массиве должна быть записана какая-то триангуляция.
Причём рёбра принадлежащие к одному треугольнику должны находится последовательно,
а поле twin должно быть меньше количества рёбер только у одного ребра из пары.
В начале 2025 года я написал функцию optiL, которая делает то же самое, что и maxL1, но при этом не является шаблоном, и используемый в ней функтор IDiagFunc прямо указывает - нужно ли изменить для данной пары треугольников диагональ. Для этого ему надо передать индекс полуребра и номера граней. Имеется две функции optiL. Первая использует уже созданный массив полурёбер rib, а вторая заполняет его по указанной триангуляции trian: class IDiagFunc { public: virtual IDiagFunc & link ( CArrRef<SemiRib> & r ) = 0; virtual bool operator () ( nat r, nat s1, nat s2 ) = 0; }; void optiL ( IDiagFunc & change, ArrRef<SemiRib> & rib ); void optiL ( IDiagFunc & change, CCArrRef<Set3<nat> > & trian, DynArray<SemiRib> & rib ); По идее шаблон maxL1 можно везде заменить на функцию optiL, но я пока это сделал в отдельных случаях. Шаблон функций maxG1 осуществляет глобальную оптимизацию путём перебора всех возможных вариантов триангуляции: template <class T> SuiteRef<Set3<nat> > & maxG1 ( const Func3a<T,nat> & quality, const Func2a<T,T> & merge, nat nv, SuiteRef<Set3<nat> > & res ) ...Исходными данными являются: функтор качества треугольника, функтор слияния качеств, количество вершин многоугольника и ссылка на массив, куда записывается результат триангуляции. Этот алгоритм требует дополнительной памяти O ( n 2 ) и времени O ( n 3 ). Описание шаблона классов Set3 находится здесь.
|