Як показали Натан Рід і теодрон, рецепт обертання вектора v кватерніоном q одиниці довжини :
1) Створіть чистий кватерніон p з v . Це просто означає додавання четвертої координати 0:
p=(vx,vy,vz,0)⇔p=(v,0)
2) Попередньо помножте його на q і помножте на кон'югат q * :
p′=q×p×q∗
3) У результаті вийде ще один чистий кватерніон, який можна повернути до вектора:
v′=(p′x,p′y,p′z)
Цей вектор v′ є v повернута на q .
Це працює, але далеко не оптимально . Множення кватерніона означає тонни і тонни операцій. Мені було цікаво різних реалізацій, таких як ця , і вирішив знайти, звідки вони прийшли. Ось мої висновки.
Ми також можемо описати q як поєднання тривимірного вектора u та скалярного s :
q=(ux,uy,uz,s)⇔q=(u,s)
За правилами множення кватерніона , і оскільки сполучник одиниці довжини кватерніона просто обернений, ми отримуємо:
p′=qpq∗=(u,s)(v,0)(−u,s)=(sv+u×v,−u⋅v)(−u,s)=((−u⋅v)(−u)+s(sv+u× v)+(sv+u×v)×(−u),…)=((u⋅v)u+s2v+s(u×v)+sv×(−u)+(u×v)×(−u),…)
Скалярна частина (еліпси) призводить до нуля, як детально описано тут . Що цікаво, це векторна частина, AKA наш обертовий вектор v ' . Його можна спростити за допомогою деяких основних векторних ідентичностей :
v′=(u⋅v)u+s2v+s(u×v)+s(u×v)+u×(u×v)=(u⋅v)u+s2v+2s(u×v)+(u⋅v)u−(u⋅u)v=2(u⋅v)u+(s2−u⋅u)v+2s(u×v)
Зараз це набагато оптимальніше ; дві крапкові вироби, поперечний продукт і кілька додаткових: близько половини операцій. Що б дало щось подібне у вихідному коді (якщо припустити, загальна бібліотека векторної математики):
void rotate_vector_by_quaternion(const Vector3& v, const Quaternion& q, Vector3& vprime)
{
// Extract the vector part of the quaternion
Vector3 u(q.x, q.y, q.z);
// Extract the scalar part of the quaternion
float s = q.w;
// Do the math
vprime = 2.0f * dot(u, v) * u
+ (s*s - dot(u, u)) * v
+ 2.0f * s * cross(u, v);
}