지우너
[DX12를 이용한 게임 프로그래밍 입문] Part1-Chap1 벡터대수(2) 내적 본문
Chap1. 벡터 대수(2) 내적
아래 글은 Chap1 벡터대수의 1.3 내적의 내용을 담고 있습니다.
[목표]
1. 벡터의 기하학적 표현 방법과 수치적 표현 방법을 배운다.
2. 벡터에 대해 정의되는 연산들과 그 연산들의 기하학적 응용방법을 배운다.
3. DirectXMath 라이브러리의 벡터 관련 함수들과 클래스들에 익숙해진다.
내적(inner product)
점곱(dot product), 스칼라 곱(scalar product)이라고도 부름(벡터연산할 때 스칼라 곱셈이라고 하던 거랑 다른 개념임에 주의할 것!)
결과가 스칼라값(방향이 없고, 크기만 있는 값)
$u=(u_x, u_y, u_z),\, v=(v_x, v_y, v_z)$일 때 내적은 벡터의 각 성분들의 곱들의 합(x끼리, y끼리, z끼리 곱한 값을 더한 것)
$\vec{u}\cdot\vec{v} = u_xv_x+u_yv_y+u_zv_z$
내적의 기하학적 의미
코사인 법칙을 적용하면 아래와 같은 식을 얻을 수 있다.
$\vec{u}\cdot\vec{v} = ||u||\,||v||\,\cos{\theta}$ ($0\leq\theta\leq\pi$)
- 코사인 법칙: 특수각(30, 45, 60, 90, 180)일 경우 세 변의 정보를 알면 세각의 크기를 모두 알 수 있다.
어떻게 코사인 법칙을 적용해서 저 식을 도출한 걸까
내적에 코사인 법칙을 적용해 $\vec{u}\cdot\vec{v} = ||u||\,||v||\,\cos{\theta} = u_xv_x+u_yv_y+u_zv_z$ 증명하기
제가 어렵다고 느꼈던 부분이라 천천히 모든 과정을 다 적었습니다.
$u=(u_x, u_y, u_z),\,v=(v_x, v_y, v_z)$이고, $a=||u||,\,b=||v||,\,c=||u-v||$
$||u||=\sqrt{u_x^2+u_y^2+u_z^2}$ (벡터 크기 구하는 공식)
삼각형의 한 변이 $\vec{v}$, 다른 변이 $\vec{u}$ 라고 했을 때 나머지 한 변은 u의 머리에서 v의 머리로 향하는 벡터 $||u-v||$가 된다 (아래 그림 1.9 참고)
- $c^2=a^2+b^2-2ab\cos{\theta}$ (코사인 법칙)
- $2ab\cos{\theta}=a^2+b^2-c^2$ (1의 양변에 $2ab\cos{\theta}$를 더하고, $c^2$을 빼줌)
- $2\,||u||\,||v||\cos{\theta}= ||u||^2+ ||v||^2-||u-v||^2$ (2에 $a=||u||,\,b=||v||,\,c=||u-v||$ 대입)
- $u-v=(u_x-v_x, u_y-v_y, u_z-v_z),\,||u-v||=\sqrt{(u_x-v_x)^2+(u_y-v_y)^2+ (u_z-v_z)^2}$ (벡터 크기 구하는 공식)
- $2\,||u||\,||v||\cos{\theta}= (\sqrt{u_x^2+u_y^2+u_z^2})^2+(\sqrt{v_x^2+v_y^2+v_z^2})^2-(\sqrt{(u_x-v_x)^2+(u_y-v_y)^2+ (u_z-v_z)^2})^2$ (벡터 크기 공식 대입)
- $2\,||u||\,||v||\cos{\theta}= (u_x^2+u_y^2+u_z^2)+(v_x^2+v_y^2+v_z^2)-((u_x-v_x)^2+(u_y-v_y)^2+ (u_z-v_z)^2)$ (우항의 전체 제곱이랑 루트를 날려줌)
- $2\,||u||\,||v||\cos{\theta}= (u_x^2+u_y^2+u_z^2)+(v_x^2+v_y^2+v_z^2)-(u_x^2-2u_xv_x+v_x^2)-(u_y^2-2u_yv_y+v_y^2)-(u_z^2-2u_zv_z+v_z^2)$ (곱셈공식 $(a-b)^2=a^2-2ab+b^2$)
- $2\,||u||\,||v||\cos{\theta}= (u_x^2+u_y^2+u_z^2)+(v_x^2+v_y^2+v_z^2)-u_x^2+2u_xv_x-v_x^2-u_y^2+2u_yv_y-v_y^2-u_z^2+2u_zv_z-v_z^2$ (-부호 분배해줌)
- $2\,||u||\,||v||\cos{\theta}= 2u_xv_x+2u_yv_y+2u_zv_z$ (단순계산)
- $2\,||u||\,||v||\cos{\theta}= 2(u_xv_x+u_yv_y+u_zv_z)$ (우변을 2로 묶어줌)
- $||u||\,||v||\cos{\theta}= (u_xv_x+u_yv_y+u_zv_z)$ (양변을 2로 나눔)
- 따라서, $u_xv_x+u_yv_y+u_zv_z = ||u||\,||v||\,\cos{\theta}$
두 벡터 u, v가 모두 단위벡터일 때, $\vec{u}\cdot\vec{v}=\cos{\theta}$ 이다
(단위벡터의 크기는 1이기 때문에 $1*1*\cos{\theta}=\cos{\theta}$)
- $\vec{u}\cdot\vec{v} =0$이면 $u\perp v$(두 벡터는 직교=직각으로 만남)
- $\vec{u}\cdot\vec{v} > 0$이면 두 벡터 사이의 각도 $\theta$는 90도 보다 작다.
- $\vec{u}\cdot\vec{v} < 0$이면 두 벡터 사이의 각도 $\theta$는 90도 보다 크다.
아래 코사인 함수 그래프를 보면, (360°가 $2\pi$이므로 $\frac{\pi}{2}=90°$)
즉, $\cos{0°}=1,\,\cos{90°}=0,\,\cos{180°}=-1$이다.
$\cos{90°}=0$이기 때문에 1*1*0=0이 돼서 내적했을 때 0이 나오면 직교 (1성립)
$\theta<90°$라는 것은 다시 말해 $\cos{0°}~\cos{90°}$라는 의미이다.
$\cos{0°}=1, \cos{90°}=0$ 따라서 $\theta<90°$은 양수가 된다. 1*1*(양수)>0 (2 성립)
$\theta>90°$라는 것은 다시 말해 $\cos{90°}~\cos{180°}$라는 의미이다.
(삼각형은 세각의 합이 180°여야 하기 때문에 두 벡터 사이의 각은 180을 넘을 수 없다)
$\cos{90°}=0, \cos{180°}=-1$ 따라서 $\theta<90°$은 음수가 된다. 1*1*(음수)<0 (3 성립)
직교투영과 직교화
두 개념에 대해서는 나중에 추가하겠다. (최대한 쉽고 자세히 정리하려다 보니 정리에 시간이 너무 많이 걸린다)
일단은 아래 두 가지만 알아 두자!
정규직교: 벡터 집합의 모든 벡터가 단위길이(=길이가 1)이고, 서로 직교(직각으로 만남)
직교화: 벡터 집합을 정규직교벡터 집합으로 만드는 것
혹시 이 부분이 궁금하실 분이 있을까 하여 필기노트를 따로 첨부합니다:)
관련 사이트
'Programming > DirectX' 카테고리의 다른 글
[DX12를 이용한 게임 프로그래밍 입문] Part1-Chap1 벡터대수(1) (0) | 2024.05.31 |
---|