7 분 소요

행렬 Matrix

행렬 Matrix 란?

행렬이란 행(Row)과 열(Col)로 이루어진 2차원 배열이라고 생각하면 된다.

예시로 다음 이미지는 3x2 행렬이다.

3x2행렬


행렬 연산

상수 곱하기

행렬에 어떠한 상수 하나를 곱하는건 매우 단순하다.
그저 모든 원소에 상수를 곱해주면 된다.

상수곱


더하고 빼기

더하기 빼기의 경우는 행과 열의 개수가 정확히 같은 행렬끼리만 연산할 수 있다. 이때 행과 열이 같은 원소끼리 더하고 뺸다.

덧셈뺼셈


행렬의 곱

행렬을 사용하는 이유의 가장 중요한 부분이라고 생각한다.
행렬은 곱은 앞에오는 행렬의 열뒤에서 곱해지는 행렬의 행 갯수가 같아야 연산할 수 있다. 행렬의 곱의 결과앞에 오는 행렬의 행 x 뒤에서 곱해지는 행렬의 열로 이루어진다.

행곱


간단하게 말해서 1x4 행렬과 4x3행렬은 서로 곱할 수 있고 결과는 1x3의 행렬이 나온다.

그럼 행렬의 곱이 어떻게 이루어지는지 보자.
행렬의 곱의 결과의 원소들은 다음과 같은 값을 가진다.

행렬곱 공식


식대로라면 곱의 결과의 i행j열은 (행렬A의 i행1열 x 행렬 B의 1행j열) + (행렬A의 i행2열 x 행렬 B의 2행j열) … (행렬A의 i행n열 x 행렬 B의 n행j열) 이 된다.
그러면 3x2행렬 A와 2x3행렬 B의 곱을 봐보자.
곱의 결과의 1행1열은 다음과 같이 구할 수 있다.

1행1열


위의 이미지 처럼 곱의 결과의 1행1렬은 A행렬의 1행의 모든 값B행렬의 1열의 모든 값을 각각 곱하고 더한다.
그럼 곱의 결과의 1행2열은 어떻게 구할까?
답은 다음과 같다.

1행2열


2행1열과 2행2열도 다음과 같이 구할 수 있다.

2행1열

2행2열

기억하기 어렵다면 이 부분만 기억하자.

  • 곱의 결과의 행은 행렬A의 행의 갯수와 같고 열은 행렬B의 열의 갯수와 같다. (3x2 와 2x3의 곱은 2x2)
  • 곱의 결과의 원소인 i행j열의 값에 대해서는 행렬A의 i행의 모든 원소행렬 B의 j열의 모든 원소를 각각 곱하고 더해준다.

행렬의 교환법칙과 결합법칙

행렬은 우선 교환법칙이 성립하지 않는다.

AB != BA

교환법칙

하지만 결합법칙은 성립한다.

(AxB) x C = A x (B x C)

항등행렬 identity

항등 행렬은 왼쪽 위에서 오른쪽 아래를 나타내는 대각선 원소들이 1이고 그 외 나머지 모든 원소가 0인 행렬이다.
또한 행과 열의 갯수가 정확히 같은 n x n의 행렬에서만 존재한다.

항등행렬

항등행렬은 다음과 같은 중요한 특징들이 있다.


  • 교환법칙 성립
  • 다른 어떤 행렬과 곱했을 때 그 행렬이 그대로 유지

항등행렬특징

역행렬

정방행렬(즉,n×n 행렬) A 에 대해, 만약 어떤 행렬 B가 존재하며
A X B = I(항등행렬) 과 B X A = I 를 만족한다면
B는 A의 역행렬이고 A는 B의 역행렬이라고 할 수 있다.

역행렬은 기존 행렬을 완전히 초기화 시킨다고 볼 수 있기 떄문에 표기할 때 -1기호를 윗첨자로 붙여 표기한다.
$A^{-1} $

역행렬은 다음과 같은 중요한 특징들이 있다.


  • 역행렬의 역행렬은 원래 행렬이다. $ (A^{-1})^{-1} = A $

  • 역행렬은 단 한개만 존재한다.


역행렬을 구하는 공식은 다음과 같다.

행렬M 어떠한 행렬 M이 있을 때,

역행렬 공식 조건 다음 조건을 만족하면

역행렬 공식 아래와 같이 구할 수 있다.

역행렬 공식 예시

전치행렬 Transpose Matrix

전치 행렬은 어떤 행렬의 행과 열을 서로 바꾼 행렬을 의미하며 $ M^{T} $ 이런식으로 윗첨자 T를 붙여 표기한다.

전치 행렬


곱의 전치 두 행렬 M과 N이 있다고 했을때
$ (MN)^{T} = N^{T}M&{T} $ 를 만족한다.

곱의 전치

직교 행렬

직교 행렬이란 행과 열이 서로 직교하는 행렬을 말한다.
직교두 벡터가 수직인 경우, 즉 내적의 값이 0일경우 직교하다고 할 수 있다.

예를 들어 다음과 같은 3x3 행렬인 M이 있다.
행렬3x3

이 행렬은 다음과 같이 행끼리 또는 열끼리 나눠 3개의 벡터를 만들 수 있다.
행과열로나누기

이렇게 행과 열로 나눠진 벡터들의 내적의 값이 0일 경우 직교 행렬이라고 할 수 있다. 내적 결과

직교 행렬을 정의하는 또 다른 방법은 어떠한 행렬의 역행렬과 전치행렬이 같은 경우 직교행렬이라고 할 수 있다.

$ M^{T} = M^{-1} , MM^{T} = I$

게임 엔진에서의 행렬

유니티와 같은 게임 엔진에서는 벡터를 이용하여 위치(Position), 회전(Rotation), 크기(Scale)을 표현한다.
이러한 벡터들을 연산하여 위치,회전,크기등을 변환할 수 있다.
이때 벡터의 연산을 다음과 같이 행렬의 곱으로 나타낼 수 있다.

벡터를 행렬의 곱으로

위의 이미지를 보면 xyz값이 들어가 있는 1x4행렬에 어떠한 행렬 M(4x4)를 곱해 나오는 결과로 새로운 XYZ값이 들어간 1x4행렬을 얻을 수 있다.

여기서 굳이 xyz값만 들어간 1x3행렬이아닌 1이 포함된 1x4행렬을 사용하는데 이를 동차좌표계라고 하며 SRT변환을 더 간편하게 처리할 수 있게 해준다.

SRT(scale, rotation, translation) 변환 행렬

그럼 행렬을 통해 위치, 회전, 크기등을 어떻게 바꿀 수 있는지 보자.
비교적 간단한 이동과, 크기를 먼저 설명하고 회전을 설명하겠다.

이동 (Translation)

어떠한 좌표 P1(x,y,z)가 있다고 해보자.
P1좌표에서 v(a,b,c)벡터만큼 이동하여 P2(X,Y,Z)좌표가 된다고 했을 때
P2의 좌표값(X,Y,Z)는 다음 처럼 세 개의 식으로 정의할 수 있다.

이동예시


하지만 행렬의 곱을 이용하여 3개의 식으로 각각 구하지 않고 한 번의 공식으로 정리할 수 있다.
즉 아래의 두 식이 같은 결과를 만들도록 바꿔야 한다.

두식


결과는 아래와 같이 4x4행렬을 다음과 같이 바꾸면 된다. translation행렬 결과

크기(Scale)

scale또한 간단하다. 어떠한 오브젝트의 크기가 S1(x,y,z) 일때,
각 축별로 v(a,b,c) 배로 커져 크기 S2(X,Y,Z)가 된다고 했을 때
P2의 크기는 다음 처럼 세 개의 식으로 정의할 수 있다.

크기예시


이 또한 행렬의 곱으로 표현할 수 있고 4x4행렬을 다음과 같이 바꾸면 된다.


크기 결과


회전(Rotation)

벡터의 회전연산을 행렬로 나타내는 방법은 다음과 같다.
우선, 예를 들어 어떠한 점 P1이 Z축을 중심으로 β만큼 회전을 하여 P2의 위치로 이동한다고 가정해보자.

회전 예시


이 회전을 다음과 같이 나타내어 간단한 식을 만들 수 있다.

좌표 시각화


이 식을 삼각함수의 덧셈공식을 이용하여 X와 Y에 대한 식으로 변경이 가능하다.

삼각함수 덧셈공식

변환공식 만들기


이렇게 만들어진 식을 이제 행렬의 곱으로 나타내기 위해서 4x4행렬을 만들 수 있다.

행렬의 곱으로 변환?


4x4행렬의 결과는 다음과 같다.

z축 기준 회전행렬


어떤 축으로 회전하느냐에 따라서 행렬의 모양이 조금씩 달라지지만,
모두 같은 방식으로 행렬의 곱 공식을 유도할 수 있다.

회전 공식 유도

참고로 이 회전 행렬은 1x4(xyz1) * 4x4를 기준으로 만든 회전 행렬이기 때문에
4x4 * 4x1(xyz1)를 기준으로한 회전 행렬과는 전치행렬의 관계를 가지고있다.

좌표계 변환 행렬

3D세계의 중심(0,0,0)을 기준으로 가지는 월드 좌표계라는 개념도 있지만,
자기자신의 중심을 기준으로 가지는 로컬 좌표계도 존재한다.
그렇기 때문에 만약 사용하는 좌표계가 다를 경우 벡터 연산을 하기 위해서는 좌표계를 일치시켜줄 필요가 있다.

이때 사용할 수 있는 행렬이 좌표계 변환 행렬이다.
A좌표계를 기준으로하는 어느 한 벡터 v(x,y,z)를 이 행렬과 곱하여 B좌표계를 기준으로 하는 벡터 V(X,Y,Z)로 변환하는 것이 목적이다. 간단한 유도과정을 위해서 2차원 좌표계로 공식을 유도해보면 다음과 같다.
먼저 좌표계 A가 존재하고 A좌표계 안에서 M(x,y)가 존재한다.

A좌표계속 M


이때 $\overrightarrow{AM}$ 은 A좌표계단위벡터인 u와 v로 나타낼 수 있다.

AM


똑같은 방식으로 새로운 좌표계 B가 있을 때 $\overrightarrow{BM}$ 도 B좌표계의 단위벡터인 U와 V로 나타낼 수 있다.

BM


여기서 중요한 점은 A좌표계의 단위벡터u,vB좌표계의 X,Y성분으로 쪼개질 수 있기 때문에
B좌표계의 단위벡터 U,V에 대한 값으로 치환할 수 있다는 것이다.

단위벡터변환


단위 벡터의 치환을 이용하여 A좌표계를 기준으로한 벡터 v를 가지고
B좌표계를 기준으로한 벡터V로 바꾸는 공식을 다음과 같이 유도할 수 있다.

공식 유도

이 공식이 의미하는 바는 간단하다.
A좌표계에서 B좌표계로 바뀔 때 A좌표계의 단위 벡터 u와 v는 B좌표계의 X와Y성분으로 쪼개질 수 있기에
uX성분과 vX성분을 더해 X값을,
uY성분vY성분으로 Y값을 유추할 수 있다.
마지막으로 좌표계의 중심이 되는 지점도 다르므로 좌표계끼리의 간격 $\overrightarrow{BA}$ 를 더하므로(평행이동) A좌표계에서 B좌표계로 변환이 가능하다는 소리이다.

3차원에서의 경우도 똑같은 방식으로 공식이 만들 수 있을것이며 다음과 같은 공식이 나올것이다.

3차원공식


이 공식을 이제 행렬의 곱으로 나타내기위해 4x4행렬로 바꾸면 다음과 같이 만들 수 있다.

행렬공식 완성


이 좌표계 변환 행렬의 특징으로는 다음과 같이 A좌표계의 성분과 좌표를 알아낼 수 있다.

좌표계변환행렬특징


추가로 알아두면 좋은 점이 있다.
A좌표계 기준 점M의 위치 벡터인 1x4(x,y,z,1) 과 4x4좌표계 변환 행렬을 곱해서 B좌표계 기준 점M의 위치를 구할 수 있다.

이때, 위치벡터인 1x4행렬의 동차좌표계가 0이되면 어떤 의미가 될까?
답은 바로 A좌표계 기준으로하는 어떠한 방향벡터를 B좌표계 기준으로 바꾸는 것이다.

동차 좌표계가 0이된다면 좌표계 변환행렬의 Qx,Qy,Qz값이 0이 되는것과 같을 것이다.
이는 곧, 좌표계 변환행렬에서 두 좌표계의 원점은 같고 회전값만 다른것을 의미하며
그렇기 때문에 A좌표계의 어떠한 벡터 v를 B좌표계 기준의 값으로 바꿀 수 있다.

흑흑

다 까먹어도 이것만 기억해두자.
좌표계 변환 행렬은 S(Scale)R(Rotation)T(Translate)순으로 행렬은 곱한 결과이다.
하지만 보통 좌표계 변환에서 S은 의미가 없기 때문에 RxT 라고 볼 수 있다.

RT

4x4행렬에서 1x3~3x3 이 부분이 회전 정보를 담고 있고, 4x1 ~ 4x3 이 부분이 이동 정보를 담고있다고 생각하면 된다.

World 변환 행렬

게임 세상에선 월드 좌표라는 기준이 존재한다.
다른 모든 좌표계는 이 월드 좌표를 기준으로하여 scale, roation, translation이 변화한 것이다.
즉, 월드 좌표계를 기준으로 변한 로컬좌표계의 SRT행렬이 곧 로컬에서 월드 의 변환행렬을 나타내는것이다.
(로컬 좌표계의 어느 한 점의 좌표는 로컬 좌표계가 월드좌표계에서 변한 SRT값을 곱해주면 월드 좌표를 기준으로 하는 좌표가됨.)

위에서 한 좌표계 변환 행렬을 통해서 월드 변환 행렬에 적용해볼 수 있다.
로컬좌표계(A)에서 월드좌표계(B)로 변환하는 예시를 보자.

월드 좌표계(B)를 기준으로 (2,0,-3)만큼 떨어진 곳을 기준으로하여 추가로 (0,-45도,0)만큼 회전한 좌표계A가 있다.
A좌표계


이 A좌표계를 기준으로 (2,0,1)에 위치한 점M이 존재한다.
이 점M을 월드좌표계(B)를 기준으로하는 좌표값을 알아내는것이 목표이다.

문제

위의 값을 알아내려면 A->B좌표계의 변환 행렬을 구해야한다.
구해야하는 4x4행렬


맨 밑 4행의 값은 위에서도 나왔듯 A좌표계는 B좌표계로 부터 2,0,-3 떨어져 있기에 다음과 같이 채울 수 있다.

Q채우기


123행은 B좌표계 기준으로 A좌표계의 단위 벡터의 xyz성분을 넣어줘야한다.
채우는것은 간단한데 A좌표게 단위 벡터B좌표계의 단위 벡터y축을 기준으로 -45도 회전한 것이기에
B좌표의 단위벡터 x(1,0,0,0), y(0,1,0,0), z(0,0,1,0)
각각 y축을 기준으로 -45도 회전하는 회전형렬을 곱한뒤(cos값과 sin값은 대략적으로 구함)
1행,2행,3행에 차례대로 넣어주면 된다. 그러면 B좌표게 변환 행렬이 완성된다.

A단위벡터 성분 구하기

변환공식 완성

완성된 변환 행렬로 B좌표계에서의 점M(A좌표계기준 2.0,1위치)의 위치를 구할 수 있다.

결과

View space 변환 행렬

카메라 좌표계를 기준으로 변환하는 행렬을 View 변환 행렬이라고 한다.

View행렬을 구하는 방법은 View(카메라)좌표계에서 World좌표계로 변환하는 행렬을 역행렬하여 구할 수 있다.

공식 유도

$T^{-1} * R^{T}$ 는 다음과 같이 구함
공식유도2

다음과 같은 View space 변환 행렬을 얻어낼 수 있다. View변환 행렬

4행의 1열 2열 3열을 내적으로 표현해서 와닿지 않을 수 있는데,
다른 좌표계변환 행렬과 똑같이 View(카메라)좌표계를 기준으로 원점(0,0,0)의 위치라고 생각하면 된다.

Projection 변환 행렬

projection 변환이란 3D 공간의 좌표를 2D화면에 투영시키는 것이다.
즉 xyz값을 통해 XY값을 뽑는다. 남은 Z값 자리에는 near(0)와 far(1)사이로 값을 담아 거리를 담을 수 있다.

투영 이미지

Projection 변환 행렬을 유도하는 과정은 다음과 같다.
3D 좌표계인 카메라 좌표계의 xyz 좌표를 통해 2D좌표계인 컴퓨터의 화면인 XY좌표로 유도하는 과정이다.(X,Y는 -1 ~ 1사이의 값)

다음과 같이 카메라를 기준으로한 좌표계에서 점 M이 위치한다.

점M

이 점을 카메라 시점으로 Z가 1인 지점에 투영한다고 하였을 때, 다음과 같이 투영된다.

투영

그럼 z의 값이 1까지 줄어드니 같은 비율로 xy도 함께 값이 줄어들어야한다.
그래서 다음과 같이 XY를 구하는 간단한 식을 작성할 수 있다.

간단한 XY식

모니터 화면이 정확한 정사각형도 아니기 때문에 비율을 맞춰줄 보정값을 추가한다.(일단 화면을 800 x 600 해상도라고 해둠)

보정값 추가

여기까지는 카메라의 시점 각도가 90도로 고정된 상태로 유도한 것이지만,
카메라의 각도도 줄이거나 늘릴 수 있기 때문에 다음과 같이 바꾼다.
tan

그럼 이렇게 만들어진 식을 4x4과의 행렬의 곱으로 나타내야 한다.

행렬식

하지만 이 행렬식을 통해서는 x나y가 곱해지는 동시에 z가 나눠지는 식을 만드는게 불가능하다.
그렇기 떄문에 조금의 변칙을 줘서 식을 만들어야한다.

그래서 행렬의 곱에 더해서 Z로 나누는 두 번의 계산으로 나눠 식을 만들 수 있다.

식

추가로 projection 변환에선 nearfar라는 개념이 존재한다.
카메라의 범위 내에서 사물을 화면에 담을 수 있는 가장 가까운거리 near
가장 먼거리far 사이의 들어온 좌표만을 판별하기 위해 z거리에 따라 0~1사이의 값으로 추가로 저장해야한다.

예시 이미지

그래서 계산의 결과인 1x4행렬의 3번쨰 열에 A와B의 보정값을 추가해 0~1사이의 값을 추가로 저장한다.

최종유도

최종적으로 다음과 같이 행렬식을 구할 수 있다. 최종식

태그:

카테고리:

업데이트:

댓글남기기