Joonas' Note
[Graphics/Math] Euler to Quaternion, Quaternion to Euler 본문
Euler angle to Quaternion then Quaternion to euler angle
I'm using lib glm (http://glm.g-truc.net/) for test quaternion but I've a problem; when I convert euler angle to quaternion then immediatly quaternion to euler angles, my result are totally different
stackoverflow.com
http://marc-b-reynolds.github.io/math/2017/04/18/TaitEuler.html
Converting to Euler & Tait-Bryan
A note on reducing errors when converting to Euler angles or Tait-Bryan paramerters.
marc-b-reynolds.github.io
http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm
Maths - Conversion Quaternion to Euler - Martin Baker
Equations heading = atan2(2*qy*qw-2*qx*qz , 1 - 2*qy2 - 2*qz2) attitude = asin(2*qx*qy + 2*qz*qw) bank = atan2(2*qx*qw-2*qy*qz , 1 - 2*qx2 - 2*qz2) except when qx*qy + qz*qw = 0.5 (north pole) which gives: heading = 2 * atan2(x,w) bank = 0 and when qx*qy +
www.euclideanspace.com
Javascript로 옮기면 이렇다.
function threeAxisRotote(r11, r12, r21, r31, r32){
return [
Math.atan2(r11, r12),
Math.asin(r21),
Math.atan2(r31, r32),
];
}
function quaternionToEuler(q, order) {
switch(order){
case "ZYX":
return threeAxisRotote(
2*(q.x*q.y + q.w*q.z),
q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z,
-2*(q.x*q.z - q.w*q.y),
2*(q.y*q.z + q.w*q.x),
q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
);
case "ZXY":
return threeAxisRotote(
-2*(q.x*q.y - q.w*q.z),
q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z,
2*(q.y*q.z + q.w*q.x),
-2*(q.x*q.z - q.w*q.y),
q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
);
case "YXZ":
return threeAxisRotote(
2*(q.x*q.z + q.w*q.y),
q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z,
-2*(q.y*q.z - q.w*q.x),
2*(q.x*q.y + q.w*q.z),
q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z
);
case "YZX":
return threeAxisRotote(
-2*(q.x*q.z - q.w*q.y),
q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z,
2*(q.x*q.y + q.w*q.z),
-2*(q.y*q.z - q.w*q.x),
q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z
);
case "XYZ":
return threeAxisRotote(
-2*(q.y*q.z - q.w*q.x),
q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z,
2*(q.x*q.z + q.w*q.y),
-2*(q.x*q.y - q.w*q.z),
q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z
);
case "XZY":
return threeAxisRotote(
2*(q.y*q.z + q.w*q.x),
q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z,
-2*(q.x*q.y - q.w*q.z),
2*(q.x*q.z + q.w*q.y),
q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z
);
}
}
Euler --(XYZ)--> Quaternion --(ZYX)--> Euler 로 변환해야 같은 euler 값을 꺼낼 수 있다.
그리고 위 레퍼런스 코드가 xyz가 아니라 zyx 순으로 읽고 사용하는 것 같다.
'알고리즘' 카테고리의 다른 글
노래 가사의 반복도를 계산할 수 있을까? (1) | 2024.01.30 |
---|---|
[코딩으로 풀어보기] 문제적 남자 4화 - (9, 9, 9, 9, 9, 9)으로 100 만들기 (0) | 2022.05.20 |
[코딩으로 풀어보기] 자동차 번호판의 숫자가 겹칠 확률 (0) | 2021.11.12 |
트리의 노드 순서 정리해서 구간으로 만들기 (0) | 2020.05.13 |
Binary search 쉬운 구현 + 설명 (0) | 2020.04.06 |