Изменения

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

Упрощение полигональной цепи

142 байта убрано, 15:24, 16 июня 2012
Задача
Упрощение полигональной цепи {{---}} процесс, позволяющий уменьшить число точек полилинии.
==Задача==
Дана некоторая полилиния, заданная последовательностью точек <tex> a_1, a_2, ..., a_n</tex>, и некоторое <tex>\varepsilon</tex>. Требуется найти цепь <tex> a_1, a_i, a_j, ..., a_n </tex>, являющейся подпоследовательностью исходной, для которой . Для этой цепи верно, что для всех <tex>k</tex>, таких что <tex> i < k < j:</tex> <tex>\rho(a_k, Segment(a_i, a_j)) \le \varepsilon</tex> для любых соседних <tex>i</tex> и <tex>j</tex>.
Существует также альтернативная задача, в которой вместо <tex>\varepsilon</tex> задано число <tex>k</tex> вершин в итоговой цепи, . В этом случае требуется составить цепь <tex> a_1, a_i, a_j, ..., a_n </tex> заданной длины таким образом, что максимально необходимое <tex>\varepsilon</tex> для условия <tex> \rho(a_k, Segment(a_i, a_j)) \le \varepsilon</tex> было минимально.
Также упрощение можно выполнять с помощью введения новой полилинии, не сохраняющей точки исходной, но такая вариация задачи рассмотрена не будет.
Алгоритм рекурсивно делит полилинию. Входом алгоритма служат координаты всех точек между первой и последней включая их, а так же <tex>\varepsilon</tex>. Первая и последняя точка сохраняются неизменными. После чего алгоритм находит точку, наиболее удалённую от отрезка, состоящего из первой и последней (оптимальный способ поиска расстояния от точки до отрезка рассмотрен ниже). Если точка находится на расстоянии, меньше, чем <tex>\varepsilon</tex>, то все точки, которые ещё не были отмечены к сохранению, могут быть выброшены из набора, и получившаяся прямая сглаживает кривую с точностью не ниже <tex>\varepsilon</tex>.
Если же расстояние больше <tex>\varepsilon</tex>, то алгоритм рекурсивно вызывает себя на наборе от начальной до данной и от данной до конечной точек (это означает, что данная точка будет отмечена к сохранению).
По окончанию всех рекурсивных вызовов итоговая полилиния строится только из тех точек, что были отмечены к сохранению.
| <tex>9</tex> || Алгоритм завершен
|}
Полилиния, полученная в результате работы алгоритма, отражается черной пунктирной линией.    
===Время работы===
Ожидаемая сложность алгоритма может быть оценена выражением <tex>\Theta(n\log n)</tex> в лучшем случае, когда номер наиболее удаленной точки всегда оказывается лексикографически центральным. Однако, в худшем случае сложность алгоритма составляет <tex>O(n^2)</tex>. Это достигается, апримернапример, в случае, если номер наиболее удаленной точки всегда соседний к номеру граничной точки.
===Замечания к алгоритму===
К сожалению, алгоритм Дугласа-Пекера в ходе своей работы не сохраняет топологию. Это означает, что в ответе мы можем получить линию с самопересечениями.
В статье де Берга (de Berg) ''[http://www.bowdoin.edu/~ltoma/teaching/cs350/spring06/Lecture-Handouts/deberg95new.pdf "A New Approach to Subdivision Simplification"]''(1995) приведен алгоритм, позволяющий решать чуть более общую задачу, чем текущая: упрощение полигональной цепи с учетом обязательных особых точек, не входящих в нее и с учетом топологии. Можно использовать алгоритм и для текущего случая, задав множество особых точек пустым. Время работы алгоритма при этом составит <tex>O(n^2\log n)</tex>. Краткое описание алгоритма дано ниже.
====Оптимальность====
===Решение альтернативной задачи===
Альтернативную задачу Решение альтернативной задачи очень схоже с заданным числом <tex>k</tex> оптимально решать такисходном алгоритмом. На каждой итерации алгоритм находит подучасток исходной цепи, что в итоговой цепи останутся лишь на котором расстояние до наиболее значимые удаленной точки. Алгоритм начинается максимально, делит ее так же, как и алгоритм в исходном алгоритме и запоминает полученные в результате деления подучастки для решения обычной задачи. Теперь каждый раз выбирается та часть, у которой наиболее удаленная вершина находится на большем расстоянии относительно таких же вершин других частейследующих итераций. Алгоритм завершитсястартует, когда будет итоговая для выбора доступна только исходная цепь будет состоять из требуемого числа точек.
====Реализация====
Практически очевидно, что данный вариант алгоритма легко реализовать на приоритетной очереди. Будем хранить расстояние, на котором находится наиболее удаленная вершина, как ключ, а номера вершин-границ как значение. На каждой итерации мы выбираем обьект с наибольшим ключем, делим и получившиеся части кладем обратно в очередь с новыми ключами.
===Реализация===
[[Файл:DistancePtoSDistancePtoS1.png‎|400px|right]]Даны точка <tex>(x_0, y_0)O</tex> и отрезок, заданный точками <tex>(x_1, y_1)A</tex> и <tex>(x_2, y_2)B</tex>.
Введём обозначения:
*<tex>R_1</tex> {{---}} отрезок <tex>[(x_0, y_0)O; (x_1, y_1)A]</tex>*<tex>R_2</tex> {{---}} отрезок <tex>[(x_0, y_0)O; (x_2, y_2)B]</tex>*<tex>R_{12}</tex> {{---}} отрезок <tex>[(x_1, y_1)A; (x_2, y_2)B]</tex>
Если:
*<tex>|R_1| \ge \sqrt{|R_2|^2+|R_{12}|^2}</tex>, то ответ это <tex>|R_2|</tex>, так как угол между <tex>R_2</tex> и <tex>R_{12}</tex> при данном условии <tex> \ge 90^{\circ}</tex>
*<tex>|R_2| \ge \sqrt{|R_1|^2+|R_{12}|^2}</tex>, то ответ это <tex>|R_1|</tex>, так как угол между <tex>R_1</tex> и <tex>R_{12}</tex> при данном условии <tex> \ge 90^{\circ}</tex>
*Оба предыдущих условия ложны, то <tex>\operatorname{abs} (\frac{| \overrightarrow{R_{12}} \times \overrightarrow{R_1}|}{|\overrightarrow{R_{12}}|})</tex>, где <tex> \overrightarrow{R_{12}} = (x_2 B -x_1, y_2 - y_1)A</tex> и <tex> \overrightarrow{R_1} = (x_1 - x_0, y_1 A - y_0)O</tex>. Это следует из формул для площади параллелограмма через векторное произведение и через произведения основания на высоту
<br clear="all"/>
==Обзор ускорения работы алгоритма Дугласа-Пекера==
Как описано выше, в худшем случае алгоритм работает за <tex>O(n^2)</tex>. Можно внести дополнения, которые позволят получить <tex>O(n\log n)</tex> в худшем случае. Ускорение основывается на уменьшении времени поиска наиболее удаленной вершины. Это можно осуществить благодаря идее о том, что наиболее удаленная вершина лежит на выпуклой оболочке полигональной цепи. Описание ускорения взято из статьи Хершберга(Hershberger) ''[http://www.bowdoin.edu/~ltoma/teaching/cs350/spring06/Lecture-Handouts/hershberger92speeding.pdf "Speeding Up the Douglas-Peucker Line-Simplification Algorithm"]'' (1992).
Для построения выпуклой оболочки используется [http://www.ams.sunysb.edu/~jsbm/courses/545/melkman.pdf алгоритм Мелкмана], который работает для двумерной полигональной цепи без самопересечений за <tex>O(n)</tex>, строя все промежуточные выпуклые оболочки, которые пригодятся в дальнейшем.
Алгоритм делится на четыре основных этапа:
*Создание графа <tex>G_1</tex>, в котором помимо исходных ребер, добавлены все возможные сокращенные ребра. Иначе говоря ребра, для который верно, что <tex>i < j</tex> и для любого <tex>t</tex>, такого что <tex>i < t < j</tex>, верно <tex>distance\rho(V_t, \overline{V_iV_j}) \le \varepsilon</tex>.
*Создание графа <tex>G_2</tex>, в котором добавлены все возможные ребра, не нарушающие топологию. На этом этапе построение выполняется без учета <tex>\varepsilon</tex>.
*Создание графа <tex> G = G_1 \cap G_2</tex>, в котором будет содержаться кратчайшая полигональная цепь без самопересечений по построению <tex>G_1</tex> и <tex>G_2</tex>.
*[http://pers.narod.ru/algorithms/pas_dist_from_point_to_line.html Поиск расстояния от точки до отрезка]
*[http://algolist.manual.ru/maths/geom/distance/pointline.php Поиск расстояния от точки до прямой]
*[http://www.bowdoin.edu/~ltoma/teaching/cs350/spring06/Lecture-Handouts/hershberger92speeding.pdf "Speeding Up the Douglas-Peucker Line-Simplification Algorithm"]
*[http://www.ams.sunysb.edu/~jsbm/courses/545/melkman.pdf Алгоритм Мелкмана]
*[http://softsurfer.com/Archive/algorithm_0203/algorithm_0203.htm Алгоритм Мелкмана]
*[http://softsurfer.com/Archive/algorithm_0112/algorithm_0112.htm Двоичный поиск на выпуклой оболочке]
*[http://www.bowdoin.edu/~ltoma/teaching/cs350/spring06/Lecture-Handouts/deberg95new.pdf "A New Approach to Subdivision Simplification"]
*[http://www.codeproject.com/Articles/114797/Polyline-Simplification#headingRD Алгоритмы и визуализатор упрощения полигональной цепи]
 
[[Категория: Вычислительная геометрия]]
Анонимный участник

Навигация