罗盘 Angle/Rotation 跟踪方向到 X、Y 位置的角度 Javascript
Compass Angle/Rotation Angle For Tracking Direction to X,Y Position In Javascript
假设您有两个 x,y 坐标:起点:(100, 100) 和终点:(96, 105)。所以我需要向左和向上。我想要一个箭头指向目的地的方向,由 css 旋转 属性 旋转,所以我需要角度方向(从 0 到 360)。 0表示直线向上,180表示直线向下,90表示向右,等等
大多数帖子都说通过使用以下方式获得方位角:(Math.atan2(105 - 100, 96 - 100) * 180) / Math.PI;
。但我无法让它发挥作用。有了上面的坐标,我得到 128.6598...
,它会在右下方。它还给出负数,这也会把它扔掉。我已经尝试根据它是正数还是负数来添加不同的度数,但没有任何效果。
有没有办法获得这两个点的正确航向(从 0 到 360)?谢谢!
我觉得应该是{end point} - {starting point}
(Math.atan2(96 - 100, 105 - 100) * 180) / Math.PI;
// giving -38.659808254090095 = Down to the right
我认为这不是最好的方法,但应该可行:
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
工作原理如下:
r是位移矢量,给定的,我们求α(alpha),那个角度矢量.
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°[
}
编辑
后来,我意识到,它也可以与 Math.atan2
一起工作:
const getVectorAngle = ([x1, y1], [x2, y2]) => {
const x = x2 - x1
const y = y2 - y1
return x || y
? ((Math.atan2(x, y) * 180 / Math.PI) + 360) % 360
: NaN
}
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
您可能会注意到,计算的外部 shell 保持不变。那是因为 Math.atan2
已经 return 在区间 ]-180°;180°]
中以弧度为单位的角度;所以它在功能上与第一个解决方案的内部部分相同。
唯一的变化是对空向量进行额外检查:Math.atan2
在这种情况下不会 return NaN
。
假设您有两个 x,y 坐标:起点:(100, 100) 和终点:(96, 105)。所以我需要向左和向上。我想要一个箭头指向目的地的方向,由 css 旋转 属性 旋转,所以我需要角度方向(从 0 到 360)。 0表示直线向上,180表示直线向下,90表示向右,等等
大多数帖子都说通过使用以下方式获得方位角:(Math.atan2(105 - 100, 96 - 100) * 180) / Math.PI;
。但我无法让它发挥作用。有了上面的坐标,我得到 128.6598...
,它会在右下方。它还给出负数,这也会把它扔掉。我已经尝试根据它是正数还是负数来添加不同的度数,但没有任何效果。
有没有办法获得这两个点的正确航向(从 0 到 360)?谢谢!
我觉得应该是{end point} - {starting point}
(Math.atan2(96 - 100, 105 - 100) * 180) / Math.PI;
// giving -38.659808254090095 = Down to the right
我认为这不是最好的方法,但应该可行:
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
工作原理如下:
r是位移矢量,给定的,我们求α(alpha),那个角度矢量.
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°[
}
编辑
后来,我意识到,它也可以与 Math.atan2
一起工作:
const getVectorAngle = ([x1, y1], [x2, y2]) => {
const x = x2 - x1
const y = y2 - y1
return x || y
? ((Math.atan2(x, y) * 180 / Math.PI) + 360) % 360
: NaN
}
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
您可能会注意到,计算的外部 shell 保持不变。那是因为 Math.atan2
已经 return 在区间 ]-180°;180°]
中以弧度为单位的角度;所以它在功能上与第一个解决方案的内部部分相同。
唯一的变化是对空向量进行额外检查:Math.atan2
在这种情况下不会 return NaN
。