두 벡터 사이의 각도 구하기: 내적

2023. 7. 22. 16:40Public/Math

두 벡터 사이의 내적(dot product)결과는 단일 스칼라 값이다. 게임에서 내적을 사용하는 가장 일반적인 경우는 두 벡터 사이의 각도를 찾는 것이다.

내가 정리한 벡터정리글

 

벡터의 크기(길이)는 이중 수직선으로 표기한다. 예를 들어 u의 크기 ||u||

다음 방정식은 벡터 a와 b의 내적을 계산한다.

또한 내적은 각의 코사인(cosine)과 관계가 있다. 그래서 두 벡터 사이의 각도는 다음과 같이 표현할 수 있다.

그림 3.8에 나와 있는 공식은 코사인 법칙을 토대로 한 것이다. 이 공식을 사용하면 세타를 구할 수 있다.

두 벡터 a,b가 단위 벡터라면 각 벡터의 길이가 1이므로 분모를 생략할 수 있다.

단위 벡터를 사용했으므로 식이 단순해졌는데, 방향만이 중요하다면 미리 벡터를 정규화해두는 것이 좋다.

그림 3.8

예를 들어 전방 벡터 f를 가진 위치 p에 있는 플레이어를 생각해보자. 새로운 적이 위치 e에 나타난다. 기존 전방 벡터와 p에서 e로의 벡터 사이의 각도를 구해볼 것이다.

p에서 e로의 벡터 v는 다음과 같다.

그리고 이번 경우에는 방향만이 중요하므로 v를 정규화한다.

마지막으로 f와 v사이의 각도를 결정하고자 내적 공식을 사용한다.

두 벡터 사이의 각도를 계산할 시 내적에서 발생할 수 있는 몇 가지 특별한 경우를 기억해두면 좋다. 두 단위 벡터 사이의 내적이 0이면 두 벡터가 수직한다는 것을 뜻한다. 왜냐하면 cos(pai/2) = 0이기 때문이다. 또한 내적값이 1이라면 두 벡터는 평행해서 같은 방향을 향하고 있다는 걸 뜻한다. 마지막으로 -1은 두 벡터가 서로 평행하지만 반대 방향(antiparallel)으로 향하고 있다는 걸 의미한다.

각도를 계산하기 위해 내적을 사용할 경우 한 가지 결점은 아크코사인(arccosine)이 [0,pai] 범위에서 각도를 반환한다는 것이다. 이 때문에 아크코사인은 두 벡터 사이의 최소회전값을 주지만 이 회전값이 시계 방향인지 아니면 반시계 방향인지는 알 수 없다.

두 실수 사이의 곱셈처럼 내적도 덧셈과 결합에 대해서는 교환,분배 법칙이 가능하다.

또 다른 유용한 팁으로 벡터 그자체의 내적은 길이 제곱값과 같다는 걸 들 수 있다.

Math.h 라이브러리는 Vector2와 Vector3에 대한 Dot 정적 함수를 정의했다. 예를 들어 oriForward와 newForward 사이의 각도를 구하려면 다음과 같이 사용하자.

float dotResult = Vector2::Dot(origForward,newForward);
float angle = Math::Acos(dotResult);