Search
Duplicate

AI/ Quaternion Rotation

Quaternion

Quaternion은 1개의 실수와 3개의 허수로 구성되는 수 체계이며 주로 3d 점의 회전을 처리하기 위해 사용된다. 이것은 Euler Angle 사용시 겪을 수 있는 gimbal lock 문제를 해결할 수 있다. gimbal lock 문제는 회전 축 중 하나가 다른 하나와 평행하게 되면서 결과적으로 회전의 자유도가 줄어드는 현상을 말한다. 예컨대 yy축으로 90도 회전하면 xxzz축이 같은 평면 상에 놓이게 되어 두 축이 겹친다.
쿼터니언은 다음과 같은 형식으로 표현된다.
q=a+bi+cj+dk\bold{q} = a + b\bold{i} + c\bold{j} + d\bold{k}
여기서 a,b,c,da, b, c, d는 실수이고, i,j,k\bold{i},\bold{j},\bold{k}는 허수인 기저 벡터이다.
이것은 같은 벡터 형식으로도 표현될 수 있다.
q=[abcd]\bold{q} = \begin{bmatrix} a \\ b \\ c \\ d \end{bmatrix}
쿼터니언의 i,j,k\bold{i},\bold{j},\bold{k}는 다음의 성질을 갖는다.
i2=j2=k2=ijk=1ij=ji=kjk=kj=iki=ik=j\begin{aligned} \bold{i}^2 &= \bold{j}^2 = \bold{k}^2 = \bold{ijk} = -1 \\ \bold{ij} &= -\bold{ji} = \bold{k} \\ \bold{jk} &= -\bold{kj} = \bold{i} \\ \bold{ki} &= -\bold{ik} = \bold{j} \end{aligned}
이를 다음과 같은 표 형식으로 나타낼 수 있다.
↓ × →
1\bold{1}
i\bold{i}
j\bold{j}
k\bold{k}
1\bold{1}
1\bold{1}
i\bold{i}
j\bold{j}
k\bold{k}
i\bold{i}
i\bold{i}
1-\bold{1}
k\bold{k}
j-\bold{j}
j\bold{j}
j\bold{j}
k-\bold{k}
1-\bold{1}
i\bold{i}
k\bold{k}
k\bold{k}
j\bold{j}
i-\bold{i}
1-\bold{1}

Rotation

p\bold{p}을 각도 θ\theta로 회전하는 것을 쿼터니언을 이용하여 계산하려면 회전축 벡터 u\bold{u}와 회전 쿼터니언 q\bold{q}가 필요하다.
우선 회전축 벡터 u\bold{u}를 다음과 같이 정의한다.
u=(ux,uy,uz)=uxi+uyj+uzk\bold{u} = (u_x, u_y, u_z) = u_x\bold{i} + u_y\bold{j} + u_z\bold{k}
여기서 i,j,k\bold{i}, \bold{j}, \bold{k}의 계수 ux,uy,uzu_x, u_y, u_z는 회전하려는 각 축에 대한 기여도를 나타낸다. 예컨대 xx축으로만 회전한다면 u=(1,0,0)\bold{u} = (1, 0, 0)가 된다.
만일 2개 이상의 축으로 회전하려면 각각의 기여도를 정규화하여 계산하면 된다. 예컨대 xx축과 yy축으로 동일한 비율로 회전하려 한다면 (1,1,0)(1, 1, 0)가 되고 이를 정규화하면 u=(112+12,112+12,0)=(12,12,0)\bold{u} = ({1 \over \sqrt{1^2 + 1^2}}, {1 \over \sqrt{1^2 + 1^2}}, 0) = ({1 \over \sqrt{2}}, {1 \over \sqrt{2}}, 0)가 된다. 한편 xx축으로 0.50.5만큼, zz축으로 11만큼 회전하려 한다면 (0.5,0,1)(0.5, 0, 1)가 되고 이것을 정규화하면 u=(0.50.52+12,0,10.52+12)=(0.51.25,0,11.25)\bold{u} = ({0.5 \over \sqrt{0.5^2 + 1^2}}, 0, {1 \over \sqrt{0.5^2 + 1^2}}) = ({0.5 \over \sqrt{1.25}}, 0, {1 \over \sqrt{1.25}})가 된다.
다음으로 회전축 벡터 u\bold{u}를 이용하여 회전 쿼터니언 q\bold{q}를 정의한다. 이것은 지수 함수의 테일러 전개와 Euler 공식의 확장을 사용한다.
q=eθ2(uxi+uyj+uzk)=cosθ2+(uxi+uyj+uzk)sinθ2=cosθ2+usinθ2\bold{q} = e^{{\theta \over 2}(u_x\bold{i} + u_y\bold{j} + u_z\bold{k})} = \cos{\theta \over 2} + (u_x\bold{i} + u_y\bold{j} + u_z\bold{k}) \sin{\theta \over 2} = \cos {\theta \over 2} + \bold{u} \sin {\theta \over 2}
참고로 q=(q0,q1,q2,q3)\bold{q} = (q_0, q_1, q_2, q_3)의 길이는 q=q02+q12+q22+q32\|\bold{q}\| = \sqrt{q_0^2 + q_1^2 + q_2^2 + q_3^2}로 정의되며 q=1\|\bold{q}\| = 1인 경우 unit quaternion이라 한다.
추가로 q=q0+q1i+q2j+q3k\bold{q} = q_0 + q_1\bold{i} + q_2\bold{j} + q_3\bold{k}의 켤레는 q=q0q1iq2jq3k\bold{q}^* = q_0 - q_1\bold{i} - q_2\bold{j} - q_3\bold{k}로 정의되며 q\bold{q}가 unit quaternion인 경우 qq=1\bold{qq}^* = 1이 된다.
쿼터니언으로 3d 회전을 표현하기 위해 다음의 절차를 따른다.
1.
회전할 축을 고려하여 회전축 벡터 u\bold{u}를 구한다.
2.
회전축 벡터 u\bold{u}와 회전각도 θ\theta에 대해 회전 quaternion q\bold{q}을 구한다.
3.
회전할 점 p=(px,py,pz)\bold{p} = (p_x, p_y, p_z)을 쿼터니언 형식 p=0+pxi+pyj+pzk\bold{p} = 0 + p_x\bold{i} + p_y\bold{j} + p_z\bold{k}으로 변환한다.
4.
회전 쿼터니언 q\bold{q}와 그것의 역수 q1\bold{q}^{-1}를 사용하여 다음과 같이 계산하여 점 p\bold{p}의 회전된 점 p\bold{p}'를 구한다.
p=qpq1\bold{p}' = \bold{qpq}^{-1}
여기서에서 q1=q/q2\bold{q}^{-1} = \bold{q}^* / \|\bold{q}\|^2이며 q\bold{q}^*q\bold{q}의 켤레이다. q\bold{q}가 정규화 되었다면 q2=1\|\bold{q} \|^2 = 1이므로 역수 대신 켤레를 이용해서 회전을 계산할 수도 있다.
p=qpq\bold{p}' = \bold{qpq}^*
예컨대 p=(1,0,0)\bold{p} = (1, 0, 0)zz축을 중심으로 90도 회전하는 경우 다음과 같이 계산된다.
1.
z축으로만 회전하므로 u=(0,0,1)\bold{u} = (0, 0, 1)로 계산한다.
2.
회전축 벡터 u\bold{u}와 각도 90도를 이용하여 회전 쿼터니언 q\bold{q}을 다음과 같이 구한다.
q=cos(902)+sin(902)(0i+0j+1k)=cos(45)+sin(45)k=12+12k\begin{aligned} \bold{q} &= \cos \left({90 \over 2} \right) + \sin\left({90 \over 2} \right)(0\bold{i} + 0\bold{j} + 1\bold{k}) \\ &= \cos(45) + \sin(45)\bold{k} \\ &= {1\over \sqrt{2}} + {1\over \sqrt{2}}\bold{k} \end{aligned}
이를 벡터 형식으로 작성하면 q=[120012]\bold{q}^\top = \begin{bmatrix} {1\over \sqrt{2}} & 0 & 0 & {1\over \sqrt{2}} \end{bmatrix}가 된다.
3.
회전할 점을 쿼터니언 형식으로 변환한다.
p=0+1i+0j+0k=1i\bold{p} = 0 + 1\bold{i} + 0\bold{j} + 0\bold{k} = 1\bold{i}
4.
회전 쿼터니언의 길이 q\|\bold{q}\|가 1이므로 q\bold{q}의 켤레 q\bold{q}^*를 이용하여 다음과 같이 p\bold{p}'를 구한다.
p=qpq=(12+12k)(1i)(1212k)=(12i+12j)(1212k) (ki=j)=12i+12j+12j12i (ik=j,jk=i)=j\begin{aligned} \bold{p}' = \bold{qpq}^* &= ({1\over \sqrt{2}} + {1\over \sqrt{2}}\bold{k})(1\bold{i})({1\over \sqrt{2}} - {1\over \sqrt{2}}\bold{k}) \\ &= ({1\over\sqrt{2}}\bold{i} + {1\over\sqrt{2}}\bold{j})({1\over \sqrt{2}} - {1\over \sqrt{2}}\bold{k}) \ (\because \bold{ki} = \bold{j}) \\ &= {1\over2} \bold{i} + {1\over2}\bold{j} + {1\over 2}\bold{j} -{1\over2}\bold{i} \ (\because \bold{ik} = -\bold{j}, \bold{jk} = \bold{i}) \\ &= \bold{j} \end{aligned}
고로 p=(0,1,0)\bold{p}' = (0, 1, 0)이 된다.
참고로 회전 쿼터니언 q\bold{q}이 스칼라 부분을 갖고 있지만, 회전 시키려는 점 p\bold{p}의 쿼터니언 표현에서 스칼라는 0이 되고 허수 부분만 남게 되므로 qp\bold{qp}의 결과에서 스칼라 부분은 항상 0이 되고 허수 부분만 존재하게 된다. 거기에 다시 스칼라를 가진 q1\bold{q}^{-1}을 곱하더라도 허수 부분이 곱해지므로 결국 허수 부분만 남게 되어 p=qpq1\bold{p}' = \bold{qpq}^{-1}의 결과는 항상 허수만 남게 된다. 따라서 p\bold{p}'의 결과에서 스칼라를 고려하지 않고 i,j,k\bold{i}, \bold{j}, \bold{k}의 계수만 취해서 다시 좌표 형식으로 변환할 수 있다.

Rotation Matrix

회전 쿼터니언 q=(q0,q1,q2,q3)\bold{q} = (q_0, q_1, q_2, q_3)을 다음과 같은 3×33 \times 3 회전 행렬 R\bold{R}로 변환할 수 있다.
R=[12(q22+q32)2(q1q2q0q3)2(q1q3+q0q2)2(q1q2+q0q3)12(q12+q32)2(q2q3q0q1)2(q1q3q0q2)2(q2q3+q0q1)12(q12+q22)]\bold{R} = \begin{bmatrix} 1 - 2(q_2^2 + q_3^2) & 2(q_1q_2 - q_0q_3) & 2(q_1q_3 + q_0q_2) \\ 2(q_1q_2 + q_0q_3) & 1 - 2(q_1^2 + q_3^2) & 2(q_2q_3 - q_0q_1) \\ 2(q_1q_3 - q_0q_2) & 2(q_2q_3 + q_0q_1) & 1 - 2(q_1^2 + q_2^2) \end{bmatrix}
예컨대 p=(1,0,0)\bold{p} = (1, 0, 0)zz축을 중심으로 90도 회전하는 위의 예시에서 구한 회전 쿼터니언 q=[120012]\bold{q}^\top = \begin{bmatrix} {1\over \sqrt{2}} & 0 & 0 & {1\over \sqrt{2}} \end{bmatrix}를 위 회전 행렬에 적용하면 다음과 같이 계산된다.
R=[12(02+(12)2)2(001212)2(012+120)2(00+1212)12(02+(12)2)2(012120)2(012120)2(012+120)12(02+02)]=[010100001]\begin{aligned} \bold{R} &= \begin{bmatrix} 1 - 2(0^2 + ({1\over\sqrt{2}})^2) & 2(0 \cdot0 - {1\over\sqrt{2}}\cdot {1\over\sqrt{2}}) & 2(0 \cdot{1\over\sqrt{2}} + {1\over\sqrt{2}} \cdot0) \\ 2(0\cdot 0 + {1\over\sqrt{2}} \cdot {1\over\sqrt{2}}) & 1 - 2(0^2 + ({1\over\sqrt{2}})^2) & 2(0\cdot {1\over\sqrt{2}} - {1\over\sqrt{2}} \cdot 0) \\ 2(0 \cdot {1\over\sqrt{2}} - {1\over\sqrt{2}} \cdot 0) & 2(0 \cdot {1\over\sqrt{2}} + {1\over\sqrt{2}} \cdot 0) & 1 - 2(0^2 + 0^2) \end{bmatrix} \\& = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1\end{bmatrix} \end{aligned}
회전하려는 하는 점이 p=(1,0,0)\bold{p} = (1, 0, 0)이므로 다음과 같이 계산된다.
p=Rp=[010100001][100]=[010]\bold{p}' = \bold{Rp} = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1\end{bmatrix} \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix}
고로 p=(0,1,0)\bold{p}' = (0, 1, 0)이 된다.

참고