벡터를 각도로 변환: 아크탄젠트(2D추천)

2023. 7. 18. 23:02Public/Math

벡터가 주어졌을 때 이 벡터를 각도로 변환하려 한다. 탄젠트(tangent) 함수가 각도를 인자로 받고 삼각형의 밑변과 높이의 비율값을 반환했던 걸 떠올리자.

 

이제 액터의 새로운 전방 벡터로부터 회전 멤버 변수에 해당하는 각도를 구한다고 가정해본다. 이 경우에는 그림 3.7처럼 새로운 전방 벡터 v와 x축으로 직각 삼각형을 구성하면 된다. 이 삼각형에서 전방 벡터의 x요소는 삼각형의 밑변의 길이다. 그리고 전방 벡터의 y요소는 삼각형 높이다. 이 요소들의 비율값을 이용하면 아크 탄젠트 함수를 사용해서 각도 세타를 계산하는 것이 가능하다.

 

프로그래밍에서 선호되는 아크탄젠트 함수는 atan2함수다. 이 함수는 파라미터로 2개의 인자를 받는다.(삼각형의 높이와 밑변의 길이) 그리고 [- π, π] 범위의 각도를 리턴한다. 양의 각도는 삼각형이 1사분면이나 2사분면에 있고(양의 y값), 음의 각도는 삼각형이 3사분면이나 4사분면에 있다는 걸 뜻한다.

예를 들어 우주선이 운석을 바라본다고 가정하자. 먼저 우줏너에서 운석이 향하는 벡터를 만들고 이 벡터를 정규화해야 한다. 다음으로 atan2 함수를 사용해서 새로운 전방 벡터를 각도로 변환한다. 마지막으로 우주선 액터의 회전값을 이 새로운 각도로 설정한다.

SDL 2D 좌표 시스템에서는 +y가 아래를 향하므로 y값을 반전해야 한다는걸 잊지 말자. 지금까지 설명한 코드의 내용은 다음과 같다.

//(우주선과 운석은 액터다)
Vector2 shipToAsteroid = asteroid->GetPosition() - ship->GetPosition();
shipToAsteroid.Normalize();
//새 전방 벡터를 atan2 함수를 사용해서 각도로 변환한다 (SDL을 위해 y값을 반전시킨다)
float angle = Math::Atan2(-shipToAsteroid.y,shipToAsteroid.x);
ship->SetRotation(angle);

 

아크탄젠트 함수의 사용은 2D 게임에서 매우 잘 동작한다. 하지만 이 아크탄젠트 함수는 모든 물체가 x-y 평면에 존재하는 2D 게임과 같은 경우에만 동작한다. 3D 게임에서는 다음 절에서 설명할 내적을 통한 접근법을 사용하는 것이 좋다.