게임에서 atan과 atan2는 무엇입니까?


47

나는 몇 가지 문제를 이해하는 데 Math.tan()Math.atan()Math.atan2().

나는 삼각법에 대한 기본 지식을 가지고 있지만 게임 개발에 SIN, COS 및 TAN 등의 사용법은 매우 새롭습니다.

일부 자습서를 읽고 있는데 접선을 사용하면 마우스와 같은 다른 객체를 얼마나 많이 마주보고 있는지에 따라 한 객체를 회전 해야하는 각도를 얻을 수 있음을 알 수 있습니다. 그렇다면 왜 여전히 atan 또는 atan2를 사용해야합니까?


아탄은 각도를 결정하는 데 사용되며 수천 가지 다른 물건에 유용합니다. 사용에 대한 실제 질문이 있거나 일반적인 수학 도움을 찾고 있습니까?
BlueRaja-대니 Pflughoeft

5
해당 기능의 수학 / 형상을 반드시 이해해야합니다. 일단 당신이 그들을 마스터하면, 그들은 당신이 매일 사용하는 기본 문법과 같은 "세계 이해"의 일부가 될 것입니다. 일단 "수학 / 형상"을 말할 수 있다면, 그 기능들이 가장 자연스럽게 사용되는 결과를 얻기위한 간단한 도구라는 것을 알게 될 것입니다.
FxIII

해당 튜토리얼이 잘못되었거나 오해되었습니다. atan2 ()를 사용하여 한 객체에서 다른 객체로 각도를 가져옵니다. 작동 방식은 다음과 같습니다.
jhocking

답변에 대한 감사의 사람들은, 지금은 수업 시간에 더 많은 관심을 지불하지 후회 메신저
sutoL

답변:


93

탄젠트 공식은 다음과 같습니다.

tan(angle) = opposite/adjacent

이 도면을 참조하십시오.

직각 삼각형의 다이어그램, 각도 세타 및 그 반대면과 인접면이 표시됨

a인접한 쪽은 어디에 o있고 반대쪽 theta은 각도입니다. 마찬가지로 사인과 코사인은 sin (ang) = o / h 및 cos (ang) = a / h이며, 긴면 h은 다음과 같습니다. http://www.mathwords.com/s/sohcahtoa.htm

한편 atan(짧은 아크 탄젠트 일컬어, 역 탄젠트 )의 역순 tan이므로 등 :

atan(opposite/adjacent) = angle

따라서 반대면과 인접한면의 값을 모두 알고 있다면 (예를 들어, 마우스 좌표에서 객체의 좌표를 빼서)를 사용하여 각도의 값을 얻을 수 있습니다 atan.

그러나 게임 개발에서 인접면이 0과 같은 경우가 종종 발생할 수 있습니다 (예 : 벡터의 x 좌표는 0 임). tan(angle) = opposite/adjacent비참한 0으로 나누기 오류가 발생할 가능성을 명심 해야합니다. 따라서 많은 라이브러리는이라는 함수를 제공합니다.이 함수는 매개 변수 와 매개 변수를 atan2모두 지정 하여 0으로 나누기를 피하고 오른쪽 사분면에 각도를 제공합니다.xy

atan2 다이어그램

(가레스의 그림 제공, 그의 답변도 투표하십시오)


게임 개발에 삼각법을 사용하는 것은 특히 벡터에서 일반적이지만 라이브러리는 삼각법 작업을 숨 깁니다. sin / cos / tan을 사용하여 삼각형에서 값을 찾기위한 기하학적 조작과 관련된 많은 작업에 사용할 수 있습니다. 직사각형 삼각형의 다른 값을 찾으려면 3 개의 값 (측면 길이 / 각도 값)이 필요하므로 매우 유용합니다.

사인 및 코사인 함수의 "사이클링"특성을 게임의 특수 동작에 사용할 수도 있습니다. 예를 들어, cos / sin이 다른 오브젝트를 돌리기 위해 오브젝트를 많이 사용하는 것을 보았습니다.


8
그것은 가치가 주목 위키 백과 설명이다 ATAN2에 대한 다른 용도를 ( 하지 만 0으로 분할을 피하는보다 ATAN). 예를 들어, 사용중인 사분면에 맞게 자체적으로 수정되며 일반적으로 모든 작업을 직접 수행해야합니다.
doppelgreener

실제로, 매우 중요한 메모입니다. 내 답변을 업데이트합니다.
Jesse Emond

첫 번째 긴 단락에서 황갈색과 아탄을 얻지 못했습니까? atan을 사용하여 각도를 구하고 (즉, 방정식을 뒤집 음) tan를 사용하여 변의 비율을 구합니다 (예 : 정확히 방정식의 말).
jhocking

o / a가 3과 같다는 것을 알고 있다면 atan (3)으로 각도를 원한다면 이것이 의미하는 바입니다. 각도를 분리하려면 비율에 atan을 사용하십시오. 비율을 분리하려면 각도에 ​​tan을 사용하십시오.
Jesse Emond

나는 당신이 반대를 말하는 것처럼 들리기 때문에 당신의 표현을 바꿀 것입니다.
jhocking

63

여기에 이미지 설명을 입력하십시오


1
이 다이어그램을 포함하도록 최상위 답변을 편집하는 것이 무례합니까? 이 다이어그램은 훌륭하며 Jesse의 atan2 ()에 대한 설명 직후에 적합합니다.
jhocking

1
내 손님이 되세요! 완료되면이 답변을 삭제하겠습니다.
Gareth Rees

7
아니 아니. 유지하십시오! 그것은 인정되고 사람들은 여전히 ​​다이어그램에 대해 찬성해야합니다.
Jesse Emond

12

atan () 및 atan2 ()를 포함하여 trig 함수에 대해 생각하는 약간 다른 방법이 있습니다. "상대 / 인접"에 대한 설명은 어떤 이유로 나를 혼동합니다.

x, y, r, 세타

사용자는 이동 한 지점에서 다른 지점으로 얻을 수있는 X의 수평 부와 Y 부 수직 (불리는 직사각형 또는 데카르트 좌표) 또는 거리 이동하여 R을 각도 Ɵ (불리는 극성 차원 좌표)를.

극좌표 (r, Ɵ)가 있고 (x, y)로 변환하려고한다고 가정 해 봅시다.

cos (Ɵ)는 x 축을 따라있는 r 의 비율을 제공합니다 .

  • 만일 R = 1 다음, X = COS (Ɵ).
  • 만일 R = 100 후 X = 100 * COS (Ɵ).
  • 일반적으로 x = r * cos (Ɵ).

마찬가지로 sin (Ɵ)은 y 축을 따라있는 r 의 비율을 제공합니다 .

  • 만일 R = 1 다음, Y = 죄 (Ɵ).
  • 만일 R = 100 다음, Y = 100 * 죄 (Ɵ).
  • 일반적으로 y = r * sin (Ɵ).

직사각형 좌표 (x, y)를 극좌표 (r, Ɵ)로 변환하는 것은 어떻습니까?

rxy로 형성된 직각 삼각형의 빗변 이므로,

  • r = sqrt (x x + y y)

tan (Ɵ)는 길이가 r 인 선의 기울기를 나타 냅니다. 그래서:

  • tan (Ɵ) = y / x
  • Ɵ = 아탄 (y / x)

그러나 y / x를 수행 할 때 3/4를 계산하면 -3 / -4를 계산하는 것과 동일한 대답이 제공됩니다. 마찬가지로 -3/4는 3 / -4와 같은 대답을 제공합니다. 따라서 개별 부호를 올바르게 처리하고 0으로 나누기 / 무한대 오류를 방지하는 atan2 (y, x)가 있습니다.

  • Ɵ = atan2 (y, x)

4

제시와 시드가 기본적으로 옳지 만, 당신이 정말로 문제에 대한 통찰력을 가지고 있다고 생각합니다.

atan ()은 사분면에 대응하지 않으므로 필요한 수평으로부터 각도를 알려주지 않으므로 Atan2 ()가 필요합니다.

이는 벡터 (-2,2) 및 (2, -2)에 atan을 사용하면 동일한 값을 제공한다는 것을 의미합니다. 그런 다음 인수 인수 부호를 켜고 결과에 pi를 추가합니다. 또한 Jesse가 언급 한 것을 고려할 때 0으로 나누는 특별한 경우가 있습니다. 또한 x가 0에 가까울 때 atan2 ()가 atan보다 더 잘 작동합니다.

따라서 -pi와 pi 사이의 벡터 각도를 원한다면

x = -2
y = 2
angle = Math.Atan2(y, x)

또는

x = -2
y = 2
angle = calculateAngle(y, x);

double CalculateAngle(double y, double x)
{
    double angle = 0;
    if (x == 0)
    {
        if (y == 0)
            angle = 0;
        else if (y > 0)
            angle = Math.PI/2;
        else
            angle = -Math.PI/2;
    }
    else
    {
        angle = Math.Atan(y/x);
        if (x < 0)
        {
            if (y > 0)
            {
                angle += Math.PI;
            }
            else if (y < 0)
            {
                angle -= Math.PI;
            }
            else
            {
                angle = Math.PI;
            }
        }
    }
    return angle;
}

1
"이것은 벡터 (-2,2)와 (2,2)에 atan을 사용하면 동일한 값을 얻을 수 있음을 의미합니다." 이 경우 atan이 엄청나게 파손 된 경우 그 중 하나는 -π / 4이고 다른 하나는 π / 4 여야하기 때문입니다. 이 쓰레기를 투표 한 모든 사람에게 부끄러운 일.

코드가 여전히 잘못되었습니다. 다른 지점에서 테스트 한 y==0다음 나누고 x있습니다.
sam hocevar

0

몇 가지를 간결하게 설명하겠습니다. 자세한 설명은 온라인 삼각법 자습서를 참조하십시오.

각도를 보자. 그런 다음 tan (a) = tan (a + 2 * pi)입니다.

atan은 tan에 거꾸로 있습니다. 즉, tan에 주어진 각도를 제공합니다. atan (tan (a + 2 * pi))을 호출하면 대답은 a입니다. 응용 프로그램에 적합하지 않습니다.

atan2는이 정확한 상황을 돕기 위해 두 가지 주장을 취할 것입니다. atan은 기본적으로 cos (a)와 sin (a) 인 x와 y를 사용합니다.

atan2 (sin (a), cos (a)) = atan2 (sin (a + 2 * pi), cos (a + 2 * pi)) = a + 2 * pi / * sin 및 cos는 다른 부호를 가지며 다른 답변에 * /

이것이 왜 이런지 설명하는 튜토리얼을 찾아보십시오.

코드는 다음과 같아야합니다.

if (mouseMoved)
{
  double angle = atan2(mousey - objecty, mousex - objectx);

  object. setTransform to Rotate(angle);

  // If you want to print it
  print radian_to_degrees(angle); // Because angle is in radian 360 degrees = 2*Pi radians
}

tan(a) = - tan(-a), 당신이 표현하고 싶었던 방정식은 아마tan(a) = tan(pi+a)
Ali1S232

0

atan2내 코드에서 찾은 한 가지 용도 는 "서명 된 각도"입니다.

일반적으로 두 벡터 사이의 각도를 찾는 방법은

inline float angleWith( const Vector2f& o ) const
{
    return acosf( this->normalizedCopy().dot(o.normalizedCopy()) ) ;
}

그러나 이것은 어느 쪽이 "리드"(즉, 다른 쪽보다 "시계 방향으로 더 먼"지)를 알려주지 않습니다. 이 정보는 제스처 추적에 중요 할 수 있습니다.

(1,0)두 벡터에 대해 x 축에서 각도를 찾을 수 있지만 모호한 문제가 있습니다. 각도가 315 도인 벡터는 cos위 의 방법을 사용하여 45도를 반환 하며 각도도 45 도입니다. 이를 확인 y하기 위해 사인온을 수행 하거나을 사용할 수 있습니다 atan2.

// Returns + if this leads o.
// more expensive than unsigned angle.
inline float signedAngleWith( const Vector2f& o ) const
{
  float aThis = atan2f( y, x );
  float aO = atan2f( o.y, o.x ) ;
  return aThis - aO ;
}

0

아탄이 파손되지 않았습니다. arctan 또는 tan inverse는 -PI / 2와 PI / 2 사이의 함수일뿐입니다. 이 패턴을 반복하지만 여러 답변을 처리하지 않기 때문에 컴퓨터에 문제가되는 기능이 아닙니다.

이것은 -PI / 2와 PI / 2 사이의 asin과 0과 PI 사이의 acos에 동일합니다. 함수가 발생하는 가장 간단한 범위입니다. 아탄과 아인에게는 그것이 가장 부정적인 것에서 가장 긍정적 인 것으로 간다. acos의 경우 가장 긍정적 인 것에서 가장 부정적인 것으로 간다. (이것은보다 정확한 답변을 보간하는 데 도움이됩니다)

asin, acos 및 atan은 수학 함수입니다.

그러나 atan2는 완전한 회전 (라디안 또는 360도 또는 400 gradians의 PI)을 제공하므로 프로그래밍에 훨씬 유용합니다. 그들은 죄와 죄를 위해서가 아니라 황갈색을 위해 하나만 생산했음을 주목하라. Tan은 수평 및 수직 (x, y)을 사용하는 유일한 제품입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.