GLM : 오일러 각도에서 쿼터니언으로


12

문제가 있기 때문에 GL 수학 ( GLM ) 을 알고 있기를 바랍니다 .

오일러 앵글 세트가 있으며 그 사이에 부드러운 보간 을 수행해야 합니다. 가장 좋은 방법은 쿼터니언으로 변환하고 SLERP 알고리즘을 적용하는 것입니다.

내가 가진 문제는 오일러 앵글로 glm :: quaternion 을 초기화 하는 방법입니다 .

GLM 문서를 계속해서 읽었 지만 Quaternion constructor signature세 개의 오일러 각도가 필요한 적절한 것을 찾을 수 없습니다 . 내가 찾은 가장 가까운 것은 각도 값과 해당 각도의 축을 취하는 angleAxis () 함수입니다. 참고로, 내가 찾고있는 방법, 구문 분석 방법을 참조하십시오 RotX, RotY, RotZ.


자세한 내용은 위의 metAioned angleAxis () 함수 서명입니다 .

detail::tquat< valType > angleAxis (valType const &angle, valType const &x, valType const &y, valType const &z)

답변:


13

GLM에 익숙하지는 않지만 오일러 각도에서 쿼터니언으로 직접 변환하는 함수가 없으면 "축 주위 회전"함수 (예 : "angleAxis")를 직접 사용할 수 있습니다.

방법은 다음과 같습니다 (의사 코드).

Quaternion QuatAroundX = Quaternion( Vector3(1.0,0.0,0.0), EulerAngle.x );
Quaternion QuatAroundY = Quaternion( Vector3(0.0,1.0,0.0), EulerAngle.y );
Quaternion QuatAroundZ = Quaternion( Vector3(0.0,0.0,1.0), EulerAngle.z );
Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ;

또는 오일러 각도 회전을 적용하려는 순서에 따라 쿼터니언 곱셈을 전환해야 할 수도 있습니다.

또는 GLM 문서를 살펴보면 다음과 같이 오일러 각도-> 행렬 3-> 쿼터니언을 변환 할 수있는 것으로 보입니다.

toQuat( orient3( EulerAngles ) )

신청 순서가 덜 모호하기 때문에 좋은 대답입니다.
Richard Fabian 2016 년

@Trevor : +1, 안녕 Trevor, 좋은 답변 주셔서 감사합니다. 이것은 가장 실용적인 해결책처럼 보입니다. 회전 곱셈 순서를 쉽게 전환 할 수 있습니다. 아마도 조합의 수가 GLM에서 오일러 각도 대 Quaterion 변환을 사용할 수없는 이유 일 수 있습니다.
Bunkai.Satori

모든 대답은 훌륭하고 가치가 있지만, 이것이 가장 실용적 이라고 생각 합니다. 승인 된 답변 으로 표시하고 싶습니다 .
Bunkai.Satori

@Trevor : Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ ;, 어떤 종류의 곱셈 을 의미 했습니까? GLM이 operator *Quaternion 곱셈에 과부하가 걸리지 않아서 곱셈을 수동으로 수행해야 할 것 입니다.
Bunkai.Stori

3
@ 분 카이 쿼터니언 곱셈의 개념은 행렬 곱셈과 유사하며, 점이나 곱이 아닙니다. 쿼터니언의 사용법을 이해하고 행렬에 익숙해지고 축 각도를 이해하려는 경우 기본 개념은 쿼터니언과 매우 유사하지만 수학은 조금 더 발전하지만 축 각도를 이해하면 쿼터니언은 그렇지 않습니다. 더 이상
Maik Semder 2016 년

16
glm::quat myquaternion = glm::quat(glm::vec3(angle.x, angle.y, angle.z));

여기서 angleA는 glm::vec3함유 피치, 요, 롤 을 각각.

추신. 의심 스러우면 헤더로 가서 살펴보십시오. 정의는 glm / gtc / quaternion.hpp에서 찾을 수 있습니다.

explicit tquat(tvec3<T> const & eulerAngles) {
        tvec3<T> c = glm::cos(eulerAngle * value_type(0.5));
    tvec3<T> s = glm::sin(eulerAngle * value_type(0.5));

    this->w = c.x * c.y * c.z + s.x * s.y * s.z;
    this->x = s.x * c.y * c.z - c.x * s.y * s.z;
    this->y = c.x * s.y * c.z + s.x * c.y * s.z;
    this->z = c.x * c.y * s.z - s.x * s.y * c.z;    
}

quat에 대한 float typedef는 어디에 있습니까 tquat?


꽤 모호합니다. 어떤 순서로 적용됩니까? 오일러는 회전 순서가 정해지고 여기에서 쿼터니언 생성자는 신경 쓰지 않는 것 같습니다.
Richard Fabian

함수 정의는 당신과 똑같습니다; 중요한 경우 답변에 게시했습니다.
감속 캐비어

인수의 순서가 아니라 회전 적용 순서입니다. 내 답변에는 Wikipedia 기사에서 가져온 XYZ 순서가 포함되어 있지만 이전 회사에서는 ZYX 응용 프로그램 순서를 사용하고 현재 회사에서는 YZX를 사용합니다. x 각도는 여전히 모든 경우에 벡터 / 인수 목록의 첫 번째 값이지만 실제 결과 변환은 동일하지 않습니다.
Richard Fabian 2016 년

rotationQuat에 대한 답변을 수정 했으므로 순서를 쉽게 변경하는 방법을 알 수 있습니다. 기본적으로 XYZ를 허용하지만 쉽게 변경할 수 있습니다.
감속 캐비어

2
-1 : 순환 순서를 언급하지 않은
Maik Semder

7

해결책은 Wikipedia에 있습니다 : http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

그것을 사용하여 :

sx = sin(x/2); sy = sin(y/2); sz = sin(z/2);
cx = cos(x/2); cy = cos(y/2); cz = cos(z/2);

q( cx*cy*cz + sx*sy*sz,
   sx*cy*cz - cx*sy*sz,
   cx*sy*cz + sx*cy*sz,
   cx*cy*sz - sx*sy*cz ) // for XYZ application order

q( cx*cy*cz - sx*sy*sz,
   sx*cy*cz + cx*sy*sz,
   cx*sy*cz - sx*cy*sz,
   cx*cy*sz + sx*sy*cz ) // for ZYX application order

오일러 (회전 적용이 XYZ 또는 ZYX 인 경우)가있는 쿼터니언의 생성자. 그러나 오일러 각의 가능한 6 가지 조합 중 2 개에 불과합니다. 변환 행렬로 변환 할 때 오일러 각도가 어떤 순서로 구성되어 있는지 알아야합니다. 그래야만 솔루션을 정의 할 수 있습니다.

내가 근무했던 예전 회사에서는 Z가 대부분의 그래픽 카드와 같은 순방향이므로 응용 프로그램 순서는 ZYX 였고 현재 회사에서는 Y 축이 전달되고 Z는 위쪽이므로 응용 프로그램 순서는 YZX입니다. 이 순서는 쿼터니언을 곱하여 최종 변환을 생성하는 순서이며 회전 순서는 곱셈이 정식이 아닙니다.


1
+1, 안녕하세요. 훌륭한 답변 감사합니다. OpenGL을 사용 하면 Z 값이 화면에서 사라집니다. 내 응용 프로그램에서 ZYX 곱셈 순서를 수행 합니다. 원래 GLM에이 기능을 사용할 수 있다고 생각했지만 아직 구현하지 않았으므로 한 가지 대안은 수동으로 변환을 만드는 것 입니다.
Bunkai.Satori

이것이 가장 좋은 대답입니다.
plasmacel

1
vec3 myEuler (fAngle[0],fAngle[1],fAngle[2]);
glm::quat myQuat (myEuler);

f 앵글은 라디안이어야합니다!


2
이거 장난 이었어? 아니면 다른 답변 (특히 Daniel의 답변)을 읽지 않았습니까?
Chris는 Reinstate Monica
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.