Skip to main content

Command Palette

Search for a command to run...

[css] 변환 행렬 - 전편

Updated
•3 min read•View as Markdown
[css] 변환 행렬 - 전편

CSS에서는 요소의 이동이나 크기, 회전을 조절하기 위한 transform 속성이 있습니다. 이는 내부적으로 변환 행렬을 통해 처리합니다. 변환 행렬을 사용하면 요소의 변환을 비교적 간단하게 수행할 수 있습니다.

변환 행렬

변환 행렬이란 변환에 대한 행렬 표현입니다. 여기서 변환이란 함수라 생각해 주시면 됩니다. 즉, 함수의 행렬 표현 정도로 보시면 되겠네요. 행렬이 어떻게 함수의 역할을 할 수 있을까요? 함수가 무엇인가요? 기능 측면에서 접근해 봅시다. 함수는 입력이 들어오면 출력을 내보냅니다. 마찬가지로 변환 행렬에 입력을 주면, 출력을 얻을 수 있습니다. 신기하죠? 자, 이제 작동 방식을 한번 살펴봅시다.

$$\begin{aligned} \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} a & c \\ b & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + cy \\ bx + dy \end{pmatrix} \end{aligned}$$

위 수식을 보시면 변환 행렬에 순서쌍 $(x, y)$를 곱해서 새로운 순서쌍 \((ax + by, bx + dy)\)을 얻었습니다. 이게 바로 tansform 속성이 행렬을 사용해서 대상 요소를 조작하는 방식입니다. 간단하죠? 이 $x$와 $y$에 실제 값을 넣으면 우리가 원하는 변경된 좌표를 얻을 수 있습니다. 우리는 주로 사각형 영역을 다루니까 네 개의 점을 각각 대입하여 새로운 네 개의 점을 얻을 수 있겠네요.

그런데 조금 이상한 점이 있죠? transform 속성을 다룰 때 가장 많이 사용하는 함수가 무엇인가요? 제 개인적으로는 translate일 것 같은데요. translate는 위치 변환을 담당합니다. 그런데 우리가 얻은 순서쌍의 결과를 보면 상수항이 없습니다. 즉, 네 개의 점을 문자 그대로 특정 수치만큼 옮길 수가 없다는 것이죠.

예를 들어볼까요? 대상이 $(0, 0)$을 꼭짓점 중 하나로 갖는다고 가정해 봅시다. 이제 새로이 얻은 순서쌍에 점의 좌표를 대입해 봅시다. 결과는 뻔하죠? $x$와 $y$가 모두 0이니 결과는 $(0, 0)$이 되겠네요. 결과적으로 행렬을 어떻게 구성하더라도 점을 이동할 수 없다는 의미가 되겠네요.

아핀 변환 행렬

이를 해결하기 위해 아핀 변환 행렬이라는 개념을 적용합니다. 이는 차원을 하나 추가하여 위치 변환을 가능케 합니다. 변환을 수행하면 아래와 같습니다.

$$\begin{aligned} \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} ax + cy + e \\ bx + dy + f \\ 1 \end{pmatrix} \end{aligned}$$

사용하지 않는 차원을 하나 추가함으로써 새로운 순서쌍의 각 요소에 상수항을 만들어 냈습니다. 이제 기존 좌표에 영향을 받지 않고 문자 그대로 위치를 원하는 만큼 옮길 수 있겠네요.

변환 행렬의 종류

기준위치 변환기울기 변환
\(\begin{pmatrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{pmatrix}\)\(\begin{pmatrix}1 & 0 & t_x\\0 & 1 & t_y\\0 & 0 & 1\end{pmatrix}\)\(\begin{pmatrix}1 & \tan\theta_y & 0\\tan\theta_x & 1 & 0\\0 & 0 & 1\end{pmatrix}\)
기울기 변환회전 변환
\(\begin{pmatrix}1 & \tan\theta_y & 0\\tan\theta_x & 1 & 0\\0 & 0 & 1\end{pmatrix}\)\(\begin{pmatrix}\cos\theta & -\sin\theta & 0\\sin\theta & \cos\theta & 0\\0 & 0 & 1\end{pmatrix}\)

기준 행렬은 어떠한 변환도 수행하지 않은 초기 상태를 나타내며 단위행렬로 표현됩니다.

위치 변환 행렬은 대상을 이동하는 데 사용됩니다. 후술하겠지만 이는 단순히 좌표를 이동하는 것과는 조금 다릅니다.

크기 변환 행렬은 대상의 크기를 축소/확대하는 데 사용됩니다. 닮음 변환 행렬이라고도 불립니다.

기울기 변환 행렬은 대상을 특정 방향으로 기울이는 데 사용됩니다. 위 표에서는 기준 축과의 각에 대해 표현한 것으로 scaleX에 대해서는 \(\theta_y\)가 사용되며 scaleY에 대해서는 \(\theta_x\)가 사용됩니다. 전단 변환 행렬이라고도 불립니다.

회전 변환 행렬은 대상을 특정 각도만큼 회전하는 데 사용됩니다.

내용은 다음 편에서 이어집니다. 읽어주셔서 감사합니다!

묻고 답하기

개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.

More from this blog

[TypeScript] 자료 구조로 담아내기. #14 - 연결 리스트(with. 이중 연결)

이번 편은 이전 편으로부터 이어집니다. 연결 리스트의 또 다른 형태는 이중 연결 리스트입니다. 후임자의 참조만 저장하는 단일 연결 리스트와 달리 이중 연결 리스트는 선임자의 참조도 함께 저장합니다. interface DoublyLinkedListNode<T> extends DoublyLinkedList<T> { linkBefore(succ: DoublyLinkedListNode<T>): void; linkAfter(pred: D...

May 3, 20253 min read9
[TypeScript] 자료 구조로 담아내기. #14 - 연결 리스트(with. 이중 연결)

[TypeScript] 자료 구조로 담아내기. #12 - 연결 리스트(with. null 노드)

이번 편은 이전 편으로부터 이어집니다. 조금 예리하신 분들은 이전 편에서 다룬 헤드 노드만으로는 충분치 않다는 것을 느끼셨을 것입니다. 최소한 첫 노드에 예외를 부여하는 상황은 피했으나 후임자가 null임을 확인하는 구현 또한 만족스럽지는 않습니다. 카이로의 코끼리 카이로의 코끼리에 대해 알고 계십니까? 링크를 통해 확인하실 수 있습니다. 꽤 재밌으므로 한번 읽어 보시길 추천합니다. 여기서 중요한 아이디어는 끝 위치에 미리 코끼리를 둔다는 것...

Apr 19, 20252 min read12
[TypeScript] 자료 구조로 담아내기. #12 - 연결 리스트(with. null 노드)

[TypeScript] 자료 구조로 담아내기. #11 - 연결 리스트(with. 헤드 노드)

이번 편은 이전 편으로부터 이어집니다. 이전 편에서는 연결 리스트의 접근자는 첫 노드의 선임자가 적절하다는 것을 알았습니다. 얼핏 보기엔 문제없어 보이는데 어떤가요? 최상위 연결 리스트 즉, 가장 처음에 위치한 노드로 시작하는 경우를 생각해 봅시다. 가장 처음에 위치한 노드의 선임자는 무엇인가요? 맞습니다. 선임자가 존재하지 않겠지요. 그럼 어떻게 해야 할까요? 선임자를 가지지 않는 첫 노드를 갖는 연결 리스트에 대해 예외를 적용해야 할까요?...

Apr 12, 20252 min read13
[TypeScript] 자료 구조로 담아내기. #11 - 연결 리스트(with. 헤드 노드)

고라니드로의 블로그

47 posts