Вы можете удалить часть рыскания кватерниона, рассчитав часть рыскания, а затем применив ее инверсию.Давайте предположим, что ваши кватернионы равны quat(w,x,y,z) == w + xi + yj + zk)
, а рыскание определено вокруг оси Z (эйлер 123 или 213 из этой статьи ).
Обратите внимание, что в этих кадрах вращение на yaw
вокруг оси Z представлен кватернионом quat(cos(yaw/2), 0, 0, sin(yaw/2))
.
Разлагая кватернионы на эйлеровы углы, мы имеем отклонение от курса:
yaw = atan2(-2*x*y + 2*w*z, +w*w +x*x -y*y -z*z); // 123 angles (page 24)
yaw = atan2(-2*x*y + 2*w*z, +w*w -x*x +y*y -z*z); // 213 angles (page 28)
Из которого мы можем вывести, что
quat quat_2yaw = quat(w*w +x*x -y*y -z*z, 0, 0, -2*x*y + 2*w*z).normalize(); // 123 angles
quat quat_2yaw = quat(w*w -x*x +y*y -z*z, 0, 0, -2*x*y + 2*w*z).normalize(); // 213 angles
Простой способ уменьшить угол кватерниона вдвое - добавить его к единичному кватерниону и нормализовать:
quat quat_yaw = (1 + quat_2yaw).normalize();
Чтобы ответить на исходный вопрос - мы хотим взятьрыскать от q1
и заменить ею q2
.Мы можем сделать это следующим образом:
q2 = get_quat_yaw(q1) * get_quat_yaw(q2).conj() * q2;