행렬
행렬 Matrix
행렬 Matrix 란?
행렬이란 행(Row)과 열(Col)로 이루어진 2차원 배열이라고 생각하면 된다.
예시로 다음 이미지는 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렬은 A행렬의 1행의 모든 값
과 B행렬의 1열의 모든 값
을 각각 곱하고 더한다.
그럼 곱의 결과의 1행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이 있을 때,
다음 조건을 만족하면
아래와 같이 구할 수 있다.
전치행렬 Transpose Matrix
전치 행렬은 어떤 행렬의 행과 열을 서로 바꾼 행렬
을 의미하며 $ M^{T} $ 이런식으로 윗첨자 T를 붙여 표기한다.
곱의 전치
두 행렬 M과 N이 있다고 했을때
$ (MN)^{T} = N^{T}M&{T} $ 를 만족한다.
직교 행렬
직교 행렬이란 행과 열이 서로 직교
하는 행렬을 말한다.
직교
란 두 벡터가 수직
인 경우, 즉 내적의 값이 0
일경우 직교하다고 할 수 있다.
예를 들어 다음과 같은 3x3 행렬인 M이 있다.
이 행렬은 다음과 같이 행끼리 또는 열끼리 나눠 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행렬을 다음과 같이 바꾸면 된다.
크기(Scale)
scale또한 간단하다. 어떠한 오브젝트의 크기가 S1(x,y,z)
일때,
각 축별로 v(a,b,c) 배로 커져 크기 S2(X,Y,Z)
가 된다고 했을 때
P2의 크기는 다음 처럼 세 개의 식으로 정의할 수 있다.
이 또한 행렬의 곱으로 표현할 수 있고 4x4행렬을 다음과 같이 바꾸면 된다.
회전(Rotation)
벡터의 회전연산을 행렬로 나타내는 방법은 다음과 같다.
우선, 예를 들어 어떠한 점 P1이 Z축을 중심으로 β만큼
회전을 하여 P2의 위치로 이동한다고 가정해보자.
이 회전을 다음과 같이 나타내어 간단한 식을 만들 수 있다.
이 식을 삼각함수의 덧셈공식을 이용하여 X와 Y에 대한 식으로 변경
이 가능하다.
이렇게 만들어진 식을 이제 행렬의 곱으로 나타내기 위해서 4x4행렬을 만들 수 있다.
4x4행렬의 결과는 다음과 같다.
어떤 축으로 회전하느냐에 따라서 행렬의 모양이 조금씩 달라지지만,
모두 같은 방식으로 행렬의 곱 공식을 유도할 수 있다.
참고로 이 회전 행렬은 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)가 존재
한다.
이때 $\overrightarrow{AM}$ 은 A좌표계
의 단위벡터인 u와 v로 나타낼 수 있다.
똑같은 방식으로 새로운 좌표계 B
가 있을 때 $\overrightarrow{BM}$ 도 B좌표계의 단위벡터인 U와 V로 나타낼 수 있다.
여기서 중요한 점은 A좌표계의 단위벡터u,v
가 B좌표계의 X,Y성분으로 쪼개질 수 있기 때문에
B좌표계의 단위벡터 U,V에 대한 값
으로 치환
할 수 있다는 것이다.
단위 벡터의 치환을 이용하여 A좌표계를 기준으로한 벡터 v
를 가지고
B좌표계를 기준으로한 벡터V
로 바꾸는 공식을 다음과 같이 유도할 수 있다.
이 공식이 의미하는 바는 간단하다.
A좌표계에서 B좌표계로 바뀔 때
A좌표계의 단위 벡터 u와 v
는 B좌표계의 X와Y성분으로 쪼개질 수 있기에
u
의 X성분과
v
의 X성분
을 더해 X
값을,
u
의 Y성분
과 v
의 Y성분
으로 Y
값을 유추
할 수 있다.
마지막으로 좌표계의 중심이 되는 지점도 다르므로
좌표계끼리의 간격
$\overrightarrow{BA}$ 를 더하므로(평행이동) A좌표계에서 B좌표계로 변환
이 가능하다는 소리이다.
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
라고 볼 수 있다.
4x4행렬에서 1x3~3x3 이 부분이 회전 정보
를 담고 있고, 4x1 ~ 4x3 이 부분이 이동 정보
를 담고있다고 생각하면 된다.
World 변환 행렬
게임 세상에선 월드 좌표라는 기준이 존재한다.
다른 모든 좌표계는 이 월드 좌표를 기준으로하여 scale, roation, translation이 변화한 것이다.
즉, 월드 좌표계를 기준으로 변한 로컬좌표계의 SRT행렬이 곧 로컬에서 월드
의 변환행렬을 나타내는것이다.
(로컬 좌표계의 어느 한 점의 좌표는 로컬 좌표계가 월드좌표계에서 변한 SRT값을 곱해주면 월드 좌표를 기준으로 하는 좌표가됨.)
위에서 한 좌표계 변환 행렬
을 통해서 월드 변환 행렬
에 적용해볼 수 있다.
로컬좌표계(A)에서 월드좌표계(B)로 변환하는 예시를 보자.
월드 좌표계(B)를 기준으로 (2,0,-3)
만큼 떨어진 곳을 기준으로하여 추가로 (0,-45도,0)만큼 회전
한 좌표계A가 있다.
이 A좌표계를 기준으로 (2,0,1)에 위치한 점M
이 존재한다.
이 점M을 월드좌표계(B)를 기준으로하는 좌표값
을 알아내는것이 목표이다.
위의 값을 알아내려면 A->B좌표계의 변환 행렬을 구해야한다.
맨 밑 4행의 값은 위에서도 나왔듯 A좌표계는 B좌표계로 부터 2,0,-3 떨어져 있기
에 다음과 같이 채울 수 있다.
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좌표게 변환 행렬이 완성된다.
완성된 변환 행렬로 B좌표계에서의 점M(A좌표계기준 2.0,1위치)의 위치를 구할 수 있다.
View space 변환 행렬
카메라 좌표계를 기준으로 변환하는 행렬을 View 변환 행렬이라고 한다.
View행렬을 구하는 방법은 View(카메라)좌표계에서 World좌표계로 변환하는 행렬을 역행렬
하여 구할 수 있다.
$T^{-1} * R^{T}$ 는 다음과 같이 구함
다음과 같은 View space 변환 행렬을 얻어낼 수 있다.
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이 위치한다.
이 점을 카메라 시점으로 Z가 1인 지점에 투영한다고 하였을 때, 다음과 같이 투영된다.
그럼 z의 값이 1까지 줄어드니 같은 비율로 xy도 함께 값이 줄어들어야한다.
그래서 다음과 같이 XY를 구하는 간단한 식을 작성할 수 있다.
모니터 화면이 정확한 정사각형도 아니기 때문에 비율을 맞춰줄 보정값을 추가한다.(일단 화면을 800 x 600 해상도라고 해둠)
여기까지는 카메라의 시점 각도가 90도로 고정된 상태로 유도한 것이지만,
카메라의 각도도 줄이거나 늘릴 수 있기 때문에 다음과 같이 바꾼다.
그럼 이렇게 만들어진 식을 4x4과의 행렬의 곱으로 나타내야 한다.
하지만 이 행렬식을 통해서는 x나y가 곱해지는 동시에 z가 나눠지는 식을 만드는게 불가능하다.
그렇기 떄문에 조금의 변칙을 줘서 식을 만들어야한다.
그래서 행렬의 곱에 더해서 Z로 나누는 두 번의 계산으로 나눠 식을 만들 수 있다.
추가로 projection 변환에선 near
와 far
라는 개념이 존재한다.
카메라의 범위 내에서 사물을 화면에 담을 수 있는 가장 가까운거리 near
와
가장 먼거리far
사이의 들어온 좌표만을 판별하기 위해 z거리에 따라
0~1사이의 값으로 추가로 저장해야한다.
그래서 계산의 결과인 1x4행렬의 3번쨰 열에 A와B의 보정값을 추가해 0~1사이의 값을 추가로 저장한다.
최종적으로 다음과 같이 행렬식을 구할 수 있다.
댓글남기기