Изменения

Перейти к: навигация, поиск

Straight skeleton

2844 байта добавлено, 17:48, 3 декабря 2014
Алгоритм с изпользованием SLAV
Далее считаем, что полигон представлен рёбрами вдоль движения по контуру полигона против часовой стрелки.
# '''Шаг 1.''' Инициализация: ::<tex>(a)</tex> Поместим все вершины многоугольника <tex> V_1, V_2 \dots V_n </tex> в двусвязный циклический список в порядке обхода вдоль контура. Все вершины в <tex> \mathrm{LAV}</tex> считаются активными сейчас.::<tex>(b)</tex> Для каждой вершины <tex> V_i </tex> в <tex> \mathrm{LAV}</tex> добавим указатели на инцидентные рёбра <tex> e_{i-1} = V_{i-1}V_i</tex> и <tex> e_i = V_i V_{i+1}</tex>, а также найдём луч биссектрисы <tex> b_i </tex>.::<tex>(c)</tex> Для каждой вершины <tex> V_i </tex> найдём ближайшее пересечение биссектрисы <tex> b_i </tex> лучами <tex> b_{i-1} </tex> и <tex> b_{i+1} </tex>. Если это пересечение существует, то положим его в [[Двоичная куча | приоритетную очередь]] согласно <tex> L(e_i) </tex> {{---}} расстоянию от точки пересечения до одного из рёбер, инцидентных вершине <tex> V_i </tex>. Для каждой точки пересечения <tex> I_i </tex> будем так же хранить два указателя на вершины <tex> V_a </tex> и <tex> V_b </tex> {{---}} начала лучей биссектрис, которые пересекаются в точке <tex> I_i </tex>. Эти указатели понадобятся в будущем, когда нужно будет определять соответствующие вершинам рёбра <tex> e_a, e_b </tex> (см. рисунок ниже).'''Шаг 2.''' Следующие действия выполняются в цикле, пока приоритетная очередь не пустая::<tex>(a)</tex> Извлечём точку пересечения <tex> I </tex> из приоритетной очереди.:<tex>(b)</tex> Если вершины <tex> V_a </tex> и <tex> V_b </tex>, соответствующие данной точке пересечения помечены как обработанные, то переходим к следующей итерации цикла шага 2. Это означает, что ребро между данными вершинами полностью стянулось (обработанные вершины и стянутые рёбра помечены крестом на рисунке ниже).:<tex>(c)</tex> Если осталось всего три вершины <tex> V_a, V_b, V_c </tex>, то добавим в <tex> \mathrm{straight}\ \mathrm{skeleton} </tex> рёбра <tex> IV_a, IV_b, IV_c </tex>. В случае выпуклого многоугольника в этом месте можно завершить алгоритм. Но в общем случае нужно будет перейти к началу цикла снова.:<tex>(d)</tex> Добавим в <tex> \mathrm{straight}\ \mathrm{skeleton} </tex> рёбра <tex> IV_a, IV_b </tex>.:<tex>(e)</tex> Теперь необходимо модифицировать <tex> \mathrm{LAV}</tex> (детали на рисунке ниже):::* пометим вершины <tex> V_a </tex> и <tex> V_b </tex> как обработанные (напомню, что они обозначаются крестом на рисунке к данному алгоритму),::* создадим новую вершину <tex> V </tex> в точке пересечения <tex> I </tex> (отмечена квадратиком на рисунке),::* добавим вершину <tex> V </tex> в <tex> \mathrm{LAV}</tex>, то есть между предыдущем к <tex> V_a </tex> и следующим к <tex> V_b </tex> узлами,::* добавим вершине <tex> V </tex> указатели на соответствующие рёбра <tex> e_a </tex> и <tex> e_b </tex>.:<tex>(f)</tex> Посчитаем дополнительные величины для вершины <tex> V </tex>:::* луч биссектрисы <tex> b </tex> между рёбрами <tex> e_a </tex> и <tex> e_b </tex>,::* точки пересечения луча b с соседями <tex> V </tex> в <tex> \mathrm{LAV}</tex>, как в шаге <tex> 1c </tex>::* сохраним ближайшие точки пересечения в приоритетной очереди.
=== Невыпуклый полигон ===

Навигация