Предикат "левый поворот" — различия между версиями
Rybak (обсуждение | вклад) м |
|||
Строка 13: | Строка 13: | ||
\operatorname{LeftTurn}(a, b, c) =\left\{ | \operatorname{LeftTurn}(a, b, c) =\left\{ | ||
\begin{array}{rl} | \begin{array}{rl} | ||
− | -1 &\mbox{, | + | -1 &\mbox{, if}\ (b - a)\times(c - a) < 0\\ |
− | 0 &\mbox{, | + | 0 &\mbox{, if}\ (b - a)\times(c - a) = 0\\ |
− | 1 &\mbox{, | + | 1 &\mbox{, if}\ (b - a)\times(c - a) > 0 |
\end{array} | \end{array} | ||
\right. | \right. |
Версия 19:46, 26 марта 2012
Даны два отрезка, которые задаются начальной и конечной точками
и определяются как множества точек . Требуется проверить существование множества их общих точек. Для определения этого факта в вычислительной геометрии используется предикат левый поворот (или по часовой стрелке). Рассмотрим возможные расположения точек и самих отрезков относительно друг друга:Определим, лежат ли точки концов отрезков по разные стороны от другого отрезка.
Определение: |
Распишем подробнее:
Какие при этом у нас будут погрешности? Допустим, что все числа положительные и будем писать без модулей:
Замечание: при сложении складываются абсолютные погрешности, при умножении складываются относительные погрешности.
Заметим, что все координаты (а, значит, и наши вычисления) производятся в вещественных числах, а это значит, что при вычислениях мы можем допустить ошибку. Более точно, определить знак нашего выражения поможет вычисление с интервальной арифметикой. Все исходные переменные будут вырожденными интервалами. Из-за погрешностей, возникающих при округлении вещественных чисел, истинные значения операций нам будут неизвестны, но они обязательно будет содержаться в посчитанных интервалах. Для точного вычисления необходимо фильтрованное вычисление предикатов.
;
Именно поэтому, когда угол между отрезками АВ и АС крайне мал, мы можем получить неверное значение предиката.
Bounding box
Ещё следует обратить внимание на граничные случаи, когда какие-то точки попадают на саму прямую. При этом возникает единственный особый случай, когда вышеописанные проверки ничего не дадут — случай, когда оба отрезка лежат на одной прямой. Этот случай надо рассмотреть отдельно. Для этого достаточно проверить, что проекции этих двух отрезков на оси X и Y пересекаются (часто эту проверку называют проверкой на bounding box).
План решения
Итак, теперь зная, какие подводные камни нам могут встретиться, накидаем план вычисления предиката:
рас-рас, тут еще пишу