Для чого в іграх використовуються 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.