Что такое atan и atan2, используемые в играх?

У меня возникли проблемы с пониманием Math.tan() и Math.atan() и Math.atan2().

У меня есть базовые знания о тригонометрии, но использование SIN, COS и TAN и т. д. для разработки игр для меня очень нова.

Я читаю некоторые уроки, и я вижу, что используя тангенс, мы можем получить угол, в котором один объект должен быть повернут тем, как можно столкнуться с другим объектом, например с мышью. Итак, почему нам еще нужно использовать atan или atan2?

41 голос | спросил sutoL 8 J000000Friday11 2011, 06:03:19

7 ответов


87

Тангенс-формула такова:

tan(angle) = opposite/adjacent

Обратитесь к этому рисунку:

Диаграмма прямоугольного треугольника с углом тета и его противоположными и смежными сторонами отмечена«> </p>

<p> Где <code>a</code> - соседняя сторона, <code>o</code> - противоположная сторона, а <code>theta</code> - это угол. Аналогично, синус и косинус sin (ang) = o /h и cos (ang) = a /h, где <code>h</code> - длинная сторона: <a href = http://www.mathwords.com/s/sohcahtoa.htm

Между тем a (short для arc-tangent , также известный как обратный тангенс ) - это обратная сторона o, так:

theta

Таким образом, если вы знаете значения как противоположной, так и смежных сторон (например, вычитая координаты объекта из координат мыши), вы можете получить значение угла с помощью h.

Тем не менее, в разработке игр может случиться довольно часто, что соседняя сторона равна 0 (например, координата x вектора равна 0). Помня, что atan потенциал для катастрофической ошибки деления на нуль должен быть ясным. Поэтому многие библиотеки предлагают функцию под названием tan, которая позволяет указать параметры atan(opposite/adjacent) = angle и atan, чтобы избежать деления на ноль для вы дадите угол в правом квадранте.

диаграмма atan2

(диаграмма любезно предоставлена ​​гаретом, пожалуйста, проголосуйте также за свой ответ)


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

Вы даже можете использовать «циклическую» природу функций синуса и косинуса для особого поведения в игре, например. Я видел, что cos /sin много использовал, чтобы объект обернулся другим.

ответил Jesse Emond 8 J000000Friday11 2011, 06:21:47
60

введите описание изображения здесь>> </p></body></html>

ответил Gareth Rees 9 J000000Saturday11 2011, 13:11:17
11

Вот несколько иной способ мышления о функциях триггера - в том числе atan () и atan2 () - что я считаю полезным (объяснения с точки зрения «противоположного /смежного» меня почему-то путают).

x, y, r, theta

Вы можете перейти из одной точки в другую, перемещая единицы измерения 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
  • ÆŸ = atan (y /x)

Однако при выполнении y /x вычисление 3/4 дает тот же ответ, что и вычисление -3 /-4. Аналогично -3/4 дает тот же ответ, что и 3 /-4. Таким образом, мы имеем atan2 (y, x), который правильно обрабатывает индивидуальные знаки и предотвращает ошибку divide-by-zero /infinity.

  • ÆŸ = atan2 (y, x)
ответил AbePralle 14 FriEurope/Moscow2012-12-14T09:45:45+04:00Europe/Moscow12bEurope/MoscowFri, 14 Dec 2012 09:45:45 +0400 2012, 09:45:45
4

Джесси и Сид в основном правы, но я подозреваю, что вы действительно понимаете проблему.

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

Это означает, что использование atan для векторов (-2,2) и (2, -2) даст одно и то же значение. Затем вы должны включить знак ваших аргументов и добавить pi к результату. Кроме того, у вас есть деление на нулевой особый случай, чтобы учесть, что Джесси упоминал. Также atan2 () работает лучше, чем atan, когда x близок к 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;
}
ответил LukeN 8 J000000Friday11 2011, 11:34:30
0

Я проясню несколько вещей кратким образом. Подробные объяснения см. В учебниках тригонометрии онлайн.

Пусть a - угол. Тогда tan (a) = tan (a + 2 * pi).

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

atan2 возьмет 2 аргумента, чтобы помочь в этих точных ситуациях. atan принимает x и y, которые в основном cos (a) и sin (a).

atan2 (sin (a), cos (a)) = 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
}
ответил Sid Datta 8 J000000Friday11 2011, 07:10:33
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 ;
}
ответил bobobobo 15 SatEurope/Moscow2012-12-15T03:49:42+04:00Europe/Moscow12bEurope/MoscowSat, 15 Dec 2012 03:49:42 +0400 2012, 03:49:42
0

Обратите внимание, что атаан не сломан. arctan или tan inverse - это только функция между -PI /2 и PI /2. Он повторяет этот шаблон, но затем он не является функцией, которая является проблемой для компьютера, поскольку она не обрабатывает несколько ответов.

Это то же самое для asin между -PI /2 и PI /2 и acos между 0 и PI. Это самые простые диапазоны для функции. Для анан и асин он от самого негативного до самого положительного. Для acos его происходит от самого положительного до самого негативного. (это помогает интерполировать более точные ответы)

, так что asin, acos и atan являются математическими функциями.

atan2, однако, гораздо полезнее для программирования, поскольку он обеспечивает полную революцию (PI в радианах или 360 градусах или 400 градиентах). Обратите внимание, что они производят только один загар не для sin или cos. Тан является единственным, который использует горизонтальные и вертикальные (x, y)

ответил Deuce 26 J0000006Europe/Moscow 2015, 20:16:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132