2D корпус
Так само, як точковий добуток пропорційний косинусу кута, визначник пропорційний його синусу. Тож ви можете обчислити кут так:
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)
Орієнтація цього кута збігається з орієнтацією системи координат. У лівій системі координат , тобто х, спрямованому вправо та у вниз, як це звичайно для комп'ютерної графіки, це означатиме, що ви отримаєте позитивний знак для кутів за годинниковою стрілкою. Якщо орієнтація системи координат математична з 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 . Точковий добуток, таким чином, в основному вимірюватиме довжину цього вектора, але з прикріпленим до нього правильним знаком.
std::atan2()
?