Углы обнаружения 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;
}
}