Решение, которое я сейчас использую, похоже, здесь отсутствует.
Предполагая, что нормаль плоскости нормализована (|Vn| == 1
), угол со знаком просто:
atan2((Vb x Va) . Vn, Va . Vb)
, который возвращает угол в диапазоне [-PI, + PI] (или независимо от того, что возвращает доступная реализация atan2).
.
и x
являются точечным и перекрестным произведением соответственно.
Нет необходимости в явном ветвлении и вычислении длины деления / вектора.
Используйте Va x Vb
для правого вращения вместо левого
Объяснение того, почему это работает: пусть альфа будет прямым углом между векторами (от 0 ° до 180 °), а бета - искомым углом (от 0 ° до 360 °) с помощью beta == alpha
или beta == 360° - alpha
Va . Vb == |Va| * |Vb| * cos(alpha) (by definition)
== |Va| * |Vb| * cos(beta) (cos(alpha) == cos(-alpha) == cos(360° - alpha)
Va x Vb == |Va| * |Vb| * sin(alpha) * n1
(by definition; n1 is a unit vector perpendicular to Va and Vb with
orientation matching the right-hand rule)
Therefore (again assuming Vn is normalized):
n1 . Vn == 1 when beta < 180
n1 . Vn == -1 when beta > 180
==> (Va x Vb) . Vn == |Va| * |Vb| * sin(beta)
Наконец
tan(beta) = sin(beta) / cos(beta) == ((Va x Vb) . Vn) / (Va . Vb)