Learn JavaScript

Math.atan2() - метод для вычисления угла по координатам y и x в JavaScript

Math.atan2() вычисляет угол по координатам y и x.

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

Главное, что нужно запомнить сразу:

  • метод принимает сначала y, а потом x
  • результат возвращается в радианах

Синтаксис

Math.atan2(y, x)
  • y - координата по вертикали
  • x - координата по горизонтали

Что делает Math.atan2()

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

console.log(Math.atan2(0, 1)); // 0
console.log(Math.atan2(1, 1)); // 0.7853981633974483
console.log(Math.atan2(1, 0)); // 1.5707963267948966

Это значит:

  • Math.atan2(0, 1) равно 0
  • Math.atan2(1, 1) равно π / 4
  • Math.atan2(1, 0) равно π / 2

Что возвращает Math.atan2()

Math.atan2() возвращает число типа number.

const result = Math.atan2(1, 2);

console.log(result);        // 0.4636476090008061
console.log(typeof result); // "number"

Результат всегда находится в диапазоне от -Math.PI до Math.PI.

Порядок аргументов: сначала y, потом x

Это самая частая ошибка при работе с Math.atan2().

console.log(Math.atan2(1, 2)); // 0.4636476090008061
console.log(Math.atan2(2, 1)); // 1.1071487177940904

Результаты разные, потому что это уже разные точки:

  • (x = 2, y = 1)
  • (x = 1, y = 2)

Если перепутать аргументы местами, получится другой угол.

Результат возвращается в радианах

Это второй важный момент при работе с Math.atan2().

console.log(Math.atan2(1, 1)); // 0.7853981633974483

Это не 0.78 градуса и не 45 градусов, а угол в радианах.

Если нужно перевести результат в градусы, используйте формулу:

градусы = радианы * 180 / Math.PI

Пример:

const radians = Math.atan2(1, 1);
const degrees = radians * 180 / Math.PI;

console.log(degrees); // 45

Четверти координатной плоскости

Одно из главных преимуществ Math.atan2() в том, что метод правильно определяет четверть, в которой находится точка.

console.log(Math.atan2(1, 1));   // 0.7853981633974483
console.log(Math.atan2(1, -1));  // 2.356194490192345
console.log(Math.atan2(-1, -1)); // -2.356194490192345
console.log(Math.atan2(-1, 1));  // -0.7853981633974483

Это соответствует разным четвертям:

  • (1, 1) - первая четверть
  • (-1, 1) - вторая четверть
  • (-1, -1) - третья четверть
  • (1, -1) - четвёртая четверть

Что происходит на осях

Math.atan2() хорошо работает и в случаях, когда точка лежит прямо на оси.

console.log(Math.atan2(0, 1));  // 0
console.log(Math.atan2(1, 0));  // 1.5707963267948966
console.log(Math.atan2(0, -1)); // 3.141592653589793
console.log(Math.atan2(-1, 0)); // -1.5707963267948966

Это удобно, потому что не нужно отдельно обрабатывать деление на ноль.

Что будет для точки (0, 0)

Это особый случай.

console.log(Math.atan2(0, 0)); // 0

В математике направление для точки (0, 0) считается неопределённым, но в JavaScript метод возвращает 0.

Math.atan2() и Math.atan()

Эти методы похожи по названию, но делают не одно и то же.

console.log(Math.atan(1));      // 0.7853981633974483
console.log(Math.atan2(1, 1));  // 0.7853981633974483
  • Math.atan(x) работает с одним числом
  • Math.atan2(y, x) работает с двумя координатами

Если у вас есть именно точка на плоскости или отдельно x и y, обычно лучше использовать Math.atan2().

Math.atan2() и Math.atan(y / x)

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

Иногда это действительно даёт похожий результат:

console.log(Math.atan2(1, 2));    // 0.4636476090008061
console.log(Math.atan(1 / 2));    // 0.4636476090008061

Но не всегда:

console.log(Math.atan2(1, -1));  // 2.356194490192345
console.log(Math.atan(1 / -1));  // -0.7853981633974483

И ещё пример:

console.log(Math.atan2(-1, -1));     // -2.356194490192345
console.log(Math.atan((-1) / (-1))); // 0.7853981633974483

Math.atan(y / x) теряет информацию о четверти, а Math.atan2(y, x) её сохраняет.

Именно поэтому Math.atan2() обычно надёжнее для геометрии, графики и координат.

Без аргументов

Если вызвать Math.atan2() без аргументов, результатом будет NaN.

console.log(Math.atan2()); // NaN

Если передать только один аргумент, результат тоже будет NaN.

console.log(Math.atan2(1)); // NaN

Так происходит потому, что методу нужны оба значения: и y, и x.

Неявное приведение типов

Math.atan2() сначала пытается привести оба аргумента к числу.

console.log(Math.atan2("1", "1"));   // 0.7853981633974483
console.log(Math.atan2(null, 1));    // 0
console.log(Math.atan2(1, null));    // 1.5707963267948966
console.log(Math.atan2(undefined, 1)); // NaN

На практике лучше передавать в метод уже готовые числа.

NaN и Infinity

Для специальных значений метод тоже имеет предсказуемое поведение.

console.log(Math.atan2(NaN, 1));                // NaN
console.log(Math.atan2(Infinity, Infinity));    // 0.7853981633974483
console.log(Math.atan2(Infinity, -Infinity));   // 2.356194490192345
console.log(Math.atan2(-Infinity, -Infinity));  // -2.356194490192345

Это полезно помнить:

  • если хотя бы один аргумент NaN, результат будет NaN
  • с Infinity метод всё равно может вычислить направление

Числа не меняются

Math.atan2() не изменяет исходные значения. Он только возвращает новый результат.

const y = 1;
const x = 1;
const result = Math.atan2(y, x);

console.log(y);      // 1
console.log(x);      // 1
console.log(result); // 0.7853981633974483

Когда это полезно

Math.atan2() часто используют, когда:

  • нужно найти угол точки относительно центра
  • вы работаете с координатами на плоскости
  • делаете поворот объектов в играх и анимациях
  • строите графику, стрелки, векторы или траектории

Пример:

const x = 10;
const y = 10;
const angle = Math.atan2(y, x);

console.log(angle); // 0.7853981633974483
console.log(angle * 180 / Math.PI); // 45

Частые ошибки

Путать порядок аргументов

console.log(Math.atan2(1, 2)); // 0.4636476090008061
console.log(Math.atan2(2, 1)); // 1.1071487177940904

В Math.atan2() сначала идёт y, потом x.

Ожидать результат в градусах

console.log(Math.atan2(1, 1)); // 0.7853981633974483

Это радианы. Если нужны градусы, переводите отдельно.

Думать, что Math.atan2(y, x) - это то же самое, что Math.atan(y / x)

console.log(Math.atan2(-1, -1));     // -2.356194490192345
console.log(Math.atan((-1) / (-1))); // 0.7853981633974483

У Math.atan2() есть важное преимущество: он правильно определяет четверть.

Быстрая памятка

  • Math.atan2(y, x) вычисляет угол по координатам
  • аргументы передаются в порядке y, потом x
  • метод возвращает number
  • результат всегда находится в диапазоне от -Math.PI до Math.PI
  • результат возвращается в радианах
  • Math.atan2(1, 1) равно Math.PI / 4
  • Math.atan2(1, 0) равно Math.PI / 2
  • Math.atan2(0, -1) равно Math.PI
  • для координат и направлений Math.atan2() обычно лучше, чем Math.atan(y / x)

Коротко

Math.atan2() - это стандартный способ вычислить угол по координатам y и x в JavaScript. Главное, что нужно запомнить: метод принимает аргументы в порядке y, x, возвращает результат в радианах и, в отличие от Math.atan(y / x), правильно определяет четверть угла.