В чем разница между atan и atan2 в C ++?


Ответы:



322

Из школьной математики мы знаем, что касательная имеет определение

tan(α) = sin(α) / cos(α)

и мы различаем четыре квадранта в зависимости от угла зрения функций. Знак sin, cosи tanимеют следующие отношения (где мы пренебрегаем точными коэффициентами π/2):

  Quadrant    Angle              sin   cos   tan
-------------------------------------------------
  I           0    < α < π/2      +     +     +
  II          π/2  < α < π        +     -     -
  III         π    < α < 3π/2     -     -     +
  IV          3π/2 < α < 2π       -     +     -

Учитывая, что значение tan(α)положительно, мы не можем различить, был ли угол от первого или третьего квадранта, и если он отрицателен, он может исходить из второго или четвертого квадранта. Таким образом, по соглашению, atan()возвращает угол из первого или четвертого квадранта (то есть -π/2 <= atan() <= π/2), независимо от исходного ввода в касательную.

Чтобы получить полную информацию, мы не должны использовать результат деления, sin(α) / cos(α)но мы должны смотреть на значения синуса и косинуса отдельно. И это то, что atan2()делает. Он принимает оба, sin(α)и cos(α)и разрешает все четыре квадранта, добавляя πк результату atan()всякий раз, когда косинус отрицателен.

Примечание:atan2(y, x) функция фактически принимает yи в xаргумент, который является проекцией вектора с длиной vи углом αна y- и оси х, т.е.

y = v * sin(α)
x = v * cos(α)

который дает отношение

y/x = tan(α)

Вывод: atan(y/x) удерживается некоторая информация и можно только предполагать, что входные данные поступили из квадрантов I или IV. Напротив, atan2(y,x)получает все данные и, следовательно, может разрешить правильный угол.


3
Одна маленькая деталь, диапазон -π/2 <= atan() <= π/2фактически включает одну точку ( pi/2) из квадранта II.
Z бозон

28

Еще одна вещь, которую стоит упомянуть, это то, что atan2она более стабильна при вычислении касательных с использованием выражения, подобного atan(y / x)и xравного 0 или близкого к 0.


Интересно, у вас есть источник для этого? Это правда в целом или только для C ++?
Джерард

26

Фактические значения в радианах, но для их интерпретации в градусах это будет:

  • atan = дает значение угла между -90 и 90
  • atan2 = дает значение угла между -180 и 180

Для моей работы, которая включает в себя вычисление различных углов, таких как направление и направление в навигации, atan2в большинстве случаев делает эту работу.


12

atan (x) Возвращает главное значение арктангенса x, выраженное в радианах.

atan2 (y, x) Возвращает главное значение арктангенса y / x, выраженное в радианах.

Обратите внимание, что из-за неоднозначности знака функция не может с уверенностью определить, в каком квадранте угол падает только по его значению касательной (только atan). Вы можете использовать atan2, если вам нужно определить квадрант.


3
atan2 (x, y) -> atan2 (y, x)
yesraaj

Диапазон основных значений, (-pi,pi]но у atan2 есть диапазон, [-pi,pi]поэтому он включает одно дополнительное значение -piиз другой ветви из-за atan2(-0.0,x)for x<0.
Z бозон

4

Я предполагаю, что главный вопрос пытается выяснить: «когда я должен использовать тот или другой», или «который я должен использовать», или «я использую правильный»?

Я предполагаю, что важным моментом является то, что atan предназначен только для подачи положительных значений по кривой направления вправо-вверх, как для векторов времени-расстояния. Cero всегда находится внизу слева, и пальцы могут двигаться только вверх и вправо, только медленнее или быстрее. atan не возвращает отрицательные числа, поэтому вы не можете отследить вещи в четырех направлениях на экране, просто сложив / вычтя результат.

atan2 предназначен для того, чтобы источник находился посередине, и все может идти назад или вниз. Это то, что вы бы использовали в представлении на экране, потому что это НЕ имеет значения, в каком направлении вы хотите, чтобы кривая шла. Таким образом, atan2 может дать вам отрицательные числа, потому что его cero находится в центре, а его результат - то, что вы можете использовать для отслеживания вещей в 4 направлениях.


2

С atan2 вы можете определить квадрант, как указано здесь .

Вы можете использовать atan2, если вам нужно определить квадрант.


2

Рассмотрим прямоугольный треугольник. Мы помечаем гипотенузу r, горизонтальную сторону y и вертикальную сторону x. Угол интереса α - это угол между x и r.

C ++ atan2(y, x)даст нам значение угла α в радианах. atanиспользуется, если мы знаем или заинтересованы только в y / x, а не в y и x по отдельности. Поэтому, если p = y / x, то для получения α мы будем использовать atan(p).

Вы не можете использовать atan2для определения квадранта, вы можете использовать, atan2только если вы уже знаете, какой квадрант ваш в! В частности, положительные x и y означают первый квадрант, положительный y и отрицательный x, второй и так далее. atanили atan2сами просто вернуть положительное или отрицательное число, не более того.


4
Если все, что у вас есть, p=y/xвы все еще можете использовать atan2(p,1).
Марк Рэнсом

0

Mehrwolf ниже верен, но вот эвристика, которая может помочь:

Если вы работаете в двумерной системе координат, которая часто используется для программирования обратной касательной, вы должны обязательно использовать atan2. Он даст полный диапазон углов 2 пи и позаботится о нулях в координате х.

Другой способ сказать, что atan (y / x) практически всегда неверен. Используйте atan, только если аргумент не может рассматриваться как y / x.


0

atan2(y,x)обычно используется, если вы хотите преобразовать декартовы координаты в полярные координаты. Это даст вам угол, в то время как sqrt(x*x+y*y)или, если доступно, hypot(y,x)даст вам размер.

atan(x)это просто обратный загар. В досадном случае вы должны использовать, atan(y/x)потому что ваша система не обеспечивает atan2, вам нужно будет сделать дополнительные проверки для признаков xи y, и, для x=0того, чтобы получить правильный угол.

Примечание: atan2(y,x) определяется для всех действительных значений yи x, за исключением случая, когда оба аргумента равны нулю.


0

В atan2, выход: -pi< atan2(y,x)< pi
и в Атан, выход: -pi/2< atan(y/x)< pi/2 // это доза не считают четверть.
Если вы хотите получить ориентацию между 0и 2*pi(например, по математике в старшей школе), нам нужно использовать atan2, а для отрицательных значений - добавить, 2*piчтобы получить окончательный результат между 0и 2*pi.
Вот исходный код Java, чтобы объяснить это ясно:

System.out.println(Math.atan2(1,1)); //pi/4 in the 1st quarter
System.out.println(Math.atan2(1,-1)); //(pi/4)+(pi/2)=3*(pi/4) in the 2nd quarter

System.out.println(Math.atan2(-1,-1 ));//-3*(pi/4) and it is less than 0.
System.out.println(Math.atan2(-1,-1)+2*Math.PI); //5(pi/4) in the 3rd quarter

System.out.println(Math.atan2(-1,1 ));//-pi/4 and it is less than 0.
System.out.println(Math.atan2(-1,1)+2*Math.PI); //7*(pi/4) in the 4th quarter

System.out.println(Math.atan(1 ));//pi/4
System.out.println(Math.atan(-1 ));//-pi/4
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.