Как стать автором
Обновить

Оптимизация алгоритма проверки условия Делоне через уравнение описанной окружности и его применение

Время на прочтение4 мин
Количество просмотров14K
Расскажу секрет о том, как быстро проверить выполнение условия Делоне для двух треугольников.
Собственно сама оптимизация описана немного ниже(см.«Оптимизация алгоритма проверки условия Делоне через уравнение описанной окружности»), но расскажу обо всем по порядку.

В моем случае триангуляция применяется в трассировке изображения, для разбиения плоскости на примитивные сектора (треугольники). Как известно, она делится также на несколько этапов: корректировка, выявление границ, обход границ, заметание контуров. Это в самом общем виде. Я бы хотел остановиться, думаю, на самом сложном этапе: заметание плоскости.

На входе

После обнаружения и обхода границ на выходе я получил множество внешних контуров. Каждые соприкасающиеся контура имеют разные цвета. Внутри каждого такого контура содержится также известное кол-во внутренних контуров.
Таким образом, с точки зрения «заметания плоскости», если рассматривать внешние контура отдельно, имеем множество точек, каждая из которых имеет по одному соседу справа и слева. Т.е. все точки замкнуты в цепи, нет ни одной одиночной «висячей» точки, а так же в каждой из цепей содержится не менее 3-ех точек (Рисунок 1).


Рисунок 1

Что надо сделать

Нужно заметать фигуру треугольниками.

Поиски

Прочитав книгу [1] не нашел ни одного (хотя бы одного) хоть сколько нибудь подходящего к моему случаю способа построения триангуляции Делоне. Искать другие книги не стал. Да и этой хватило, она привела мысли моей головы в порядок. В итоге изобрел свой «велосипед».

Алгоритм

1) Допустим, для начала, что в рассматриваемой фигуре всего одна последовательность. Тогда все сводится к последовательному забиранию треугольников. Берем любую точку и пытаемся построить треугольник с соседними точками. Если треугольник построить не получилось (линия связывающая эти две точки, пересекается с уже построенными или линия проходит в зоне отчуждения (Рисунок 2), двигаемся к соседней точке, допустим вправо. Когда очередной треугольник найден, заносим его в список (Рисунок 3), а точку из которой он строился удаляем (Рисунок 4).


Рисунок 2

Рисунок 3

Рисунок 4

Еще одно но: при сохранении очередного треугольника необходимо записывать вершины в обходе по часовой стрелке (в правой системе координат). Это пригодится в дальнейшем для уменьшения вычислительных ресурсов.

2) Повторяем шаг 1 пока не заметаем всю плоскость.

3) Если последовательностей несколько, т.е. одна, а внутри её еще одна или более внутренних контуров (Рисунок 1). Тут необходимо рассмотреть каждую последовательность отдельно. Возьмем очередной внутренний контур. Из одного внешнего и одного внутреннего сделаем два одиночных контура. Для этого нужно найти два «порта» из одного контура в другой. Условие для «портов»: они не должны пересекаться между собой(не должны соприкасаться даже концами), не должны пересекаться с линиями контуров (Рисунок 5).


Рисунок 5

Рисунок 6
4) Далее следует ввести поочередно все внутренние последовательности в уже образованные, отделенные друг от друга (пункт 3) последовательности. Сливать нужно с той, которая содержит новую. По определению ни одна внутренняя последовательность не касается и не пересекается с другими(как одной внешней, так и всеми возможными внутренними), так что все пройдет гладко.
Найдя порты (Рисунок 6) легко построить новые последовательности и обойти их пунктами 1 и 2 текущего алгоритма (Рисунок 7).

Рисунок 7

5) После 4-его этапа имеем список треугольников(Рисунок 8). Как бы с задачей уже справились, но осталось сделать картинку красивой: проверить выполнение условия Делоне (Рисунок 9).

Рисунок 8

Рисунок 9

6)Забегая вперед расскажу про шестой пункт. Он заключается в последовательном прогоне по списку полученных треугольников пунктом №5. Сначала метим все треугольники «грязными». В каждом цикле проверяем для каждого треугольника условие Делоне. Если условие не выполняется, то делаем перестроение и помечаем соседей и текущий треугольник «грязными». Если условие выполняется, то метим его чистым. В моей реализации алгоритма, каждый треугольник имеет ссылку на соседей. В этом случае 6-ой пункт работает наиболее быстро.

Подробнее о пятом этапе

Сейчас, на сколько я знаю, существуют два возможных способа определить удовлетворяют треугольники условию Делоне или нет: 1) Проверить сумму противоположных углов. Она должны быть меньше 180. 2) Вычислить центр описанной окружности и посчитать расстояние до 4-ой точки. Всем известно, условие Делоне выполняется, если точка находится за пределами описанной окружности.

Мощность вычислений №1: 10 операций умножения/деления и 13 операций сложения/вычитания.
Мощность вычислений №2: 29 операций умножения/деления и 24 операций сложения/вычитания.

С точки зрения вычислительной мощности, которая высчитывается к примеру в книге [1], выгоднее вариант №1. Его и реализовал, если бы не… (Рисунок 10). Как оказалось после постановки данного метода на «конвейер», получилась неопределенность. Это вариант, когда сам угол А больше 180 градусов. Он рассматривается в книге [1] как один из отдельных частных методов. А с этим пропадает вся его элегантность, прозрачность и производительность. А так же в последствии оказалось, что метод №2 можно очень существенно оптимизировать.


Рисунок 10

Оптимизация алгоритма проверки условия Делоне через уравнение описанной окружности


Далее чистая математика.

Итак имеем:
Проверка условия для точки M(X, Y) уравнением окружности, проходящей через точки A(x1, y1), B(x2, y2 ), C(x3, y3 ), можно записать в виде:

(a ⋅ (X^2 + Y^ 2) − b ⋅ X + c ⋅ Y − d) ⋅ sign a ≥ 0

Подробности можно взять в великолепной книге [1]. (Нет, не я ее автор)
Итак, sign a — это знак направления обхода, с самого начала я строил треугольники по часовой стрелке, так что его можно опустить ( он равен единице).

Далее перенеся центр координат в точку М, получим (Рисунок 11):

A(x1 — X, y1 — Y), B(x2 — X, y2 — Y), B(x3 — X, y3 — Y);

-d >= 0

Рисунок 11

Просто не правда ли?

d <= 0

Согласно книге, опять же, [1]

(x1^2 + y1^2)*(y2*x3 - x2*y3) + (x2^2 + y2^2)*(x1*y3 - y1*x3) + (x3^2 + y3^2)*(y1*x2 - x1*y2) <= 0


Имеем: 15 операций умножения/деления и 14 операций сложения/вычитания.

Спасибо за внимание. Жду критики.

Список используемой литературы

1. Скворцов А.В. Триангуляция Делоне и её применение. – Томск: Изд-во Том. ун-та, 2002. – 128 с. ISBN 5-7511-1501-5
Теги:
Хабы:
+8
Комментарии61

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн