일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 그래프
- 프로세스
- dfs
- 코딩테스트
- DirectX
- 혼자공부하는
- 스레드
- DDR SDRAM
- static
- 인터럽트
- 프로그래머스
- 렌더링 파이프라인
- CPU 스케줄링
- 운영체제
- C++
- 입출력장치
- 독학
- 131701
- 지역변수
- 풀이
- 138477
- 혼자 공부하는
- 보조기억장치
- 멀티스레드
- 컴퓨터구조
- BFS
- 장치컨트롤러
- 컴퓨터 구조
- Transform
- 한빛미디어
- Today
- Total
빼미의 개발일기
[DirectX] - 01. 변환(Transform) (3) 본문
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}$$
'프로그래밍 > 게임그래픽' 카테고리의 다른 글
[DirectX] - 01. 변환(Transform) (2) (1) | 2023.12.21 |
---|---|
[DirectX] - 01. 변환 (Transform) (1) (2) | 2023.12.19 |
[DirectX] - 00. 렌더링 파이프라인 개요 (3) (1) | 2023.12.18 |
[DirectX] - 00. 렌더링 파이프라인 개요 (2) (1) | 2023.11.28 |
[DirectX] - 00. 렌더링 파이프라인 개요 (1) (2) | 2023.11.25 |