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

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

11 ответов


std::atan2 позволяет вычислить арктангенс всех четырех квадрантах. std::atan только позволяет вычислять из квадрантов 1 и 4.


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

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(α) но мы должны смотреть на значения синуса и Косинуса отдельно. И вот что!--12--> делает. Он принимает как sin(α) и cos(α) и разрешает все четыре квадранты путем добавления π в результате atan() всякий раз, когда Косинус отрицателен.

замечание: на


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


фактические значения находятся в радианах, но интерпретировать их в градусах будет:

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

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


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

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

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


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

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

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


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

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


рассмотрим прямоугольный треугольник. Обозначим гипотенузу 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 сами просто возвращают положительное или отрицательное число, не более того.


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

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

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


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, за исключением случая, когда оба аргумента равны нулю.


в atan2 выход:-pi atan2(y,x) pi
и в atan выход:-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