Принадлежность точки выпуклому и невыпуклому многоугольникам — различия между версиями
Gromak (обсуждение | вклад) |
Yulya3102 (обсуждение | вклад) (→Выпуклый многоугольник) |
||
Строка 1: | Строка 1: | ||
{{ready}} | {{ready}} | ||
== Выпуклый многоугольник == | == Выпуклый многоугольник == | ||
− | + | Выпуклый многоугольник задан как замкнутая полилиния, поэтому для любой вершины этого многоугольника все остальные точки будут отсортированы по углу. Возьмём первую точку многоугольника и мысленно проведём от неё все лучи, содержащие диагонали. Бинпоиском за логарифм можно пройтись по углам и понять, в каком из них лежит точка. Когда найден угол, за константное время можно проверить, с какой стороны от противолежащего первой точке ребра многоугольника лежит точка. | |
+ | |||
+ | Итоговый алгоритм: | ||
+ | |||
+ | * если искомая точка <tex>q</tex> лежит левее самой левой грани или правее самой правой, сразу возвращаем false | ||
+ | * бинпоиском ищем такое ребро <tex>a_i a_{i+1}</tex>, не инцидентное самой первой точке <tex>a_0</tex> заданного многоугольника, что повороты точек <tex>a_0, a_i, q</tex> и <tex>a_0, a_{i+1}, q</tex> различаются | ||
+ | * проверяем поворот точек <tex>a_i, a_{i+1}, q</tex>, если он левый — точка лежит внутри, если правый — снаружи | ||
+ | |||
+ | Итоговое время работы: <tex>O(\log n)</tex>. | ||
== Невыпуклый многоугольник == | == Невыпуклый многоугольник == |
Версия 14:29, 22 февраля 2014
Конспект готов к прочтению. |
Выпуклый многоугольник
Выпуклый многоугольник задан как замкнутая полилиния, поэтому для любой вершины этого многоугольника все остальные точки будут отсортированы по углу. Возьмём первую точку многоугольника и мысленно проведём от неё все лучи, содержащие диагонали. Бинпоиском за логарифм можно пройтись по углам и понять, в каком из них лежит точка. Когда найден угол, за константное время можно проверить, с какой стороны от противолежащего первой точке ребра многоугольника лежит точка.
Итоговый алгоритм:
- если искомая точка лежит левее самой левой грани или правее самой правой, сразу возвращаем false
- бинпоиском ищем такое ребро , не инцидентное самой первой точке заданного многоугольника, что повороты точек и различаются
- проверяем поворот точек , если он левый — точка лежит внутри, если правый — снаружи
Итоговое время работы:
.Невыпуклый многоугольник
Если точка лежит на ребре, сразу вернём true.
Очевидно, что, если пустить из точки луч, то по чётности числа пересечений с рёбрами многоугольника можно определить, внутри точка лежит или снаружи.
Пустим луч, например, по иксу и за посмотрим, до ребра или после него начался луч.
переберём все рёбра и проверим их на пересечение с лучом. Как проверять: сначала проверим, что ордината точки лежит между ординатами концов ребра, затемЛуч может попасть в точку, при этом прохождение через точку учтётся два раза (по разу для каждого отрезка, к которым принадлежит точка). Иногда это и есть то, чего нам хочется (когда фигура находится выше или ниже луча), но иногда нам хочется учесть только один раз. Для этого делаем такую штуку: для каждого отрезка учитываем только верхнюю точку. Дальше всё очевидно.