Угол компаса / угол поворота для отслеживания направления по X, Y в Javascript - PullRequest
1 голос
/ 18 июня 2020

Допустим, у вас есть две координаты x, y: начальная точка: (100, 100) и конечная точка (96, 105). Так что мне нужно go влево и вверх. Я хочу, чтобы стрелка указывала путь к месту назначения, повернутого свойством css rotate, поэтому мне нужен заголовок в градусах (от 0 до 360). 0 будет означать go прямо вверх, 180 будет означать go прямо вниз, 90 будет go вправо, et c.

В большинстве сообщений говорится, что азимут в градусах можно получить с помощью: (Math.atan2(105 - 100, 96 - 100) * 180) / Math.PI;. Но я не могу заставить это работать. С указанными выше координатами я получаю 128.6598..., который будет справа и снизу. Он также дает отрицательные числа, которые тоже его сбивают. Я пробовал добавлять различные степени в зависимости от того, положительный он или отрицательный, но ничего не получалось.

Есть ли способ получить правильный заголовок (от 0 до 360) для двух точек? Спасибо!

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Я думаю, что это не лучший способ сделать это, но он должен работать:

const getVectorAngle = ([x1, y1], [x2, y2]) => {
  const x = x2 - x1
  const y = y2 - y1
  return (((Math.acos(y / Math.sqrt(x * x + y * y)) * (Math.sign(x) || 1)) * 180 / Math.PI) + 360) % 360
}

console.log(getVectorAngle([100, 100], [96, 105])) //321.3401

console.log(getVectorAngle([100, 100], [100, 101])) //0
console.log(getVectorAngle([100, 100], [101, 101])) //45
console.log(getVectorAngle([100, 100], [101, 100])) //90
console.log(getVectorAngle([100, 100], [101,  99])) //135
console.log(getVectorAngle([100, 100], [100,  99])) //180
console.log(getVectorAngle([100, 100], [ 99,  99])) //225
console.log(getVectorAngle([100, 100], [ 99, 100])) //270
console.log(getVectorAngle([100, 100], [ 99, 101])) //315
console.log(getVectorAngle([100, 100], [100, 100])) //NaN, start and end values are the same

Вот как это работает:

Visualisation Visalisation made by Геометрия Geogebra

r - вектор смещения, который задается, и мы ищем α (альфа), угол этого вектора.

const getVectorAngle = ([x1, y1], [x2, y2]) => {
  const x = x2 - x1
  const y = y2 - y1
  return (
      (
        ( //Getting angle by `y = cos(alpha) * r` -> `alpha = cos^-1(y / r)`
          Math.acos(
            y / 
            Math.sqrt(x * x + y * y) //Pythagorean theorem to get the length of r, `r^2 = x^2 + y^2` -> `r = sqrt(x^2 + y^2)`
          ) //= angle in interval [0°; 180°] (in radians)
          * ( //Detect the direction of angle by changing its sign
            Math.sign(x) //Sign of x, +1 if positive, -1 if negative
            || 1         //Return +1 even if x is 0, to avoid cancelling out 180°
          )
        ) //= angle in interval ]-180°; 180°] (still in radians)
        * 180 / Math.PI //Convert angle from radians to degrees
      ) //= angle in degrees
      + 360 //Add 360° to avoid negative values
    ) //= angle in interval ]180°; 540°]
    % 360 //Modulo by 360° to simplify angles >=360°
  //= angle in degrees in interval [0°; 360°[
}
1 голос
/ 18 июня 2020

Думаю, должно быть {end point} - {starting point}

(Math.atan2(96 - 100, 105 - 100) * 180) / Math.PI;
// giving -38.659808254090095 = Down to the right
...