[C++] 3.2.2 두 공의 충돌 : 벡터 내적
카테고리: C++ games
인프런에 있는 홍정모 교수님의 홍정모의 게임 만들기 연습 문제 패키지 강의를 듣고 정리한 필기입니다.😀
🌜 공부에 사용된 홍정모 교수님의 코드들 보러가기
🌜 [홍정모의 게임 만들기 연습 문제 패키지] 강의 들으러 가기!
Chapter 3. 게임 물리 맛보기 : 공 두 개를 충돌시켜보자
벡터, 상대 속도 등등, 해당 강의에서 다루었던 물리학적 개념들이 문과생인 나에겐 생소하고 잘 와닿지 않았던 개념이라 강의를 필기하기에 앞서 개인적으로 따로 공부하여 정리해보았다.
벡터 내적
🔔 벡터의 스칼라 곱
\[\vec{A} = k\vec{B}\]
- \(\vec{A}\) 벡터와 \(\vec{B}\) 벡터는 방향이 같다.
- \(\vec{A}\) 벡터의 크기는 \(\vec{B}\) 벡터의 크기의 \(k\)배가 된다.
🔔 벡터 내적 (Dot Product)
벡터 내적의 기하학적 원리
벡터 내적
: 두 벡터의 곱하기 정의 중 하나로 (다른 하나로는 외적 이 있다) 벡터를 마치 수처럼 곱하는 개념이다. 따라서 결과 값도 스칼라 값이다.
\(\vec{A}\cdot\vec{B}\) A dot B 라고 부른다.
그림 속에서 상자를 끌고자 하는 수평 방향가진 벡터를 메인 벡터
라고 하고 수지가 상자를 해당 방향으로 이동 시키기 위해 상자를 끌며 힘을 주는 방향을 가진 벡터를 서브 벡터
라고 대충 칭해 보자. 수지가 주는 힘인 서브 벡터가 메인 벡터에 도움을 주는 정도(스칼라)와 메인 벡터의 크기(스칼라)를 곱하면 이게 바로 두 벡터의 내적 값이 된다. 둘 중 어느 벡터를 메인 벡터로 삼든 그건 상관 없다. 물리학적으로 '일'을 한 정도를 내적으로 표현한다. \(W = \vec{F}\cdot\vec{S}\)
- 스칼라끼리 곱은 그냥 2 곱하기 3은 6 하면 그만이지만 벡터는 크기와 더불어
방향
이 있기 때문에 곱을 해주기 위해선 두 벡터 중 하나를 다른 한 벡터에 정사영시켜 두 벡터의 방향을 일치시켜 준다. - \[벡터 내적 = \vec{A}\cdot\vec{B} = \vert\vec{A}\vert×\vert\vec{B}\vert×\cos\theta\]
- 메인 벡터를 \(\vec{A}\)라고 하면 (둘 중 뭐를 메인 벡터로 생각할지는 상관 없다.) 메인 벡터의 크기는 \(\vert\vec{A}\vert\) 가 되고
- \(\vert\vec{B}\vert×\cos\theta\)는 메인 벡터인 \(\vec{A}\)에 도움 혹은 영향을 끼친
정도(양)
을 의미한다.- \vec{B}를 vec{A}에 정사영 했을 때의 길이
- 이 두 개의 곱은 두 벡터의 내적값이 된다.
벡터의 공식
- 기하학
- \[\vec{A}\cdot\vec{B} = \vert\vec{A}\vert×\vert\vec{B}\vert×\cos\theta\]
- 대수학(프로그래밍)
- \[\vec{A}\cdot\vec{B} = x_A{\cdot}x_B + y_A{\cdot}y_B \]
- 두 벡터의 각 성분끼리 곱하고 더해준다.
- 프로그래밍 할 때 벡터의 내적 값은 주로 이 공식으로 구한다.
- 증명은 이 블로그의 포스트 참고
벡터 내적 Case by Case
\[벡터 내적 = \vec{A}\cdot\vec{B} = \vert\vec{A}\vert×\vert\vec{B}\vert×\cos\theta\]
- \(\vert\vec{A}\vert\) 와 \(\vert\vec{B}\vert\)는 양수이므로 \(\cos\theta\)의 부호에 달려 있다.
- 두 벡터의 내적 값이
양수
- \(\cos\theta\) > 0
- 0 ~ 90도
- 270 ~ 360도 - 두 벡터의 방향이 예각을 이룬다.
- 즉 서브벡터가 메인벡터에게 도움이 되는 영향을 주고 있다.
- 상자를 움직여야 하는 방향으로 열심히 상자를 끌고 있는 경우와 비슷
- 상자를 끄는 힘과 상자를 움직여야하는 힘의 각도가 예각
- 두 벡터의 내적 값이
0
- \(\cos\theta\) = 0
- 90도 - 두 벡터의 방향이 직각을 이룬다.
- 즉 서브벡터가 메인벡터에게 도움을 주는 영향이든 악영향이든 어떤 영향도 주고 있지 않다.
- 상자를 움직여야 하는데도 불구하고 그냥 상자를 들고 가만히 서 있는 것과 마찬가지.
- 상자를 끄는 힘(전혀 끌지 않고 들고 서있음)과 상자를 움직여야하는 힘의 각도가 직각
- 두 벡터의 내적 값이
음수
- \(\cos\theta\) < 0
- 90 ~ 270도 - 두 벡터의 방향이 둔각을 이룬다.
- 즉 서브벡터가 메인벡터에게 반대로 악영향을 주고 있다.
- 상자를 움직여야 하는 방향과 반대 방향으로 상자를 끌면서 방해하는 것에 비유할 수 있다.
- 상자를 끄는 힘과 상자를 움직여야하는 힘의 각도가 둔각
방향이 같은 벡터끼리의 내적
- 방향이 같다는건 평행하다는 것이기 때문에 두 벡터의 사이각이 0도라는 것이다.
- \(\theta = 0\)이면 \(\cos\theta = 1\)이 되어
- 두 벡터의 내적 값은 \(\vert\vec{A}\vert\cdot\vert\vec{B}\vert\) 이다.
- 크기까지 같아 아예 같은 벡터끼리의 내적은 \(\vec{A}\cdot\vec{A} = \vert\vec{A}\vert^2\)
- 단위 벡터이자 같은 벡터끼리의 내적 값은 \(\vec{n}\cdot\vec{n} = 1\)이 된다.
벡터 내적의 쓰임새 in 게임프로그래밍
벡터 내적을 사용하는 예
- 두 벡터의 사이각 구하기
- 벡터 내적 공식을 이용하여 아래와 같이 구하면 된다.
- \[\theta = \arccos{\vec{A}\cdot\vec{B}\over\vert\vec{A}\vert\vert\vec{B}\vert}\]
- 적이 플레이어의 앞에 있는지 뒤에 있는지 판별
- 벡터 A = 적과 플레이어의 거리.
- 적의 위치벡터 - 플레이어의 위치벡터 - 벡터 F = 플레이어의 정면 수직 방향 벡터
- \(\vec{F}\cdot\vec{A}\)
- 내적값이 양수면 F와 A가 예각.
- 적이 플레이어의 앞에 있음.
- 내적값이 음수면 F와 A가 둔각.
- 적이 플레이어의 뒤에 있음.
- 적이 뒤에 있는 경우 렌더링 할 필요가 없음.
- 내적값이 양수면 F와 A가 예각.
- 적이 주인공의 시야에 있는지 판별
- 주인공의 시야 각을 \(\theta\) 라고 한다면
- F 벡터와 벡터 A가의 내적으로 나오는 각도가 \(\theta/2\) 를 넘지 않아야 적이 시야 내에 존재.
- 플레이어의 시야 내에 없는 적은 렌더링 할 필요가 없다.
- 카메라가 보는 방향과 화면의 방향이 서로 직교(내적값 = 0)하면 2D처럼 볼 수 있다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기