목표
- Vector에 대해 이해한다.
Vector란 무엇인가?
벡터의 정의
- Vector란 방향과 크기를 나타내는 수학적 도구이다.
공간의 정의
- 1차원 : 한 축으로 표시되며, 수직 선상에 표시된다.
- 2차원 : x,y 축으로 표시되며, 2차원 공간에 표시된다.
- 3차원 : x,y,z 축으로 표시되며, 3차원 공간에 표시된다.
Unity에서 좌표계
2차원
- 2차원 좌표계는 왼쪽 아래를 (0,0)으로 위와, 오른쪽이 양(+)의 방향인 데카르트 좌표계와
- 왼쪽 상단이 (0,0)으로 아래와 오른족이 양(+)의 방향인 직교 좌표계가 있다.
- 또는 평면 위의 위치를 각도와 거리로 표시하는 극 좌표계가 존재한다.
- Unity의 경우, 2차원에서 데카르트 좌표계를 사용한다.
3차원
- 일반적으로 수학이나 OpenGL 등에서는 3차원을 표현할때 오른손 좌표계가 사용된다.
- 또는 원통형 좌표계와 구면 좌표계가 존재한다.
- 왼손 좌표계는 x가 오른쪽, y가 위쪽, z가 앞쭉을 향하는 좌표계를 말한다.
- Unity의 경우, 3차원에서 왼손 좌표계가 사용된다.
벡터의 성분
- 벡터를 해석적인 식으로 표현하면 V = [V1, V2, ..Vn] 과 같이 표현할 수 있다.
- 벡터의 성분은 V1, V2, .. Vn을 말한다.
벡터의 표현 방식
-
괄호 표기법 (comma-delimited)
$\mathbf{v}=\begin{pmatrix}
v_1, \
v_2, \
... \
v_n \end{pmatrix}$ -
행 백터 (row-verctor)
$\mathbf{v}=\begin{bmatrix}
v_1, \
v_2, \
... \
v_n \end{bmatrix}$ -
열 백터 (column-vector)
$\mathbf{v}=\left[\begin{array}{r}
v_1 \\
v_2 \\
\vdots \\
v_n \\
\end{array}\right]$
위치 벡터
- 유클리드공간에서 좌표의 원점 O를 시작으로, 공간 내의 임의의 한점 P를 끝 점으로 하는 벡터를 말한다.
동등 벡터
- 기준이 되는 벡터와 크기와 방향이 같은 경우 동등 벡터라 한다.
- 벡터란 애초에 크가와 방향 정보만 가지기 때문에 같음을 표시하는데 시작지점은 상관 없다.
벡터의 종류
자유 벡터 (Free Vector)
- 위치에 상관없이 크키와 방향이 같은 벡터
이동 벡터 (Sliding Vector)
- 직전 상에서만 움직일 수 있는 벡터
고정 벡터 (Fixed Vector)
- 위치, 크기, 방향이 변하지 않는 벡터
벡터의 크기
$\mathbf{v}=\left[\begin{array}{r}
v_x \\
v_y \\
\end{array}\right]$ 가 존재할 때,
$||V||$는 $\sqrt{V_x^2+V_y^2}$ 이다. ($||V||$는 벡터의 크기를 나타내는 기호이며 노옴(Norm)이라 한다.)
$\sqrt{\sum_{k=1}^{N}V_k^2}$는 유클리드 노옴으로 최단거리를 구하는 방식이다.
x-y-z 3차원 좌표계에서 벡터의 크기는 $||V||$는 $\sqrt{V_x^2+V_y^2+V_z^2}$ 이다.
단위 벡터
단위벡터는 크기가 1인 벡터를 말한다. U가 단위 백터라고 한다면 다음과 같이 표현할 수 있다.
$\sqrt{U_x^2+U_y^2}=1$
크키가 1인 벡터는 방향만 가리키는데 사용되며, 광원의 방향, 평면의 법선 방향, 카메라 방향 등에 사용된다.
이때, 크기를 가진 벡터를 단위 벡터로 만들어 주는 과정을 정규화(Normalization)이라고 하며, 벡터를 자신의 크기로 나줘줌으로써 단위벡터를 구할 수 있다.
$U=\frac{V}{||V||}$ = $\frac{1}{\sqrt{V_x^2+V_y^2}}V$
벡터 연산
벡터 덧셈
벡터의 덧셈은 다음과 같이 표현될 수 있다.
$\mathbf{A + B}=\begin{bmatrix}
A_1 + B_2, \
A_2 + B_2, \
... \
A_n + B_n \end{bmatrix}$
성분으로 표시했을 경우 다음과 같다.
$\mathbf{A}=\begin{bmatrix} 5, \ 4\end{bmatrix}$ 이고 $\mathbf{B}=\begin{bmatrix} 3, \ 3\end{bmatrix}$ 일때
$\mathbf{A + B}=\begin{bmatrix}
5 + 4, \
3 + 3 \
\end{bmatrix} = \begin{bmatrix} 9 ,\ 6\end{bmatrix}$
벡터 뺄셈
벡터의 덧셈은 다음과 같이 표현될 수 있다.
$\mathbf{A - B}=\begin{bmatrix}
A_1 - B_2, \
A_2 - B_2, \
... \
A_n - B_n \end{bmatrix}$
성분으로 표시했을 경우 다음과 같다.
$\mathbf{A}=\begin{bmatrix} 5, \ 4\end{bmatrix}$ 이고 $\mathbf{B}=\begin{bmatrix} 3, \ 3\end{bmatrix}$ 일때
$\mathbf{A - B}=\begin{bmatrix}
5 - 4, \
3 - 3 \
\end{bmatrix} = \begin{bmatrix} 1 ,\ 0\end{bmatrix}$
벡터와 스칼라와의 곱
스칼라 : 스칼라는 크기만 가지고 방향은 가지지 않는 양을 말한다.
벡터와 스칼라 곱은 벡터의 크기에 스칼라를 곱해주는 것으로, 스칼라 k와 벡터 V를 곱한 성분을 표시하면 아래와 같다.
$kV = Vk = \begin{bmatrix}
kV_1, \
kV_2 \
... \
kV_n \
\end{bmatrix}$
벡터의 연산법칙
다음은 일반적인 벡터의 연산법칙에 대해 알아보자.
각각 A,B,C는 벡터이고, $n,m$은 스칼라이다.
- $A+B = B+A$ (교환법칙)
- $(A+B)+C = A+(B+C)$ (결합 법칙)
- $A+0=0+A=A$
- $A + (-A) = 0$
- $(n+m)A = nA + mA$ (분배 법칙)
- $n(A+B) = nA + nB$
- $(nm)A = n(mA)$
- $1A = A$
- $0A = 0$
- $n0 = 0$
- $(-1)A = -A$
벡터의 내적
- 내적의 내적은 두 벡터의 사잇각을 구하는데 사용된다.
- 내적의 결과는 스칼라이다.
- 벡터의 내적은 스칼라곱(scalar product) 또는 점곱(inner product)라 불린다.
시점이 일치하는 두 벡터 A,B가 주어지고 두 벡터의 사잇각이 $\theta(0^o \le \theta \le 180^o)$ 일때
A와 B의 내적은 $A \cdot B = ||A|| ||B|| cos\theta$ 이다.
내적 연산법칙
- $A \cdot B = B \cdot A$
- $(kA)\cdot B = A \cdot (kB) = k(A \cdot B)$
- $A \cdot (B+C) = A \cdot B + A \cdot C$
- $0 \cdot A = A \cdot 0 = 0$
위 식을 이용하여 x,y,z 성분을 가지고 있는 두 백터의 내적을 구해보면 아래와 같이 표현할 수 있다.
$cos\theta = \frac{A \cdot B}{||A||||B||} = \frac{A_xB_x+A_yB_y+A_zB_z}{(\sqrt{A_x^2+A_y^2+A_z^2})(\sqrt{B_x^2+B_y^2+B_z^2})}$
이때, 벡터의 연산법칙을 이용하여 $theta$를 구할 수 있다.
$\theta = cos^-1\frac{A \cdot B}{||A||||B||}$
라디안(radian)과 디그리(degree)
- 우리가 일반적으로 생각하는 각도는, 디그리이다.
- 디그리는 원 한바퀴를 360도로 표현하는 방법이다.
- 라디안은 호의 길이와 반지름의 길이가 같은 부채꼴의 중심각을 1로 표현하는 방법이다.
- 위와 같이 디그리를 이용하여 각을 측정하는 방식을 각도법, 라디안을 이용하여 각을 측정하는 방식을 호도법이라 한다.
내적의 결과를 각도로 변환하기
-
내적의 결과는 스칼라이지만, $acos(\theta)$의 결과는 라디안이다.
-
라디안을 각으로 변환하는 공식은 다음과 같다.
$degree = \theta * 180 / PI$ -
$acos(-1) ~ acos(1)$을 라디안으로 표시하면 0 ~ $\pi$를 의미한다.
- acos(-1) = $0^o$
- acos(0) = $90^o$
- acos(1) = $180^o$
-
내적만으로는 $\theta(0^o \le \theta \le 180^o)$도 사이의 결과만 구할 수 있다.
-
사잇각이 $\theta(0^o \le \theta \le 360^o)$도인 경우를 측정하기 위해서는, 외적의 z 성분을 이용해야 한다.
-
z 성분을 구하는 방법은, 아래 백터의 외적 부분을 참고한다.
벡터의 외적
- 벡터의 외적은 두 벡터에 모두 수직한 벡터를 결과값으로 갖는다.
- 백터의 외적은 주로 $A \times B$로 표기된다.
- 백터의 외적은 교환법칙이 적용되지 않음으로, 순서에 주의한다.
벡터의 외적을 구할 때는 다음과 같은 공식이 사용된다.
$A \times B = (||A||||B||sin\theta)E$
$=\begin{bmatrix}
A_yB_z - A_zB_y, \
A_zB_x - A_xB_z, \
A_xB_y - A_yB_x \end{bmatrix}$
외적 연산법칙
- $A \times B = -B \times A$
- $A \times (B+C) = (A \times B) + (A \times C)$
- $(A+B) \times C = (A \times C) +(B \times C)$
- $k(A \times B) = (kA) \times B = A \times (kB)$
- $A \times 0 = 0 \times A = 0$
- $A \times A = 0$
360도 범위에서 내적 표현하기
- 360도에서 내적을 표현하기 위해서는 다음과 같은 방법을 사용한다.
- 사잇각을 구한다. (내적에서 호도법 변환까지)
- 두 벡터의 외적을 구한다.
- 외적 결과와 Up Vector(0,1,0)의 내적을 구한다.
- 내적의 결과가 0보다 작다면, 360 - $\theta$를 해준다.
- $\theta$의 결과가 360보다 크거나 같다면, -360을 해준다.
벡터 클래스
- 아래 예제 CVector에는 백터의 크기, 단위백터, 내적, 외적을 구하는 기능을 구현하였다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 3차원 Vector를 구현해 본다.
public class CVector
{
public static float GetLength(Vector3 v3)
{
//return v3.magnitude
return Sqrt(Pow(v3.x) + Pow(v3.y) + Pow(v3.z));
}
public static Vector3 GetNormalize(Vector3 v3)
{
//return v3.normalized
float lenght = GetLength(v3);
return new Vector3(
v3.x / lenght,
v3.y / lenght,
v3.z / lenght);
}
public static float Sqrt(float val)
{
// Mathf.Sqrt(val)
float root = 2;
for (int i = 0; i < 20; i++)
{
root = (root + (val / root)) / 2;
}
return root;
}
public static float Pow(float val)
{
// Mathf.Pow(val,2)
return val * val;
}
public static float GetContAngle(Vector3 form, Vector3 to, Vector up)
{
float angle = GetAngle(form, to);
Vector3 cross = GetCross(form, to);
if (GetDot(cross, up) < 0.0f)
{
angle -= 360.0f;
if (angle >= 360.0f)
{
angle -= 360.0f;
}
}
return angle;
}
public static float GetAngle(Vector3 form, Vector3 to)
{
// Vector3.Angle
float theta = GetDot(form, to);
float radian = Mathf.Acos(theta);
radian *= 180.0f / Mathf.PI;
return radian;
}
public static float GetDot(Vector3 form, Vector3 to)
{
// Vector3.Dot
float scalra = ((form.x * to.x) + (form.y * to.y) + (form.z * to.z));
float length = form.magnitude * to.magnitude;
return scalra / length;
}
public static Vector3 GetCross(Vector3 form, Vector3 to)
{
float x = (form.y * to.z) - (form.z * to.y);
float y = (form.z * to.x) - (form.x * to.z);
float z = (form.x * to.y) - (form.y * to.x);
return new Vector3(x,y,z);
}
}
Unity에서 Vector 함수
- Vector.magnitude : AB벡터의 길이를 반환한다.
- Vector.Dot : AB가 이루는 각을 반환한다.
- Vector.Cross : A와도 수직이고, B와도 수직인 선을 반환한다.
- Vector.Angle : A 와 B 사잇각을 degree로 반환한다.
수학적 이해
- 벡터에 대한 상세 내용은 khanacademy를 참고한다.