Пушыстый (_winnie) wrote,
Пушыстый
_winnie

Угол между двумя векторами:

Угол между векторами: atan2( length(cross(a, b)), dot(a,b) ). atan2 - из стандартной мат-библиотеки языка. cross - векторное произведение, dot - скалярное.
В двухмерном случае length(cross(a,b)) заменяется на axby - bxay, и угол считается проще, atan2(axby - bxay, axbx + ayby). Угол даже со знаком получается (против/по часовой стрелке).

А то часто заморачиваются с аркосинусами, получают сложный некрасивый код и падают при попытке взять аркосинус(1.0001235) после ошибок округления.

Очень часто угол вообще излишен, достаточно только косинуса угла ( dot(a, b) ), а угол считают зря. Напр. выражение для сравнения угла с константой:
angle(a, b) < 45°
можно записать как
cos(angle(a, b)) > cos(45°)
dot(a, b)/(length(a)*length(b)) > cos(45°)
dot(a, b)2 > 0.5*length2(a)*length2(b).
0.5 здесь взялся как cos2(45°). И ещё надо не забыть условие dot(a, b) > 0. length2 - это sqrt(x2+y2+z2)2, то есть (x2+y2+z2), без извлечения корня.

В результат код без делений, без квадратных корней, без тригонометрических функций, что может ускорить его в десятки раз. Если вектора единичные (заранее отнормировали), то вообще замечательно. Можно не ломать голову, как корректно возвести длину в квадрат.

PS. Если в коде +10% понятности значимей, чем ускорение в 20 раз, лучше писать по-человечески, как мыслишь. Только всё равно в функции angle замените аркосинусы на atan2. И проще, и безопасней.

Смотри ещё: • Пересечение двух отрезков
Смотри ещё: • Проверка точки внутри многоугольника
Tags: geom-prog, math, release, soft-dev
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 9 comments