Предикат "левый поворот" — различия между версиями
Строка 1: | Строка 1: | ||
Допустим нам дана задача: Даны два отрезка AB и CD (они могут вырождаться в точки). Требуется проверить, пересекаются они на плоскости или нет. Для упрощения определения этого факта в вычислительной геометрии используется предикат "левый поворот" (или "по часовой стрелке"). | Допустим нам дана задача: Даны два отрезка AB и CD (они могут вырождаться в точки). Требуется проверить, пересекаются они на плоскости или нет. Для упрощения определения этого факта в вычислительной геометрии используется предикат "левый поворот" (или "по часовой стрелке"). | ||
− | Итак, у нас есть задача, с чего начнем её решать? Какие вообще могут быть расположения точек и самих отрезков относительно друг друга? | + | |
+ | Итак, у нас есть задача, с чего начнем её решать? | ||
+ | |||
+ | Какие вообще могут быть расположения точек и самих отрезков относительно друг друга? | ||
[[Файл:Cross.png]] | [[Файл:Cross.png]] | ||
Строка 9: | Строка 12: | ||
{{Определение | {{Определение | ||
|definition = | |definition = | ||
− | + | <tex dpi = "120"> | |
+ | $$ | ||
+ | Left\_Turn(a, b, c) =\left\{ | ||
+ | \begin{array}{rl} | ||
+ | 1 &\mbox{, если}\ (b - a)\times(c - a)<0\\ | ||
+ | 0 &\mbox{, если}\ (b - a)\times(c - a)=0\\ | ||
+ | 2 &\mbox{, если}\ (b - a)\times(c - a)>0 | ||
+ | \end{array} | ||
+ | \right. | ||
+ | $$ | ||
+ | </tex> | ||
}} | }} | ||
Распишем поподробнее: | Распишем поподробнее: |
Версия 20:34, 19 октября 2011
Допустим нам дана задача: Даны два отрезка AB и CD (они могут вырождаться в точки). Требуется проверить, пересекаются они на плоскости или нет. Для упрощения определения этого факта в вычислительной геометрии используется предикат "левый поворот" (или "по часовой стрелке").
Итак, у нас есть задача, с чего начнем её решать?
Какие вообще могут быть расположения точек и самих отрезков относительно друг друга?
Одно из решений - определить, лежат ли точки концов отрезков по разные стороны от другого отрезка. Вот тут нам и поможет наш предикат, где два из трех аргументов (например a и b) это точки концов одного отрезка, а последний - один из концов другого отрезка.
Определение: |
Распишем поподробнее:
Какие при этом у нас будут погрешности? Нам нужно точно определить знак нашего выражения. Будем использовать для его вычисления "интервальную арифметику". Все исходные переменные, входящие в него, будут вырожденными интервалами. Из-за погрешностей, возникающих при округлении вещественных чисел, истинные значения операций нам неизвестны, но они обязательно будет содержаться в посчитанных интервалах. Допустим, что все числа положительные и будем писать без модулей:
NB: при сложении складываются абс. погрешности,при умножении складываются отн. погрешности.
Заметим, что все координаты (а значит и наши вычисления) производятся в вещественных числах, а это значит, что при вычислениях мы можем допустить ошибку. Какую? Посмотрим внимательнее на наш предикат. Ошибка раскрывается тогда, когда угол между отрезками АВ и АС крайне мал.
Ещё следует обратить внимание на граничные случаи, когда какие-то точки попадают на саму прямую. При этом возникает единственный особый случай, когда вышеописанные проверки ничего не дадут — случай, когда оба отрезка лежат на одной прямой. Этот случай надо рассмотреть отдельно. Для этого достаточно проверить, что проекции этих двух отрезков на оси X и Y пересекаются (часто эту проверку называют "проверкой на bounding box").