Для чого в іграх використовуються atan та atan2?


47

У мене виникли деякі проблеми розуміння Math.tan()і Math.atan()і Math.atan2().

У мене є основні знання з тригометрії, але використання SIN, COS і TAN тощо для розвитку ігор для мене дуже нове.

Я читаю деякі підручники і бачу, що за допомогою дотичної ми можемо отримати кут, в якому потрібно обертати один об’єкт, на скільки стикатися з іншим об'єктом, наприклад, мишею. То чому ми все-таки повинні використовувати atan або atan2?


Атан використовується для визначення кута, корисного для тисячі різних речей. У вас є актуальне питання щодо його використання чи ви просто шукаєте загальну математичну допомогу?
BlueRaja - Danny Pflughoeft

5
Вам обов'язково потрібно зрозуміти математику / геометрію цих функцій; як тільки ви оволодієте ними, вони стануть частиною вашого "світорозуміння", як основна граматика, яку ви використовуєте щодня, щоб говорити. Як тільки ви зможете "говорити з математики / геометрії", ви побачите, що ці функції - це спрощені інструменти для досягнення результату, найбільш природні для використання.
FxIII

Ці підручники або неправильні, або ви неправильно зрозуміли. Ви використовуєте atan2 () для отримання кута від одного об'єкта до іншого. Як це працює, пояснено нижче.
поштовх

дякую людям за відповіді, тепер я
шкодую, що не звертаю

Відповіді:


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потенціал згубної помилки поділу на нуль повинен бути очевидним. Так що багато бібліотек пропонують функцію atan2, що називається , яка дозволяє задавати xі yпараметри, і параметри, щоб уникнути поділу на нуль і задати кут у правому квадранті.

діаграма atan2

(схема ввічливості Гарет, будь ласка, проголосуйте також його відповідь)


Використання тригонометрії в розробці ігор досить поширене, особливо з векторами, але зазвичай бібліотеки приховують роботу тригонометрії для вас. Ви можете використовувати sin / cos / tan для багатьох завдань, які передбачають геометричні маніпуляції, щоб знайти значення з трикутника. Все, що вам потрібно, це 3 значення (бічні довжини / значення кута), щоб знайти інші значення прямокутного трикутника, тому це досить корисно.

Ви навіть можете використовувати "велосипедний" характер функцій синуса і косинуса для особливих поведінок у грі, наприклад, я бачив, як cos / sin багато використовував для того, щоб об'єкт обернувся навколо іншого.


8
Варто відзначити, що Вікіпедія описує інші звички для Atan2 ( не для атана), ніж просто уникати поділу на нуль. Наприклад, він виправляє себе для використовуваного квадранта, де зазвичай все це потрібно робити самостійно.
doppelgreener

Дійсно, дуже важлива примітка саме там. Оновлення моєї відповіді.
Джессі Емонд

Хіба ви не отримали загар і атан назад у своєму першому довгому абзаці? Ви б використовували Атан, щоб отримати кут (тобто зворотне рівняння) і загар, щоб отримати співвідношення сторін (тобто саме те, що говорить рівняння).
поштовх

Добре, якщо ви знаєте, що o / a дорівнює, наприклад, 3, то якщо ви хочете кут, який ви робите Атан (3), це я мав на увазі: якщо ви хочете ізолювати кут, ви використовуєте Атан на відношення. Якщо ви хочете ізолювати співвідношення, ви використовуєте загар на кут.
Джессі Емонд

Тоді я зміню ваше формулювання, тому що це звучить так, як ви сказали протилежне.
поштовх

63

введіть тут опис зображення


1
Чи було б нечесним редагувати верхню відповідь, щоб мати в ній цю діаграму? Ця діаграма є чудовою і добре підійде відразу після письмового пояснення Джессі про atan2 ().
поштовх

1
Вперед: будь моїм гостем! Я видалю цю відповідь, коли закінчите.
Гарет Різ

7
Ні ні. Тримай! Це зараховано, і люди все ще повинні подати заявку на цю діаграму.
Джессі Емонд

12

Ось дещо інший спосіб мислення щодо триггерних функцій - включаючи atan () та atan2 () - який мені здається корисним (пояснення в термінах "протилежне / сусіднє" просто збивають з пантелику мене з якихось причин).

х, у, г, тета

Ви можете дістатися з однієї точки в іншу, переміщаючи x одиниці по горизонталі та y одиниці вертикально (називаються прямокутними або декартовими координатами) або переміщуючи відстань r під кутом Ɵ (називається полярними координатами в 2D).

Скажімо, у нас є полярна координата (r, Ɵ) і ми хочемо перетворити її в (x, y).

cos (Ɵ) дає вам частку r, що лежить уздовж осі x :

  • Якщо r = 1, то x = cos (Ɵ).
  • Якщо r = 100, то x = 100 * cos (Ɵ).
  • Загалом x = r * cos (Ɵ).

Так само sin (Ɵ) дає вам частку r, яка лежить уздовж осі y :

  • Якщо r = 1, то y = sin (Ɵ).
  • Якщо r = 100, то y = 100 * sin (Ɵ).
  • Взагалі y = r * sin (Ɵ).

Як щодо перетворення прямокутної координати (x, y) у полярну координату (r, Ɵ)?

r - гіпотенуза правильного трикутника, утвореного x і y , так:

  • r = sqrt (x x + y y)

tan (Ɵ) дає нахил - підйом над пробігом - лінії довжиною r . Тому:

  • tan (Ɵ) = y / x
  • Ɵ = атан (у / х)

Однак, виконуючи y / x, обчислення 3/4 дає таку ж відповідь, як обчислення -3 / -4. Так само -3/4 дає таку ж відповідь, що і 3 / -4. Таким чином, у нас є atan2 (y, x), який правильно обробляє окремі знаки та запобігає помилці розділення на нуль / нескінченність.

  • Ɵ = atan2 (y, x)

4

Джессі і Сід в основному праві, але я підозрюю, що ви насправді після розуміння проблеми.

Atan2 () потрібен, оскільки atan () не вказує вам кут від горизонталі, який вам потрібен, оскільки він не справляється з квадрантами.

Це означає, що використання атана для векторів (-2,2) та (2, -2) дасть однакове значення. Тоді ви б увімкнули знак своїх аргументів і додали pi до результату. Крім того, у вас є особливий поділ на нуль, щоб врахувати, що згадував Джессі. Також atan2 () працює краще, ніж атан, коли х близький до 0

Тож ви, якщо хочете, кут вектора між -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) дасть однакове значення." Якщо це так, ваш атан надзвичайно зламаний, тому що один з них повинен бути -π / 4, а другий π / 4. Ганьба всім, хто проголосував за це сміття.

Код все ще помиляється. Ви перевіряєте на те, щоб y==0потім розділити xв іншій гілці.
sam hocevar

0

Я поясню кілька речей коротко. Детальні пояснення див. У навчальних посібниках з тригонометрії в Інтернеті.

Нехай кут. Тоді tan (a) = tan (a + 2 * pi).

Атан - загар обернений, тобто дає кут, заданий загаром. Коли ви називаєте atan (tan (a + 2 * pi)), відповідь буде а. Це буде недостатнім для вашої заявки.

atan2 візьме 2 аргументи, щоб допомогти у цій точній ситуації. атан приймає х і у, які в основному є cos (a) і sin (a).

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()) ) ;
}

Але це не говорить вам, хто з них "веде" (тобто "далі вперед за годинниковою стрілкою", ніж інший). Ця інформація може бути важливою для відстеження жестів.

Ви можете знайти кут від осі x (1,0)для обох векторів, але є ця неприємна проблема неоднозначності: вектор з кутом 315 градусів повертається на 45 градусів, використовуючи cosвищевказаний метод, і так само кут 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

Зверніть увагу: Атан не порушений. арктан або загар - це лише функція між -PI / 2 та PI / 2. Він повторює цю схему, але тоді це не функція, яка є проблемою для комп'ютера, оскільки вона не обробляє декілька відповідей.

Це те ж саме, що і для Asin між -PI / 2 і PI / 2 і acos між 0 і PI. Це найпростіші діапазони для виникнення функції. Для атана і асина він переходить від самого негативного до самого позитивного. Для acos це переходить від самого позитивного до самого негативного. (це допомагає в інтерполяції більш точних відповідей)

тому асин, аксос і атан - це математичні функції.

atan2, однак, є набагато кориснішим для програмування, оскільки забезпечує повний оберт (PI в радіанах або 360 градусів або 400 градіанів). Зауважте, вони виробляли лише для засмаги, а не для гріха чи cos. Засмага - це єдиний, який використовує горизонтальну та вертикальну (x, y)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.