В двухмерном случае 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. И проще, и безопасней.
Смотри ещё: • Пересечение двух отрезков
Смотри ещё: • Проверка точки внутри многоугольника