3차원 공간에서 물체의 회전을 표현하는 방법에는 여러 가지가 있다.
그중 가장 널리 쓰이는 쿼터니언(Quaternion)과 회전행렬(Rotation Matrix)을 알아보자.
쿼터니안은 사원수라고도 한다.
1. 사원수
허수 단위 $i$처럼 제곱해서 -1이 되는 수를 두 가지 더 만든 수 체계이다.
구체적으로는 아래와 같다.
$i^2 = j^2 = k^2 = ijk = -1$
추가로 교환법칙이 성립하지 않는다.

$a+bi$의 기존 허수처럼 실수부 하나를 더해 $a+bi+cj+dk$처럼 수를 표현할 수 있어 사원수라고 부른다.
각 허수 단위를 떼고 ($a,b,c,d$)처럼 쓰기도 한다.
또는 뒤의 세 항을 하나의 벡터처럼 표시할 수도 있다.
2. 3D 회전에서의 쿼터니언 사용
3차원 공간에서 물체의 회전을 얘기할 때, 회전의 기준이 될 회전축과 그 축을 기준으로 얼마나 회전시킬지를 나타내는 회전량이 필요하다.
회전축이 될 길이가 1인 벡터($|\vec{u}| = 1$) $\vec{u} = (u_x, u_y, u_z)$, 회전각을 $\theta$라고 할 때, 쿼터니언 $q$는 다음과 같이 정의된다.
$$q = (q_r, q_i, q_j, q_k) = (\cos \frac{\theta}{2}, u_x \sin \frac{\theta}{2}, u_y \sin \frac{\theta}{2}, u_z \sin \frac{\theta}{2})$$
만약 $(1, 1, 1)$ 축을 기준으로 $60^\circ$ 회전하는 경우의 예시를 보자.
$\vec{v} = (1, 1, 1)$의 크기는 $\sqrt{3}$이므로, 단위 벡터 $\vec{u} = (\frac{1}{\sqrt{3}}, \frac{1}{\sqrt{3}}, \frac{1}{\sqrt{3}})$가 된다.
각도 계산: $\theta = 60^\circ$이므로 $\theta/2 = 30^\circ$이다.
성분 대입:
$q_r = \cos(30^\circ) = \frac{\sqrt{3}}{2} \approx 0.866$
$(q_i, q_j, q_k) = \sin(30^\circ) \cdot \vec{u} = \frac{1}{2} \cdot (\frac{1}{\sqrt{3}}, \frac{1}{\sqrt{3}}, \frac{1}{\sqrt{3}}) \approx (0.289, 0.289, 0.289)$
최종 쿼터니언: $q \approx (0.866, 0.289, 0.289, 0.289)$
3. 크기가 1이어야 하는 이유
유효한 회전을 나타내는 쿼터니언은 반드시 단위 쿼터니언(Unit Quaternion), 즉 $\|q\| = 1$을 만족해야 한다.
따라서 위와 같이 정의를 한 것이다.
$$\|q\|^2 = q_r^2 + q_i^2 + q_j^2 + q_k^2 = \cos^2 \frac{\theta}{2} + \sin^2 \frac{\theta}{2}(u_x^2 + u_y^2 + u_z^2) = 1$$
크기가 1이 아니라면 어떤 문제가 생길까?
회전 변환 시 물체의 크기가 변하게 된다.
회전은 크기를 보존해야 하므로 크기가 1인 벡터를 사용해야한다.
4. 회전행렬(Rotation Matrix)
회전행렬 $R$은 $3 \times 3$ 크기의 직교 행렬(Orthogonal Matrix)이다.
특정 벡터 $\vec{v}$에 행렬 $R$을 곱함으로써($\vec{v'} = R\vec{v}$) 새로운 좌표로 회전시킨다.
행렬의 각 열은 회전 후의 새로운 기저 벡터(좌표축)를 의미한다.
5. 쿼터니언에서 회전행렬로 변환
단위 쿼터니언 $q = (q_r, q_i, q_j, q_k)$를 회전행렬 $R$로 변환하는 식은 다음과 같다.
$$R = \begin{pmatrix} 1-2(q_j^2+q_k^2) & 2(q_iq_j-q_rq_k) & 2(q_iq_k+q_rq_j) \\ 2(q_iq_j+q_rq_k) & 1-2(q_i^2+q_k^2) & 2(q_jq_k-q_rq_i) \\ 2(q_iq_k-q_rq_j) & 2(q_jq_k+q_rq_i) & 1-2(q_i^2+q_j^2) \end{pmatrix}$$
아래는 간단한 유도 과정이다.
먼저 임의의 벡터 $\vec{p}$를 쿼터니언 $q$로 회전시키는 연산은 $p' = q p q^{-1}$로 정의된다.
$q$의 길이가 1일 경우, $q^{-1}$은 허수부들의 부호를 바꾼 켤레와 같다.
즉 $q=(s_1, \vec{v}_1)$일 때, $q^{-1}=(s_1, -\vec{v}_1)$이다.
이때 $q$는 4차원인 반면 $p$는 3차원이므로 실수부가 0인 순수 쿼터니언 $(0, p_x, p_y, p_z)$으로 잠시 취급해 계산한다.
이 때 곱셈은 일반적인 연산이 아닌 사원수의 연산법칙을 사용한다.
$(s_1, \vec{v}_1)(s_2, \vec{v}_2) = (s_1s_2 - \vec{v}_1 \cdot \vec{v}_2, s_1\vec{v}_2 + s_2\vec{v}_1 + \vec{v}_1 \times \vec{v}_2)$
따라서 위 정보들을 이용해 $p'$을 구하면 아래와 같다.
먼저 $qp$이다.
$$qp = (q_r, \vec{v})(0, \vec{p}) = (-\vec{v} \cdot \vec{p}, \quad q_r \vec{p} + \vec{v} \times \vec{p})$$
여기에 마저 $q^{-1}$을 곱하자.
$$p' = (-\vec{v} \cdot \vec{p}, \quad q_r \vec{p} + \vec{v} \times \vec{p})(q_r, -\vec{v})$$
곱하면 실수부는 $0$이 되고 허수부는 아래와 같다.
$$\vec{p'} = q_r(q_r \vec{p} + \vec{v} \times \vec{p}) + (\vec{v} \cdot \vec{p})\vec{v} + (q_r \vec{p} + \vec{v} \times \vec{p}) \times \vec{v}$$
이 식의 후반부에 나오는 세 벡터의 외적을 계산하는 부분에 아래 항등식을 이용해 계산을 간단히 하고
$$\vec{a} \times (\vec{b} \times \vec{c}) = \vec{b}(\vec{a} \cdot \vec{c}) - \vec{c}(\vec{a} \cdot \vec{b})$$
길이가 1인 쿼터니언의 성질, $q_r^2 + |\vec{v}|^2 = 1$식과,
외적의 성질을 이용해 식을 더 간결히 정리하면
$$\vec{p'} = \vec{p} + 2\vec{v} \times (\vec{v} \times \vec{p} + q_r \vec{p})$$
최종적으로 위 식을 얻는다.
위 벡터 연산 식을 기저 벡터 $e_1(1,0,0), e_2(0,1,0), e_3(0,0,1)$에 대해 각각 적용하여 행렬의 각 열 성분을 추출하면 위 $3 \times 3$ 행렬식이 유도된다.
$e_1$에 대해서만 계산을 해보자.
$q_r=0$이므로 식은 $p+2v \times (v\times p)$로 더 간단해진다.
이제 $p=(1,0,0), \vec{v}=(q_i,q_j,q_k)$를 사용해 계산하면,
$\vec{v} \times e_1 = (0, q_k, -q_j)$
$\vec{v} \times (\vec{v} \times e_1) = (-q_j^2 - q_k^2, q_i q_j, q_i q_k)$
식에 대입하여 $x, y, z$ 성분 계산하면,
$x: 1 + 2(-q_j^2 - q_k^2) = 1 - 2(q_j^2 + q_k^2)$
$y: 0 + 2(q_r q_k + q_i q_j)$
$z: 0 + 2(q_i q_k - q_r q_j)$
이렇게 $R$의 첫번째 열벡터를 얻을 수 있다.
'기타' 카테고리의 다른 글
| 컴퓨터는 모든 것을 해결할 수 있을까? (halting problem) (2) | 2025.10.19 |
|---|---|
| [xv6] xv6 운영체제에 getppid() 시스템 콜 구현하기 (2) (0) | 2025.04.18 |
| [xv6] xv6 운영체제에 getppid() 시스템 콜 구현하기 (1) (2) | 2025.03.30 |