개인적으로 공부하는 내용이므로 틀린 부분이 있을 수 있습니다. 있다면 알려주세요 ~!
게임 개발을 위한 선형대수학 기본
행렬과 벡터(Matrices and Vectors)
행렬(matrix)
- 행렬은 주로 Matrix의 앞 문자를 따서 대문자 M으로 표현한다.
- m개의 행과 n개의 열로 이루어진 행렬을 m X n 행렬이라 한다.
- 행과 열이 같으면 정사각 행렬이라 한다.
- 행렬 M1와 행렬 M2의 곱셈이 가능하려면 행렬 M1의 열과 행렬 M2의 행이 같아야 한다. 즉 M1(a X b) M2(b X c)와 같이 되어야 하고 그 결과는 M3(a X c) 행렬이 된다.
- 행렬의 교환 법칙은 성립하지 않는다는 것을 잊지말자.
벡터(vector)
- 벡터는 보통 Vector의 앞 문자를 따서 소문자 v로 표현한다.
- 벡터는 행렬의 특수한 경우라고 볼 수 있다.
- 2차원 벡터는 (x, y), 3차원 벡터는 (x, y, z)와 같이 표현하며, 이를 행벡터(row vector)라고 한다.
- 물론 위와 같은 행벡터는 열벡터(column vector)로도 표현할 수 있다. 위 행벡터를 열벡터로 변환하면 다음과 같다.
- 행렬과 벡터는 곱셈이 가능하며, 순서는 상관없지만 교환 법칙은 당연히 성립하지 않는다.
- 행렬X벡터일 경우 행렬의 열과 벡터의 행은 같아야 한다.
- 아래의 예는 2X3 행렬과 3X1 벡터의 곱셈이며, 그 결과는 2X1 행렬이다.
전치 행렬(Transposed matrix)
- 행렬의 행과 열을 교환하여 얻은 행렬을 전치 행렬이라 한다.
- 예를 들어 다음은 기존 행렬과 전치 행렬을 나타낸 것이다.
- 두 행렬의 곱에 대한 전치 행렬은 다음과 같다.
Direct3D에서의 행렬과 벡터 사용
- Direct3D에선 열벡터가 아닌 행벡터를 사용한다.
- 행렬과 벡터를 곱할 때 벡터X행렬의 순서로 곱한다.
OpenGL에서의 행렬과 벡터 사용
- 열벡터를 사용한다.
- 행렬X벡터 순서로 곱한다.
단위 행렬(Identity matrix)
- 주대각 원소가 모두 1이고 나머지 원소가 0인 행렬을 단위 행렬이라 한다.
- 단위 행렬은 모든 행렬에 대해 항등원이다. 따라서 모든 행렬에 대해 곱셈에 대한 교환 법칙이 성립한다.
- 만약 어떤 두 행렬의 곱이 단위 행렬이라면 두 행렬은 서로 역행렬 관계이다.
단위 벡터(Unit vector)
다음과 같이 2차원, 3차원 벡터가 있다고 가정해보자.
각 벡터의 크기는 다음과 같다.
다음과 같이 각 벡터를 자신의 크기로 나누는 것을 정규화(normalization)라 한다. 정규화는 크기를 1로 만드는 과정이다. 이렇게 정규화된 벡터를 단위 벡터라 한다.
좌표계와 기저(Coordinate system and basis)
- 좌표계는 원점과 기저로 이루어진다.
- 2차원 공간(좌표계)에서 모든 벡터는 기저 벡터의 선형 결합으로 정의될 수 있다.
- 단순한 값으로 예를 들면 1이라는 기저로 모든 자연수를 표현할 수 있는 것과 같다.
다음과 같이 각각 x,y축과 일치하고 크기가 1인 벡터를 생각해보자. 그리고 이 벡터로 (3,5)라는 만들어보자.
각 벡터를 e1, e2라고 하면 간단하게 실수배를 한 뒤 두 벡터의 합으로 (3,5) 벡터를 표현할 수 있다. 여기서 결과 벡터를 만드는데 사용한 벡터를 기저 벡터라고 할 수 있다. 여기서 사용된 두 기저 벡터는 다음과 같은 특징을 가진다.
- 두 벡터는 모두 x, y축과 동일하다. (= 좌표가 1인 것을 제외한 모든 좌표가 0)
- 두 벡터는 서로 직교한다.
- 두 벡터의 크기는 모두 1이다.
우선 e1과 e2는 각각 x, y축과 일치한다. 즉 크기를 제외하면 각 축과 동일하다. 이러한 기저(벡터)를 standard basis라 한다. 그리고 두 벡터는 서로 90도를 이룬다. 이를 orthogonal하다고 한다. 그리고 두 벡터의 크기는 모두 1이다. 이를 normalized(정규화) 되었다고 한다. 그리고 이 두 조건을 모두 만족한다고 해서 합성어로 orthogonal + normalized = orthonormal하다고 한다.
그러나 다음과 같이 꼭 orthonormal과 standard를 만족하지 않아도 (3, 5) 벡터를 만들 수 있는 방법은 존재한다.
두 벡터로 (3, 5)를 만들어낼 수 있으므로 basis의 역할을 한다. 하지만 두 벡터는 서로 직교하지도 않고, 크기가 1도 아니며 standard 하지도 않다. 즉 위의 두 벡터는 non-orthonormal하며 non-standard한 기저 벡터이다.
또한 다음과 같이 standard 하진 않지만 orthonormal한 기저 벡터일 수도 있다.
좌표를 3차원으로 확장하게 되면 다음과 같다. 아래의 세 개의 벡터는 orthonormal하며 standard한 basis이다. 이러한 세 개의 벡터의 선형결합으로 모든 공간의 벡터를 만들 수 있다. 컴퓨터 그래픽스에선 주로 두 조건을 모두 만족하는 벡터를 기본으로 사용한다. 따라서 두 조건의 특징을 잘 알아두는 것이 좋다.
벡터의 내적(inner product OR dot product)
평면 또는 공간의 영벡터가 아닌 두 벡터 v1, v2가 이루는 각의 크기를 Θ(세타)라고 할 때 ||v1||*||v2||*cosΘ를 v1과 v2의 내적이라 하고 v1ㆍv2로 나타낸다. 내적의 결과는 벡터의 크기와 cos 값을 곱하기 때문에 벡터가 아닌 스칼라이다. 때문에 스칼라곱이라고도 한다. 스칼라는 방향은 고려하지 않고 크기만 고려한다.
위와 같이 두 벡터가 존재할 때 두 벡터의 내적은 다음과 같다.
위 공식에서 ||v2||*cosΘ는 v2의 v1으로의 정사영을 의미한다.
정사영된 부분 중 높이와 직교하는 점을 C라고 했을 때 결국 두 벡터의 내적은 다음과 같이 A 방향으로의 두 힘을 곱한 것이 된다. 결과적으로 내적이란 물리적인 관점에서 한 방향으로 미치는 크기에 관한 연산이다.
여기서 알 수 있는 점은 두 벡터 중 정규화된 벡터가 있다면, 즉 크기가 1인 벡터가 존재한다면 내적의 결과는 그 벡터를 나머지 벡터에 정사영한 결과가 되는 것을 알 수 있다.
한편 cos 그래프에 따르면 세타가 직각일 때 cos의 값은 0이므로 내적의 결과 역시 0이 된다. 이는 두 벡터가 직교하면 힘의 합이 0이 된다는 뜻이다. 세타가 예각일 경우 코사인 값은 양수이므로 결과 역시 양수가 된다. 세타가 둔각(90<세타<180)일 경우 코사인 값은 음수가 된다. 따라서 결과 역시 음수이다.
standard basis vector 의 내적
단위 벡터이자 standard basis인 벡터 e1, e2가 있다고 가정해보자. 만약 같은 벡터끼리의 내적을 수행하면 이루는 각도가 0도가 된다. 단위 벡터의 크기는 1이기 때문에 e1ㆍe1, e2ㆍe2처럼 같은 단위 벡터끼리의 내적은 1이 된다.
같은 벡터가 아닌 두 벡터(e1ㆍe2)를 내적했다고 가정해보자. standard basis인 두 벡터가 이루는 각은 직각이기 때문에 두 벡터의 내적은 0이 된다.
이처럼 standard basis 벡터는 내적에 있어서 배타적인 성질을 가진다.
벡터의 외적(cross product)
내적이 두 벡터에 대해 어떤 방향으로의 힘의 효율(스칼라)을 위한 연산이었다면, 외적은 회전(cross)에 대한 연산이다. 외적은 v1 X v2와 같이 표시하며 v1 cross v2라고 읽는다. 외적은 벡터곱이라고도 한다.
벡터 v1과 v2에 대한 외적은 다음과 같은 공식으로 표현할 수 있다.
위 공식에서 첫 요소만 제외하면 그 결과는 내적과 마찬가지로 스칼라가 된다. 하지만 외적은 여기에 n hat이라는 벡터를 하나 곱해준다. n hat이란 v1과 v2에 수직이면서 크기가 1인 벡터를 의미한다. 즉 orthonormal한 벡터이다.
v1과 v2에 동시에 수직이려면 v1과 v2가 이루는 평면에 수직인 벡터여야 한다. 이처럼 어떤 면에 수직을 이루는 벡터를 법선 벡터(normal vector)라 한다. 추가로 크기가 1이므로 단위 벡터이기도 하다. 이처럼 크기엔 영향이 없지만 스칼라에 방향성을 가지게 해줌으로써 최종적인 결과를 벡터로 만든다. 때문에 외적은 내적과 달리 그 결과가 벡터이다.
한편, 평면에 수직인 벡터는 다음과 같이 양쪽으로 2개가 존재할 수 있다.
두 방향 중 법선 벡터의 방향은 첫 번째 피연산자에 따라 달라진다. 예를 들어 v1 X v2에서 첫 번째 피연산자는 v1이다. 여기에 오른손 법칙을 적용해보면 우선 오른손을 v1 방향으로 뻗는다. 그 다음 v2가 있는 방향으로 손을 감싼다. 그리고 엄지 손가락을 펴면 그 방향이 법선 벡터의 방향이다.
즉 위 그림에서 법선 벡터의 방향은 위쪽 방향이다. v2에서 v1 방향으로 손가락을 접으려면 자연스럽게 엄지손가락이 아래를 향하게 된다. 따라서 v2 X v1 의 경우 법선 벡터의 방향은 아래쪽이 된다. 따라서 외적에 대한 교환법칙은 성립하지 않으므로 주의한다.
외적의 결과 벡터의 길이는 평행사변형의 면적과 동일하다.
한편, 외적의 결과 벡터의 길이는 다음과 같이 v1, v2가 이루는 평행사변형의 면적을 나타내기도 한다. v1과 v2로 이루어지는 평행사변형의 넓이를 크기로 가지는 법선 벡터가 외적의 결과라고 생각해도 좋다. 외적의 결과는 단위 벡터(n)의 실수배로도 표현할 수도 있다. 즉 k*n 이다. 평행사변형의 넓이가 s일 경우 단위 벡터를 s번 더한 s*n이 된다.
두 벡터가 동일한 방향일 경우
외적은 두 벡터가 동일할 때, 즉 두 벡터가 이루는 각이 0도일 때 sin값이 0이 된다. 때문에 이 경우 스칼라값은 0이 된다. 하지만 결과는 벡터이므로 (0,0,0) 또는 영벡터라고 표현한다. 평행사변형의 넓이를 생각해보아도 쉽게 알 수 있다.
좌표계에서 외적의 계산
v1 벡터가 (a1, a2, a3), v2 벡터가 (b1, b2, b3)의 좌표를 가질 때, v1 X v2는 다음과 같이 계산한다. 사실 (아직까지 입문 수준에서) 그래픽스 프로그래밍을 해본 결과 아래와 같은 공식을 직접적으로 사용해본 적은 없다. 주로 두 벡터가 이루는 한 평면에 수직인 노멀을 구하거나, 두 개의 축을 가지고 나머지 축을 구하는 데 사용하는데, 미리 정의된 외적 함수를 사용하면 된다. 공식 외우는 것보다 어떤 상황에 어떻게 활용할 것인지 아는 게 더 중요하다고 생각된다.
점과 벡터의 선형 보간(linear interpolation)
선형 보간이란 두 지점 사이에 위치한 값을 추정하기 위해 일종의 비례식을 사용하여 점의 위치를 계산하는 방법을 말한다. 예를 들어 다음과 같이 A(x1, y1), B(x2, y2)라는 두 점이 있을 때 두 점은 직선을 이룬다. 선형 보간은 LERF라고 부르기도 한다.
위 직선 중에서도 A와 B를 끝 점으로 하는 선분 위의 임의의 점을 구하기 위해 방정식을 푸는 것이 선형 보간이라고 할 수 있다. 위 선분 AB의 길이를 1로 보고 임의의 한 점을 P라고 했을 때 P는 AB를 β와 1-β로 분할한다.
이를 방정식으로 나타내면 다음과 같다.
β의 범위는 당연히 0과 1 사이의 값이여야 한다. β에 0.5를 넣으면 선분 AB의 중간인 A+B/2가 나오는 것을 확인할 수 있다. 위의 좌표를 3차원 좌표라 가정하고 P의 좌표들을 구하면 다음과 같다.
(2차원 좌표는 z좌표를 빼면 됨)
'게임 공부 > Computer graphics' 카테고리의 다른 글
4 - 프래그먼트 처리(Fragment processing) (0) | 2020.08.10 |
---|---|
3 - 래스터화(Rasterization) (5) | 2020.08.07 |
빠른 렌더링을 위한 오브젝트 제외 기술(유영천님 발표) (0) | 2020.08.02 |
2 - 정점 처리(Vertex processing) (1) | 2020.07.24 |
1 - 폴리곤 메쉬(Polygon mesh) (0) | 2020.07.13 |
댓글