Відповіді:
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(α)
але ми повинні дивитися на значення синуса і косинуса окремо. І це те, що 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)
отримує всі дані і таким чином може вирішити правильний кут.
Ще одна річ, яку слід зазначити, atan2
є більш стійкою при обчисленні дотичних, використовуючи вираз like atan(y / x)
і x
дорівнює 0 або близький до 0.
Фактичні значення є у радіанах, але інтерпретувати їх у градусах буде:
atan
= дає значення кута між -90 і 90atan2
= дає значення кута між -180 і 180Для моєї роботи, яка передбачає обчислення різних кутів, таких як рухи та підшипники в навігації, atan2
в більшості випадків справляється з цим завданням.
atan (x) Повертає головне значення дотичної дуги x, виражене в радіанах.
atan2 (y, x) Повертає головне значення дотичної дуги y / x, виражене в радіанах.
Зауважте, що через неоднозначність знаку функція не може з упевненістю визначити, у якому квадранті кут падає лише за його дотичною величиною (лише в атані). Ви можете використовувати atan2, якщо вам потрібно визначити квадрант.
(-pi,pi]
але atan2 має діапазон [-pi,pi]
таким чином воно включає одне додаткове значення -pi
з іншої гілки з - за atan2(-0.0,x)
для x<0
.
Я думаю, що головне питання намагається з'ясувати: "коли я повинен використовувати те чи інше", або "що я повинен використовувати", або "чи я використовую правильний"?
Я думаю, що важливим моментом є те, що лише Атан покликаний подавати позитивні значення в кривій напрямку вправо вгору, як для векторів відстані за часом. Церо завжди внизу ліворуч, а тиги можуть йти лише вгору і вправо, лише повільніше або швидше. atan не повертає негативні числа, тому ви не можете відстежувати речі в 4-х напрямках на екрані, просто додаючи / віднімаючи його результат.
atan2 призначений для того, щоб походження знаходилося посередині, і все може йти назад або вниз. Це те, що ви використовували б у поданні на екрані, оскільки це НЕ має значення в якому напрямку ви хочете, щоб крива йшла. Таким чином, atan2 може дати вам негативні цифри, оскільки церебро знаходиться в центрі, і його результат - це те, що ви можете використовувати для відстеження речей у 4 напрямках.
Розглянемо прямокутний трикутник. Позначимо гіпотенузу r, горизонтальну сторону y та вертикальну сторону x. Кут, що цікавить α, - кут між х і r.
C ++ atan2(y, x)
дасть нам значення кута α у радіанах.
atan
використовується, якщо ми знаємо або цікавимось y / x не y, а x окремо. Отже, якщо p = y / x, то для отримання α ми би використовували atan(p)
.
Ви не можете використовувати atan2
для визначення квадранта, ви можете використовувати його atan2
лише в тому випадку, якщо ви вже знаєте, який квадрант увійшов! Зокрема, позитивні х і у мають на увазі перший квадрант, позитивний у і негативний х, другий тощо. atan
або atan2
самі просто повертають позитивне чи негативне число, нічого більше.
p=y/x
ви все одно можете використовувати atan2(p,1)
.
Мервольф нижче правильний, але ось евристика, яка може допомогти:
Якщо ви працюєте в двовимірній системі координат, що часто трапляється для програмування зворотної дотичної, слід обов'язково використовувати atan2. Це дасть повний діапазон кутів 2 pi та подбає про нулі в координаті 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
і в Атан, вихід: -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
-π/2 <= atan() <= π/2
насправді включає одну точку (pi/2
) від квадранта II.