Участник:Liebeann/Принадлежность точки многоугольнику
Автор статьи: Липкина Анна
Свойства и структура алгоритмов
Общее описание алгоритма
На плоскости дан произвольный многоугольник с [math]\displaystyle{ N }[/math] вершинами и точка [math]\displaystyle{ X }[/math]. Требуется определить положение точки относительно многоугольника: находится ли точка внутри многоугольника, на его границе, совпадает с вершиной или находится вне многоугольника.
Математическое описание алгоритма
Дано: Многоугольник [math]\displaystyle{ P }[/math]с [math]\displaystyle{ N }[/math] вершинами и точка [math]\displaystyle{ X }[/math]. Каждая вершина многоугольника и точка [math]\displaystyle{ X }[/math] описываются парой координат [math]\displaystyle{ (x, y) }[/math].
Обозначения:
- [math]\displaystyle{ int(P) }[/math] — множество строго внутренних точек многоугольника [math]\displaystyle{ P }[/math]
- [math]\displaystyle{ V(P) = \{v_0, v_2, \dots, v_{N - 1} \} }[/math] — упорядоченноый набор точек, являющихся вершинами многоугольника [math]\displaystyle{ P }[/math]
- [math]\displaystyle{ D(P) }[/math] — множество граничных точек многоугольника [math]\displaystyle{ P }[/math], без учета вершин многоугольника.
- [math]\displaystyle{ out(P) }[/math] — множество строго внешних по отношению к [math]\displaystyle{ P }[/math] точек
- [math]\displaystyle{ \delta_{\varepsilon}(X) }[/math] — [math]\displaystyle{ \varepsilon }[/math]-окрестность точки [math]\displaystyle{ X }[/math], или это следующее множество точек: [math]\displaystyle{ \{x \in \mathbb{R}^2 | \rho(x, X) \leqslant \varepsilon \} }[/math], где [math]\displaystyle{ \rho(A, B) = \sqrt{(A_x - B_x)^2 + (A_y - B_y) ^ 2} }[/math] — Евклидово расстояние между точками [math]\displaystyle{ A }[/math] и [math]\displaystyle{ B }[/math], а [math]\displaystyle{ A = (A_x, A_y) }[/math] — точка, задающаяся своими координатами по осям.
Выход: вывести:
- 1, если [math]\displaystyle{ X \in int(P) }[/math]
- 2, если [math]\displaystyle{ X \in V(P) }[/math]
- 0, если [math]\displaystyle{ X \in D(P) }[/math]
- -1, если [math]\displaystyle{ X \in out(P) }[/math]
Алгоритм: Сначала проверим, принадлежит ли [math]\displaystyle{ X }[/math] множеству [math]\displaystyle{ V(P) }[/math]. Для этого достаточно перебрать все вершины [math]\displaystyle{ V(P) }[/math] и для каждой проверить, лежит ли [math]\displaystyle{ X }[/math] в маленькой [math]\displaystyle{ \varepsilon }[/math]-окрестности текущей вершины многоугольника. Более формально:
для всех v принадлежащих V(P):
если X принадлежит епсилон-окрестности v:
вернуть 2
Если точка не совпадает ни с одной вершиной, то проверим, принадлежит ли [math]\displaystyle{ X }[/math] множеству [math]\displaystyle{ D(P) }[/math]. Для этого переберем все ребра многоугольника [math]\displaystyle{ (v_i, v_{i + 1}) }[/math] и посчитаем следующие величины:
Пусть [math]\displaystyle{ v_i^l = v_i - X, v_i^r = v_{(i + 1) \% N} - X }[/math]
[math]\displaystyle{ s_i = \langle v_i^l, v_i^r \rangle }[/math] — скалярное произведение векторов [math]\displaystyle{ v_i^l, v_i^r }[/math]
[math]\displaystyle{ t_i = v_i^l \times v_i^r }[/math] — модуль вектора, полученного векторным произведением векторов [math]\displaystyle{ v_i^l, v_i^r }[/math]
Теоретически, точка лежит на ребре (строго, не совпадает ни с одной из вершин ребер), если [math]\displaystyle{ s_i \lt 0 }[/math] и [math]\displaystyle{ d_i = 0 }[/math].
Практически, равенство нулю нужно превратить в [math]\displaystyle{ |d_i| \leqslant \varepsilon }[/math].
Если все условия выполнены, то возвращаем 0.
Если [math]\displaystyle{ X \notin V(P) }[/math] и [math]\displaystyle{ X \not in D(P) }[/math]:
Посчитаем следующую сумму ориентированных углов:
[math]\displaystyle{ S = \sum_{i=0}^{N - 1} angle (v_i - X, v_{(i + 1) \% N} - X) }[/math]
где [math]\displaystyle{ angle(a, b) }[/math] — ориентированный угол между векторами [math]\displaystyle{ a }[/math] и [math]\displaystyle{ b }[/math].
Есть следующие три варианта:
- [math]\displaystyle{ |S| \lt \varepsilon \Rightarrow X \in out(P) }[/math]
- [math]\displaystyle{ |S| \in \delta_{\varepsilon}(\pi) \Rightarrow X \in D(P) }[/math]
- [math]\displaystyle{ |S| \in \delta_{\varepsilon}(2 \pi) \Rightarrow X \in int(P) }[/math]
Замечание: здесь вводятся [math]\displaystyle{ \varepsilon }[/math] - окрестности из-за того, что работа происходит с вещественными числами.
Вычислительное ядро алгоритма
Макроструктура алгоритма
Схема реализации последовательного алгоритма
Последовательная сложность алгоритма
Информационный граф
Ресурс параллелизма алгоритма
Входные и выходные данные алгоритма
Свойства алгоритма
Программная реализация алгоритма
Особенности реализации последовательного алгоритма
Локальность данных и вычислений
Возможные способы и особенности параллельной реализации алгоритма
Масштабируемость алгоритма и его реализации
Динамические характеристики и эффективность реализации алгоритма
Выводы для классов архитектур
Существующие реализации алгоритма
Литература
http://ru-wiki.org/wiki/Задача_о_принадлежности_точки_многоугольнику https://habrahabr.ru/post/301102/ http://neerc.ifmo.ru/wiki/index.php?title=Принадлежность_точки_выпуклому_и_невыпуклому_многоугольникам http://www.e-maxx-ru.1gb.ru/algo/pt_in_polygon