Углы обнаружения 0-360

Нужна помощь по математической проблеме: мне нужно получить истинный угол от 0 градусов, используя х и у корней im используя это в данный момент:

Math.atan((x2-x1)/(y1-y2))/(Math.PI/180)

но /(Math.PI/180) ограничивает результаты от -90 до 90 мне нужно 0-360

Примечание: я использую угол для указания направления:

  • 0 = вверх
  • 90 = право
  • 135 = 45 градусов справа + вниз
  • 180 = вниз
  • 270 = левый
  • и т.д.

Ответ 1

Math.atan ограничивает вас двумя крайними квадратами на единичном круге. Чтобы получить полный 0-360 градусов:

if x < 0 add 180 to the angle
else if y < 0 add 360 to the angle. 

Ваша система координат повернута и инвертирована по сравнению с моей (и по сравнению с конвенцией). Положительный x справа, положительный y - вверх. 0 градусов находится справа (x > 0, y = 0, 90 градусов вверх (x = 0, y > 0) 135 градусов вверх и влево (y > 0, x = -y) и т.д. Где указаны ваши x- и y-оси?

Ответ 2

Функция atan дает только половину единичного круга между -pi/2 и + pi/2 (0 на оси x), существует еще одна библиотечная функция, которая может дать весь единичный круг между -pi и + pi, atan2

Я бы подумал, что лучше использовать atan2, чтобы получить правильный квадрант, а не разветвляться, а затем просто масштабироваться, как вы были, что-то вроде

Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI + 180

Умножение на 180 по pi - это просто масштаб от радианов до градусов, как в вопросе (но с делением на упрощенное деление), +180 гарантирует, что его всегда положительный, то есть 0-360 град, а не -180 до 180 градусов

Ответ 3

Ответы @jilles de wit и @jk. вел меня по правильному пути, но по какой-то причине не обеспечил правильное решение моей проблемы, которое, по моему мнению, очень похоже на исходный вопрос.

Я хотел подняться = 0 °, справа = 90 °, вниз = 180 °, слева = 270 °, как в авиационных навигационных системах.

Предполагая, что вопрос касался рисования холста, я достиг этого решения:

Сначала я перевел начало холста, используя ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2). Я также уменьшил вдвое e.offsetX и e.offsedY, я получил от события мыши на холсте, чтобы получить x и y с той же системой координат, что и холст.

let radianAngle = Math.atan2(y, x);    // x has the range [-canvas.width/2 ... +canvas.width/2], y is similar
let northUpAngle = radianAngle * 180 / PI + 90;    // convert to degrees and add 90 to shift the angle counterclockwise from it default "left" = 0°
if (x < 0 && y < 0) {    // check for the top left quadrant
    northUpAngle += 360;    // add 360 to convert the range of the quadrant from [-90...0] to [270...360] (actual ranges may vary due to the way atan2 handles quadrant boundaries)
}
northUpAngle.toFixed(2)    // to avoid getting 360° near the "up" position

Может быть более сжатое решение, использующее операцию modulo, но я не мог его найти.

Ответ 4

Также обратите внимание:

if (y1==y2) {
    if (x1>x2)
        angle = 90;
    else if (x1<x2)
        angle = 270;
    else
        angle = 0;
}

Ответ 5

Это должно сделать трюк:

  • Если y2
  • Если < 0, добавить 360.

Примеры:

(x1, y1) = 0

(x2,y2) = (-1,1), atan() = -45, [add 360], 270
(x2,y2) = (1,1), atan() = 45
(x2,y2) = (1,-1), atan() = -45, [add 180], 135
(x2 ,y2) = (-1,-1), atan() = 45, [add 180], 225

Ответ 6

angle = Math.atan(this.k) * 180 / Math.PI;
angle = 180 - (angle < 0 ? 180 + angle : angle);
angle = p2.Y > p1.Y || (p2.Y == p1.Y && p2.X > p1.X) ? 180 + angle : angle;

Ответ 7

function angle(x1,y1,x2,y2)
{
eangle = Math.atan((x2-x1)/(y1-y2))/(Math.PI/180)
if ( angle > 0 )
{
  if (y1 < y2)
    return angle;
  else
    return 180 + angle;
} else {
  if (x1 < x2)
    return 180 + angle;
  else
    return 360 + angle;
}
}