[면접 대비] 짐벌락, 쿼터니언

MINO·2025년 6월 18일

짐벌락

오일러각 체계에서는 회전을 한 번에 계산하지 않고, 세 번에 나누어서 순서대로 계산한다.

어떤 축의 회전은 다른 축의 회전에 영향을 줄 수 있고,
특정한 경우, 앞의 두 회전에 의해 세번째 회전의 자유도가 상실되어
한 축의 회전을 사용할 수 없게 되는 현상이 발생한다.

이를 짐벌락 이라고 부른다.

(회전을 세 번 나누어 실행하는 도중 축 두 개가 겹쳐 하나의 축으로 잠금되는 현상)

오일러 각도에 따른 자유도 손실

위키피디아 - 짐벌락
위키피디아 - 삼각법 공식

결과 행렬에서 3열이 [ 0 -1 0 ] 으로 고정됨을 확인할 수 있다.
즉, Z축 회전 각도 phi 가 3번째 열에 영향을 미치지 못하고 사라진 것이다.
이를 짐벌락 이라고 한다.

아래는 같은 수식이지만, 마크다운 문법으로 작성해보았다.


R=Ry(ψ)Rx(θ)Rz(ϕ)R=R_{y}(\psi )\cdot R_{x}(\theta)\cdot R_{z}(\phi)

Ry(ψ)=[cosψ0sinψ010sinψ0cosψ], Rx(π/2)=[100001010], Rz(ϕ)=[cosϕsinϕ0sinϕcosϕ0001]R_y(\psi) = \begin{bmatrix} \cos \psi & 0 & \sin \psi \\ 0 & 1 & 0 \\ -\sin \psi & 0 & \cos \psi \end{bmatrix} , \ R_{x}(\pi/2) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & -1 \\ 0 & 1 & 0 \end{bmatrix} , \ R_{z}(\phi) = \begin{bmatrix} \cos \phi & -\sin \phi & 0 \\ \sin \phi & \cos \phi & 0 \\ 0 & 0 & 1 \end{bmatrix}

Let x=π/2 ,Let \ x = \pi / 2\ ,

A=Rx(π2)Rz(ϕ)=[100001010][cosϕsinϕ0sinϕcosϕ0001]=[coscsinc0001sinccosc0]A = R_x\left(\frac{\pi}{2}\right) \cdot R_z(\phi) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & -1 \\ 0 & 1 & 0 \end{bmatrix} \cdot \begin{bmatrix} \cos \phi & -\sin \phi & 0 \\ \sin \phi & \cos \phi & 0 \\ 0 & 0 & 1 \end{bmatrix}= \begin{bmatrix} \cos c & -\sin c & 0 \\ 0 & 0 & -1 \\ \sin c & \cos c & 0 \end{bmatrix}

R=Ry(ψ)A=[cosψ0sinψ010sinψ0cosψ]AR = R_y(\psi) \cdot A = \begin{bmatrix} \cos \psi & 0 & \sin \psi \\ 0 & 1 & 0 \\ -\sin \psi & 0 & \cos \psi \end{bmatrix} \cdot A

=[cosbcosc+sinbsinccosbsinc+sinbcosc0001sinbcosc+cosbsincsinbsinc+cosbcosc0]= \begin{bmatrix} \cos b \cos c + \sin b \sin c & -\cos b \sin c + \sin b \cos c & 0 \\ 0 & 0 & -1 \\ -\sin b \cos c + \cos b \sin c & \sin b \sin c + \cos b \cos c & 0 \end{bmatrix}

쿼터니언

오일러각과 다르게 한 번에 회전하는 방식으로 짐벌락 현상이 일어나지 않는다.


코드와 예제

// 오일러각을 표현하는 Vector3 값에서 새로운 Quaternion 값을 생성
Quaternion.Euler(Vector3);

// (0,60,0) 회전을 표현하는 쿼터니언 회전 데이터 생성
Quaternion rot = Quaternion.Euler(new Vector3(0,60,0)); 

// Quaternion 을 오일러각으로 가져오기
Vector3 eulerRotation = rot.eulerAngles;

// 현재 회전에서 한 번 더 회전하기 - 쿼터니언 사이의 연산은 행렬을 사용하므로 + 이 아닌 * 사용
Quaternion a = Quaternion.Euler(30,0,0);
Quaternion b = Quaternion.Euler(0,60,0);
Quaternion c = a * b;
profile
안녕하세요 게임 개발하는 MINO 입니다.

0개의 댓글