이제 SRT 변환을 행렬을 통해 알아보도록 할 것이다.
아래는 Scale, Rotation, Translation에 대한 변환 행렬이다.
Scale (크기 변환 - S)
물체의 크기를 각 축 방향으로 $a, b, c$배만큼 조절한다.
- 수식: $X = ax, \ Y = by, \ Z = cz$
- 행렬
$$M_S = \begin{pmatrix} a & 0 & 0 & 0 \\ 0 & b & 0 & 0 \\ 0 & 0 & c & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$
Rotation (회전 변환 - R)
특정 축을 기준으로 물체를 회전을 시킨다.
- X축 회전 수식:
- $X = x$
- $Y = y \cos\phi - z \sin\phi$
- $Z = y \sin\phi + z \cos\phi$
- 행렬 ($R_x$):
$$M_{Rx} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\phi & -\sin\phi & 0 \\ 0 & \sin\phi & \cos\phi & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$
- Y축 회전 수식:
- $X = x \cos\theta + z \sin\theta$
- $Y = y$
- $Z = -x \sin\theta + z \cos\theta$
- 행렬 ($R_y$):
$$M_{Ry} = \begin{pmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$
- Z축 회전 수식:
- $X = x \cos\beta - y \sin\beta$
- $Y = x \sin\beta + y \cos\beta$
- $Z = z$
- 행렬 ($R_z$)
$$M_R = \begin{pmatrix} \cos\beta & \sin\beta & 0 & 0 \\ -\sin\beta & \cos\beta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$
Translation (이동 변환 - T)
물체를 현재 위치에서 $a, b, c$만큼 평행 이동시킨다.
- 수식: $X = x + a, \ Y = y + b, \ Z = z + c$
- 행렬
$$M_T = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ a & b & c & 1 \end{pmatrix}$$
여기서 우리는 하나 주목해야 할 점이 있다. 보통 우리가 SRT를 표현할 때, $x,y,z$ 3가지 요소로 따져 3D 차원상에 표현하게 되는데, 해당 행렬은 $4 \times 4$행렬로 1차원더 많은 4차원 행렬을 이용하는 모습을 볼 수 있다.
왜 3차원 행렬이 아니라 4차원 행렬을 사용하는걸까? 이는 Translation과 밀접히 관련이 있다. 이는 $3 \times 3$행렬로 이동을 표현할 수 없기 때문이다. 이는 행렬 곱셈과, 선형 변환의 특성때문이다.
기본적으로 이동은 선형 변환으로 표현할 수 없다. 그 이유는 아래와 같은 제약사항 때문이다.
선형 변환이 되려면 덧셈 보존, 가산성(Additivity)와 스칼라 곱 보존, 동차성(Homogenelty)가 만족해야 한다.
※ 덧셈 보존: $T(u \times v) = T(u) \times T(v)$
※ 스칼라 곱 보존: $T(cv) = cT(v)$
이 두 조건을 기하학적으로 해석하면 "원점은 절대 움직이지 않고(고정한 채로), 균일하게 일정 크기만큼 변형된다"라는 의미이기도 하다.
그래서 Scale, Rotation은 선형 변환이지만, Translation은 비선형 변환이다. 정확히 Translation은 아핀 변환(Affine Transformation)이다.
그럼 먼저 Scale과 Rotation이 선형 변환인 이유를 수식과 함께 예를 들어 알아보자
먼저 Scale부터 알아보자 아래는 Scale에 대한 증명과 예시이다.
크기 변환은 각 축의 성분에 일정한 배율을 곱하는 연산이다. 2차원에서 크기 변환 함수를 $f(\mathbf{v}) = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix} \mathbf{v}$라고 가정해보자.
두 벡터 $\mathbf{u} = (x_1, y_1)$와 $\mathbf{v} = (x_2, y_2)$가 있을 때
- 가산성 ($f(\mathbf{u} + \mathbf{v}) = f(\mathbf{u}) + f(\mathbf{v})$):
$$f(\mathbf{u} + \mathbf{v}) = \begin{bmatrix} s_x(x_1 + x_2) \\ s_y(y_1 + y_2) \end{bmatrix} = \begin{bmatrix} s_x x_1 \\ s_y y_1 \end{bmatrix} + \begin{bmatrix} s_x x_2 \\ s_y y_2 \end{bmatrix} = f(\mathbf{u}) + f(\mathbf{v})$$ - 동차성 ($f(c\mathbf{v}) = cf(\mathbf{v})$):
$$f(c\mathbf{v}) = \begin{bmatrix} s_x(cx) \\ s_y(cy) \end{bmatrix} = c \begin{bmatrix} s_x x \\ s_y y \end{bmatrix} = cf(\mathbf{v})$$
예시
- 변환: $x$축으로 2배, $y$축으로 3배 키우는 행렬 $S = \begin{bmatrix} 2 & 0 \\ 0 & 3 \end{bmatrix}$
- 벡터: $\mathbf{v} = (1, 2)$
- 결과: $S\mathbf{v} = (2 \times 1, 3 \times 2) = (2, 6)$
- 이 과정에서 원점 $(0, 0)$에 $S$를 곱해도 여전히 $(0, 0)$이다. 즉, 공간의 원점은 그대로 유지된다.
이는 Rotation도 유사하다.
회전 변환은 벡터의 길이는 유지하면서 각도만 변화시킨다. 2차원 회전 행렬로 표현한다면 아래와 같다.
$$R = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}$$
회전 변환 역시 행렬과 벡터의 곱($R\mathbf{v}$)으로 표현되며, 모든 행렬 곱 연산은 선형성을 가진다.
예시
- 변환: 90° 회전 ($\theta = 90^\circ$). $\cos 90^\circ = 0, \sin 90^\circ = 1$ 이므로 $R = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}$
- 벡터: $\mathbf{v} = (1, 0)$ (오른쪽 방향)
- 결과: $R\mathbf{v} = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} \begin{bmatrix} 1 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \end{bmatrix}$
- 오른쪽을 가리키던 벡터가 정확히 위쪽($(0, 1)$)으로 회전했다. 이때도 원점은 고정되어 있다.
수학적으로 "어떤 변환을 행렬 $M$과의 곱셈($M\mathbf{v}$)으로만 나타낼 수 있다면, 그 변환은 선형 변환"이다.
- Scale은 대각 행렬과의 곱으로 표현 가능하다
- Rotation은 회전 행렬과의 곱으로 표현 가능하다.
- 반면 Translation은 단순한 $3 \times 3$ 행렬 곱으로는 $(x+d, y+d)$ 같은 더하기를 구현할 수 없어서 선형 변환의 범주를 벗어나게 되는 것이다.
그럼 여기서 한번 Translation도 선형 변환이 안되는 이유를 식과 예시로 한번 알아보자
이동 변환을 함수 $T(\mathbf{v}) = \mathbf{v} + \mathbf{d}$ 라고 정의해 보자.
여기서 $\mathbf{d}$는 이동할 거리와 방향을 나타내는 벡터(예: $(t_x, t_y)$)이며, $\mathbf{d} \neq \mathbf{0}$ 이다.
이 함수가 선형 변환의 두 가지 조건을 만족하는지 테스트해 보자.
선형 변환이라면 가산성인, $T(\mathbf{u} + \mathbf{v}) = T(\mathbf{u}) + T(\mathbf{v})$ 가 성립해야 한다.
- 좌변 (더한 뒤 이동): $T(\mathbf{u} + \mathbf{v}) = (\mathbf{u} + \mathbf{v}) + \mathbf{d}$
- 우변 (각각 이동 후 더함): $T(\mathbf{u}) + T(\mathbf{v}) = (\mathbf{u} + \mathbf{d}) + (\mathbf{v} + \mathbf{d}) = \mathbf{u} + \mathbf{v} + 2\mathbf{d}$
- 결과: $(\mathbf{u} + \mathbf{v}) + \mathbf{d} \neq \mathbf{u} + \mathbf{v} + 2\mathbf{d}$ 이므로 가산성이 성립하지 않는 모습이다.
선형 변환이라면 동차성인, $T(c\mathbf{v}) = cT(\mathbf{v})$ 가 성립해야 한다.
- 좌변 (상수배 후 이동): $T(c\mathbf{v}) = c\mathbf{v} + \mathbf{d}$
- 우변 (이동 후 상수배): $cT(\mathbf{v}) = c(\mathbf{v} + \mathbf{d}) = c\mathbf{v} + c\mathbf{d}$
- 결과: $c\mathbf{v} + \mathbf{d} \neq c\mathbf{v} + c\mathbf{d}$ 이므로 동차성도 성립하지 않는다.
원점 이동에 대한 고정성도 성립해야 한다.
- $T(\mathbf{0}) = \mathbf{0} + \mathbf{d} = \mathbf{d}$
- 입력값이 $\mathbf{0}$인데 출력값이 $\mathbf{0}$이 아닌 경우이다. 이전 답변에서 스케일은 $0$에 무엇을 곱해도 $0$이었지만, 이동은 $0$에 무언가를 더하는 연산이기 때문에 원점 자체가 이동해 버리게 된다.
결론적으로 이동 변환은 단순한 행렬의 곱셈($M\mathbf{v}$)으로 표현할 수 없고, 더하기($\mathbf{v} + \mathbf{d}$)가 반드시 필요하므로 선형 변환이 아니다. 즉, $T(0) = 0 + d = d$ 이므로, $T(0) = 0$을 만족하지 않는다는 것이다.
이런 이유로 Translation은 선형 변환으로 표현할 수 없으며, 이는 큰 골칫거리가 된다. 나머지 선형 변환은 3차원 벡터 요소로 행렬 계산을 할 수 있는데, Translation는 해당 행렬 계산 행렬 덧셈으로 따로 해줘야 하니 말이다.
이를 위한 해결 방안으로 아핀 변환이 있다. 아핀 변환은 수학적으로 "선형 변환을 수행한 직후에 이동 변환을 수행하는 것"으로 정의된다.
$$f(\mathbf{v}) = M\mathbf{v} + \mathbf{d}$$
(여기서 $M$은 선형 변환(Scale, Rotation) 행렬, $\mathbf{d}$는 이동 벡터)
아핀 변환의 중요한 기하학적 특징은 다음과 같다.
- 원점은 보존되지 않는다.
- 직선은 변환 후에도 여전히 직선으로 유지된다.
- 평행한 선은 변환 후에도 여전히 평행하게 유지된다.
$f(\mathbf{v}) = M\mathbf{v} + \mathbf{d}$ 형태는 곱셈과 덧셈이 섞여 있어 연속적인 변환(예: 스케일 $\rightarrow$ 회전 $\rightarrow$ 이동)을 한 번에 계산하기 어렵다는 문제점이 있다.
이 아핀 변환을 오직 하나의 행렬 곱셈으로만 처리하기 위해 동차 좌표계(Homogeneous Coordinates)를 이용한다.
결론은, "차원을 하나 올리면, 아핀 변환을 선형 변환처럼 취급할 수 있다." 라는게 핵심이다.
3차원 이동 벡터 $\mathbf{d} = (t_x, t_y, t_z)$를 $4 \times 4$ 행렬과 차원이 확장된 벡터의 곱셈으로 표현해보자.
$$\begin{bmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} = \begin{bmatrix} 1\cdot x + 0\cdot y + 0\cdot z + t_x\cdot 1 \\ 0\cdot x + 1\cdot y + 0\cdot z + t_y\cdot 1 \\ 0\cdot x + 0\cdot y + 1\cdot z + t_z\cdot 1 \\ 0\cdot x + 0\cdot y + 0\cdot z + 1\cdot 1 \end{bmatrix} = \begin{bmatrix} x + t_x \\ y + t_y \\ z + t_z \\ 1 \end{bmatrix}$$
여기서 추가된 동차 좌표계를 이용해서 이동을 선형(곱셈)형식으로 만들 수 있다.
이제 SRT 순서를 지켜야 하는 이유를 한번 알아보자
먼저 행렬 곱의 특성은 교환법칙이 성립하지 않는다는 점을 주목해 보자: $AB \neq BA$
즉, 변환의 순서가 바뀌면 결과도 달라지게 된다.
- Scale을 Rotation보다 먼저 하면 생기는 일을 한번 상상해 보자.
물체를 먼저 회전시킨 후, 고정된 축(Axis)을 기준으로 스케일을 키우게 될 것이다. 예를 들어보자. 45도 기울어진 직사각형을 X축으로 2배 늘린다고 상상해 보자. 물체가 단순히 길어지는 게 아니라 옆으로 찌그러지는 Shear(밀림) 현상이 발생하여 모델의 형태가 왜곡될 수 있다. - Rotation을 Translation보다 먼저 하면 생기는 일을 한번 상상해 보자.
모든 선형 변환(Scale, Rotation)은 원점 $(0,0,0)$을 기준으로 일어난다는 점을 상기시켜보자
먼저 물체를 먼저 $(10, 0, 0)$ 위치로 이동시킨다고 가정해 보자. 이 상태에서 회전을 적용하면, 물체는 여전히 원점 $(0,0,0)$을 기준으로 회전하려고 할 것이다. 물체가 제자리에서 도는 게 아니라, 원점을 중심으로 커다란 원을 그리며 공전(Orbit)하며 자기 자신도 같이 회전(자전)하게 될 것이다.
이런 이유들로 인해 SRT 순서를 지켜주는게 중요하다.
'DirectX' 카테고리의 다른 글
| DirectX3D) 8. 선형변환 (0) | 2026.05.10 |
|---|---|
| DirectX3D) 7. 행렬식 (0) | 2026.05.10 |
| DirectX3D) 5. 행렬 (0) | 2026.05.05 |
| DirectX3D) 4. Point (0) | 2026.04.30 |
| DirectX3D) 3. 외적 (0) | 2026.04.29 |