빼미의 개발일기

[DirectX] - 01. 변환(Transform) (3) 본문

프로그래밍/게임그래픽

[DirectX] - 01. 변환(Transform) (3)

빼미01 2023. 12. 26. 11:41

2) 특별한 행렬 변환 및 연산

 

2.1) 오일러 변환(Euler Transformation)

 

- 오일러 변환은 기본 뷰 방향을 반드시 설정하여야 하며 대부분의 경우 음의 z축을 정면, y축을 윗면으로 잡는다 (오른손 좌표계 기준). 오일러 변환은 회전 행렬 3개의 곱이며 수식은 다음과 같다.

 

$$E(h,p,r) = R_{z}(r)R_{x}(p)R_{y}(h)$$

 

- E는 회전의 연속으로 직교하기 때문에 역행렬 $E^{-1} = E^{T} = (R_{z} R_{x} R_{y})^{T} = R_{z}^{T} R_{x}^{T} R_{y}^{T} $ 로 표현 할 수 있다.

 

 

- h, p, r은 각 축의 헤드(Head 혹은 Yaw), 피치(Pitch), 롤(Roll)의 회전을 표현 한 것이다.

 

- 오일러 각을 이용할 때 주의할 점은 두 종류의 각을 조합해서 처리하기 어렵다는 점(각각 한 축씩 제어해야 한다)이고, 일정 각에선 두 축이 일치되며, 더 이상 한 축을 제어할 수 없는 상황짐벌락(Gimbal Lock) 현상이 발생할 수도 있다.

 


2.2) 오일러 변환 매개변수 추출

 

$$E(h,p,r) = \begin{bmatrix} e_{00} & e_{01} & e_{02} \\ e_{10} & e_{11} & e_{12} \\ e_{20} & e_{21} & e_{22} \\ \end{bmatrix}  = R_{z}(r)R_{x}(p)R_{y}(h)$$

 

- 회전 행렬에 대해서 3 X 3 행렬로도 충분하기 때문에 위와 같이 표현한다.

- 그리고 위 3 x 3 행렬을 회전행렬 3개와 연결하면 다음과 같다.

 

$$ E = R_{z}(r)R_{x}(p)R_{y}(h)  = \begin{bmatrix} cosr & -sinr & 0 \\ sinr & cosr& 0 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & cosp& -sinp \\ 0 & sinp & cosp \\ \end{bmatrix} \begin{bmatrix} cosh & 0 & sinh \\ 0 & 1 & 0 \\ -sinh & 0 & cosh \\ \end{bmatrix} $$

 

$$ E = \begin{bmatrix} cosr cosh - sinrsinpsinh & -sinrcosp & cosrsinh + sinrsinpcosh \\ sinrcosh + cosrsinpsinh & cosrcosp & sinrsinh-cosrsinpcosh \\ -cospsinh & sinp & cospcosh \\ \end{bmatrix} $$

 

- 여기서 $sinp = e_{21}$ 이라는 걸 구할 수 있고, $e_{01}$을 $e_{11}$로 나누고 $e_{20}$을 $e_{22}$로 나누면 헤드와 롤의 매개변수에 대한 추출 수식을 구할 수 있다.

 

$$\frac{e_{01}}{e_{11}} = \frac{-sinr}{cosr} = -tanr \quad and \quad \frac{e_{20}}{e_{22}} = \frac{-sinh}{cosh} = -tanh$$

 

- 따라서 오일러 매개변수 h,p,r에 대해 행렬 E에서 함수 atan2(y,x)를 사용하면 다음과 같이 구해낼 수 있다.

 

$$ h = atan2(-e_{20},e_{22}),$$

$$ p = arcsin(e_{21}), $$

$$ r = atan2(-e_{01}, e_{11}) $$

 


- 오일러 변환은 위와 같은 회전 행렬의 곱으로 인해 세개의 축은 서로 종속적인 관계를 가지며, 회전을 세 번에 나눠 순차적으로 계산하게 된다.

- 이 때 두 개 이상의 고리가 겹쳐지면서 한 축의 자유도를 상실하게 되는 현상을 짐벌락(Gimbal Lock) 이라고 한다.

- 예를 들어 $cosp = 0$ 이면 $ \pm\pi/2 + 2\pi k$ 이며 k는 정수이다. 이 때 행렬은 하나의 각도인 r + h나 r - h에만 의존하기 때문에 자유도 1을 잃게 된다.

 

$$ if\quad cosp = 0  : \begin{bmatrix} cosr cosh - sinrsinh & 0 & cosrsinh + sinrcosh \\ sinrcosh + cosrsinh & 0 & sinrsinh-cosrcosh \\ 0 & 1 & 0 \\ \end{bmatrix} $$

 

짐벌락 시각화


2.3) 행렬 분해(Matrix Decomposition)

 

연결된 행렬에서 다양한 변환을 검색하는 작업을 행렬 분해라고 하며 다음과 같은 사용 예를 갖는다.

  • 오브젝트에 대한 크기 조절 비율만 추출할 경우
  • 특정 시스템이 필요로 하는 변환을 찾을 경우
  • 모델에 강체 변환만 적용됐는지 알아야 하는 경우
  • 오브젝트의 행렬만 사용 가능할 때 애니메이션에서 키프레임 사이를 보간할 경우
  • 회전 행렬에서 전단 변환을 제거할 경우

- 이전에서 이동과 회전 행렬을 강체 변환에 대해 유도하고, 직교 행렬에서 오일러 각을 유도하는 등의 식이 행렬 분해이다.

 


2.4) 임의의 축에 대한 회전

 

- 임의의 축 r에 대해 a 라디안 만큼 회전하려고 하고 축 r이 정규화 되어 있다고 가정한다.

- 결론적으론 축 r을 x축이 되는 공간으로 변환하고 x축에 대한 a 라디안 회전을 진행한뒤 다시 원래의 축 r로 변환하는 과정을 진행한다. 이 때 축 r을 x축으로 변환하는 행렬을 M이라고 한다면 식은 다음과 같다.

 

$$X = M^{T}R_{x}(\alpha)M$$

 

- M을 계산하려면 r과 서로 직교하는 두 개의 축을 찾아야 하는데, 안정적으로 처리하는 방법은 가장 작은 r의 요소를 찾은 뒤 이를 0으로 설정하는 것이다. 

 

$$ \overline{s} = \left\{\begin{matrix} (0, -r_{z}, r_{y} ), & if \quad |r_{x}| \leq |r_{y}| \quad and \quad |r_{x}| \leq |r_{z}|\\
( -r_{z} , 0, r_{y} )  & if \quad |r_{y}| \leq |r_{x}| \quad and \quad |r_{y}| \leq |r_{z}|\\ (0, -r_{z}, r_{y} )  & if \quad |r_{z}| \leq |r_{x}| \quad and \quad |r_{z}| \leq |r_{y}|\\ \end{matrix}\right.$$

 

$$s = \overline{s}/||\overline{s}||$$

 

$$t = r \times s$$

 

- s가 r에 대해 직교하는 것이 보장되기 때문에 (r, s, t)는 직교 기저(orthogonal basis)이다.

- 이를 통해 r를 가진 직교 기저를 x, y, z 축으로의 회전 행렬 M을 구할 수 있다.

 

$$ M = \begin{pmatrix} r^{T} \\ s^{T} \\ t^{T} \end{pmatrix}$$

 

- 회전 행렬 M을 이용해 위에서의 변환 X를 실행 할 수 있다.

 

- 또는 Goldman이 제시한 임의의 정규 축 r에 대해 \phi 라디안 회전을 하는 다른 식도 있다.

 

$$ R = \begin{pmatrix} cos\phi + (1-cos\phi)r^{2}_{x} &(1-cos\phi)r_{x}r_{y}-r_{z}sin\phi  & (1-cos\phi)r_{x}r_{z}+r_{y}sin\phi \\  (1-cos\phi)r_{x}r_{y}+r_{z}sin\phi & cos\phi + (1-cos\phi)r^{2}_{y} & (1-cos\phi)r_{y}r_{z}-r_{x}sin\phi \\ (1-cos\phi)r_{x}r_{z}-r_{y}sin\phi & (1-cos\phi)r_{y}r_{z}+r_{x}sin\phi & cos\phi + (1-cos\phi)r^{2}_{z} \\ \end{pmatrix}$$

Comments