2D-корпус
Точно так же, как dot
product пропорционален косинусу угла, детерминант является пропорциональным его
синусоиде. Таким образом, вы можете вычислить угол следующим
образом:
dot = x1*x2 + y1*y2 # dot product between [x1, y1] and [x2, y2]
det = x1*y2 - y1*x2 # determinant
angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)
Ориентация этого угла совпадает с ориентацией системы координат.
В левая система координат , то есть x ,
указывающая вправо и y вниз, как это принято в
компьютерной графике, это означает, что вы получите положительный
знак для углов по часовой стрелке. Если ориентация системы
координат математическая с y вверх, вы получаете углы
против часовой стрелки, как это принято в математике. Изменение
порядка входов изменит знак, поэтому, если вы недовольны знаками,
просто замените их.
3D-корпус
В 3D два произвольно размещенных вектора определяют собственную
ось вращения, перпендикулярную обоим. Эта ось вращения не имеет
фиксированной ориентации, что означает, что вы не можете однозначно
фиксировать направление угла поворота. Одно общее соглашение
состоит в том, чтобы углы всегда были положительными и
ориентировали ось таким образом, чтобы она находилась под
положительным углом. В этом случае точечного произведения
нормированных векторов достаточно для вычисления углов.
dot = x1*x2 + y1*y2 + z1*z2 #between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1*x1 + y1*y1 + z1*z1
lenSq2 = x2*x2 + y2*y2 + z2*z2
angle = acos(dot/sqrt(lenSq1 * lenSq2))
Плоскость, встроенная в 3D
Одним из особых случаев является случай, когда ваши векторы не
расположены произвольно, а лежат в плоскости с известным нормальным
вектором n . Тогда ось вращения будет в направлении
n , а ориентация n зафиксирует ориентацию для
этой оси. В этом случае вы можете адаптировать 2D-вычисление выше,
включая n в определитель сделать свой размер 3 × 3.
dot = x1*x2 + y1*y2 + z1*z2
det = x1*y2*zn + x2*yn*z1 + xn*y1*z2 - z1*y2*xn - z2*yn*x1 - zn*y1*x2
angle = atan2(det, dot)
Одним из условий для этого является то, что нормальный вектор
n имеет единичную длину. Если нет, вам придется
нормализовать его.
Как тройной продукт
Этот определитель можно также выразить как трехместный продукт , поскольку @Excrubulent
указал в предлагаемом редактировании.
det = n · (v1 × v2)
Это может быть проще реализовать в некоторых API-интерфейсах и
дает другую перспективу в том, что здесь происходит: поперечное
произведение пропорционально синусу угла и будет располагаться
перпендикулярно плоскости, следовательно, кратно n . Таким
образом, точечный продукт будет в основном измерять длину этого
вектора, но с прикрепленным к нему правильным знаком.