새벽동안 꽤나 고생했던 문제이다. 생각보다 해결은 쉽게 되었다.....

제목은 저렇게 거창하게 적혀있지만 실제론 게임에서 자주 사용되는 상황이기에 정리해 보았다.

여기서 잠깐 "나는 삼각비나 삼각함수를 모른다!" 하는 사람은 위키피디아, "삼각함수" 항목을 참고해도 좋다.


이 문제의 조건은 다음과 같다.


1. 점 A와 B가 존재한다. 예를 들어 A는 기준점, B는 가려하는 위치라고 생각해보자. (위치는 가변적이다.)

2. 점 A와 B를 직교선으로 이어 직각 삼각형을 만든다.

3-1. 각도 구하기인 경우 x, y, r(빗변, 피타고라스의 정리로 도출)이 모두 주어지는 상황이다.

3-2. x, y 좌표 구하기인 경우 각도와 r(빗변)이 주어지는 상황이다.


그림으로 나타내면 이런 느낌이라고 할 수 있다.



첫번째 문제인 x, y 좌표를 알 때 각도를 구해보도록 하자.

우선 위의 조건에서 라는 사실을 이미 알고 있다. 그럼 우리가 알아야 하는 값은 θ이다.

tanθ를 아는데 θ값을 구하려면 탄젠트의 역함수를 취하면 된다. 아크탄젠트라고도 한다.

수식으로 나타내면 이렇게 될 것이다. 

사실 수식이 다소 틀렸을 수도 있으나 애교로 봐주면 감사하겠다. 필자는 중학생 때 부터 쭉 수포자이며 수학을 공부한 적이 없다.


아무튼, 이제 우리는 아크탄젠트를 구해야 한다. 이는 math.h를 인클루드했을 시 몇개의 아크탄젠트 함수를 사용할 수 있다.

필자는 여기서 상당히 막혔다. 왜냐면 atan과 atan2의 차이를 몰랐기 때문이다. 애꿎은 삽질 덕분에 해가 뜨는 것을 보았다.(구라까는 거 아니다.)

생각해보면 당연하다. atan은 tanθ값을 넣는다. 나같은 수포자가 있을 것 같아 이해를 돕자면 다음의 두 경우를 생각해 보자.


case 1. x 거리가 -1이고 y 거리가 -1이면 tanθ 값은 1이 된다.

case 2. x 거리가 1이고 y 거리가 1이면 tanθ 값은 1이 된다.

∴ 두 경우 다 같은 각도를 갖는다(사실 좌표계를 배제하면 틀린 말은 아니다)


뭔가 이상하지 않은가!? 나는 이걸 눈치채는 데에 무려 장장 네시간이 걸렸다. 앞서 말했듯이 난 중학생 때 부터 쭉 수포자이다.

그래서 사분면의 위치, 파라미터의 음수값을 고려한 함수가 atan2이다. y 값과 x 값을 파라미터로 갖는 함수이다.

일단 우여곡절 끝에 우리는 atan2 함수의 반환값으로 라디안 값을 얻게 되었다. 이 값에 를 곱해주면 Degree값이 된다.

코드로 나타내면 이런 느낌일 것이다.


 m_fDegree = atan2f( (float)B.y - A.y, (float)B.x - A.x ) * 180 / 3.1415f;


자, 이렇게 우리는 각도를 얻었다!

이제 각도와 빗변을 알 때 x, y의 좌표를 구할 일이 남았다. 이 문제는 코사인과 사인만 있으면 바로 해결된다.

이건 그나마 정말 쉽다. x의 거리 부터 구해보도록 하자.



써놓고 굉장히 뿌듯했다. 딱 봐도 아 그렇군! 싶지 않은가?

특히 1차원적인 사고 및 하나를 알려주면 하나만 아는 필자에게는 굉장히 알아보기 쉬운 수식이다.

"약분해서 r이 떨어지면 x 거리만 남으니까 이렇게 x 거리를 구하겠군!"

같은 원리로 y의 거리를 구하는 것은 다음과 같다.



이러한 원리를 이용하여 앞에서 쓴 코드에 덧붙여보도록 하자.

각도는 자유로 정한다. 단, 파라미터로 들어가는 각도는 라디안임에 주의한다. 빗변의 길이는 10으로 예를 들자.

참고로 코사인과 사인 함수도 math.h에 포함되어 있으니 math.h를 인클루드했는 지 확인하기 바란다.


 m_iXDist = cos( m_fDegree ) * 10;

 m_iYDist = sin( m_fDegree ) * 10;


위의 코드로 얻은 거리 값에 현재 위치 값을 더하면 "특정 각도로 원하는 값 만큼 이동"이 된다!


이러한 각도 구하기 및 좌표 구하기를 적용하는 사례는 다양한 곳에 이용될 수 있다.

FPS 게임에서 마우스 이동으로 카메라를 회전시키는 것도 가능할 것이고, 원하는 각도로 총을 쏘는 것도 가능하다.

딱히 더 할 말이 없으므로 글을 마친다.

+ Recent posts