Javascript 如何从点计算角度?

Javascript 如何从点计算角度?,javascript,function,coordinates,angle,Javascript,Function,Coordinates,Angle,我想得到一个简单的解决方案来计算线的角度(就像时钟的指针) 我有两点: cX, cY - the center of the line. eX, eY - the end of the line. The result is angle (0 <= a < 360). cX,cY-线的中心。 eX,eY-线路的末端。 结果是角度(0您想要反正切: dy = ey - cy dx = ex - cx theta = arctan(dy/dx) theta *= 180/pi //

我想得到一个简单的解决方案来计算线的角度(就像时钟的指针)

我有两点:

cX, cY - the center of the line.
eX, eY - the end of the line.

The result is angle (0 <= a < 360).
cX,cY-线的中心。
eX,eY-线路的末端。

结果是角度(0您想要反正切:

dy = ey - cy
dx = ex - cx
theta = arctan(dy/dx)
theta *= 180/pi // rads to degs
呃,请注意,上面的代码显然不是编译Javascript代码。您必须查看函数的文档

编辑:使用将为您处理所有特殊情况和额外逻辑:

function angle(cx, cy, ex, ey) {
  var dy = ey - cy;
  var dx = ex - cx;
  var theta = Math.atan2(dy, dx); // range (-PI, PI]
  theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
  //if (theta < 0) theta = 360 + theta; // range [0, 360)
  return theta;
}
功能角度(cx、cy、ex、ey){
var-dy=ey-cy;
var dx=ex-cx;
var theta=Math.atan2(dy,dx);//范围(-PI,PI]
θ*=180/Math.PI;//rads到degs,范围(-180,180]
//如果(θ<0)θ=360+θ;//范围[0360)
返回θ;
}
的可运行版本

功能角度(cx、cy、ex、ey){
var-dy=ey-cy;
var dx=ex-cx;
var theta=Math.atan2(dy,dx);//范围(-PI,PI]
θ*=180/Math.PI;//rads到degs,范围(-180,180]
返回θ;
}
功能角度360(cx、cy、ex、ey){
varθ=角度(cx,cy,ex,ey);//范围(-180,180]
如果(θ<0)θ=360+θ;//范围[0360)
返回θ;
}
显示(“右”,0,0,1,0);
显示(“右上角”,0,0,1,1);
显示(“顶部”,0,0,0,1);
显示(“左上角”,0,0,-1,1);
显示(“左”,0,0,-1,0);
显示(“左下角”,0,0,-1,-1);
显示(“底部”,0,0,0,-1);
显示(“右下角”,0,0,1,-1);
//忽略下面的内容(所有呈现内容)
表格{
边界塌陷:塌陷;
}
表,th,td{
边框:1px纯黑;
填充物:2px4px;
}
tr>td:不是(第一个孩子){
文本对齐:居中;
}
t脚掌{
字体:斜体;
}

方向*开始角度360度
*笛卡尔坐标系
正x向右,正y向上。 功能显示(标签、cx、cy、ex、ey){ var行=”; 行+=“”+标签+“”; 行+=”+[cx,cy]+”; 行+=”+[ex,ey]+”; 行+=“”+角度(cx、cy、ex、ey)+“”; 行+=“”+angle360(cx、cy、ex、ey)+”; 行+=”; document.getElementById(“angles”).innerHTML+=行; }
获取两点或任意角度之间的角度的问题之一是您使用的参考

在数学中,我们使用一个原点位于圆右侧的三角圆(x=半径中的一个点,y=0),并从0到2PI逆时针计算角度

在地理上,原点是0度的北方,我们顺时针从0度到360度

下面的代码(C#)以弧度为单位获取角度,然后转换为地理角度:

    public double GetAngle()
    {
        var a = Math.Atan2(YEnd - YStart, XEnd - XStart);
        if (a < 0) a += 2*Math.PI; //angle is now in radians

        a -= (Math.PI/2); //shift by 90deg
        //restore value in range 0-2pi instead of -pi/2-3pi/2
        if (a < 0) a += 2*Math.PI;
        if (a < 0) a += 2*Math.PI;
        a = Math.Abs((Math.PI*2) - a); //invert rotation
        a = a*180/Math.PI; //convert to deg

        return a;
    }
public-double-GetAngle()
{
var a=Math.Atan2(YEnd-YStart,XEnd-XStart);
如果(a<0)a+=2*Math.PI;//角度现在以弧度为单位
a-=(数学PI/2);//移动90度
//恢复范围为0-2pi而不是-pi/2-3pi/2的值
如果(a<0)a+=2*Math.PI;
如果(a<0)a+=2*Math.PI;
a=Math.Abs((Math.PI*2)-a);//反转旋转
a=a*180/Math.PI;//转换为度
返回a;
}

如果您正在使用画布,您会注意到(如果您还没有)画布使用顺时针旋转,并且
y
轴被翻转。要获得一致的结果,您需要调整
角度
函数

有时,我需要编写这个函数,每次我都需要查找它,因为我永远不会找到计算的底部

虽然建议的解决方案可行,但它们没有考虑画布坐标系。请查看以下演示:

功能角度(originX,originY,targetX,targetY){
var dx=原始值-目标值;
var dy=原始-目标;
//varθ=数学atan2(dy,dx);/[0,Ⲡ] 然后[-Ⲡ, 0];顺时针;0°=西
//θ*=180/Math.PI;//[0180]然后[-180,0];顺时针;0°=西
//如果(θ<0)θ+=360;//[0360];顺时针;0°=西
//varθ=数学参数atan2(-dy,dx);/[0,Ⲡ] 然后[-Ⲡ, 0];逆时针;0°=西
//θ*=180/Math.PI;//[0,180]然后[-180,0];逆时针;0°=west
//如果(θ<0)θ+=360;/[0360];逆时针;0°=西
//varθ=数学atan2(dy,-dx);/[0,Ⲡ] 然后[-Ⲡ, 0];逆时针;0°=东
//θ*=180/Math.PI;//[0180]然后[-180,0];逆时针;0°=东
//如果(θ<0)θ+=360;/[0360];逆时针;0°=东
varθ=数学参数atan2(-dy,-dx);/[0,Ⲡ] 然后[-Ⲡ, 0];顺时针;0°=东
θ*=180/Math.PI;//[0180]然后[-180,0];顺时针;0°=东
如果(θ<0)θ+=360;//[0360];顺时针;0°=东
返回θ;
}

您可以在这里找到两个公式,一个来自正x轴,另一个来自逆时针方向

一个从北顺时针方向

有x=x2-x1和y=y2=y1。有E=E2-E1和N=N2-N1

这些公式适用于x、y、E和N的任何值

对于x=y=0或E=N=0,结果未定义

f(x,y)=pi()-pi()/2*(1+符号(x))*(1-符号(y^2))

f(E,N)=pi()-pi()/2*(1+符号(N))*(1-符号(E^2))


你至少需要三个点来计算一个角度。你是第三个?x轴还是y轴?另请参见:注意,为了避免被0除,你应该先测试
dx==0
;如果是,然后如果
dy>0
返回90度,如果
dy<0
返回270度@EtiennePerot:我记得另一个有用的函数,并更新了我的ans我们可以用它来代替。你可能还想把结果转换成度,这听起来像是OP想要的。几乎,这里面有一个小错误:
theta*=180/Math。PI
是正确的。你也不需要担心零除法,当使用
atan2()
时,它也会返回正确的值和
0
。添加(可选)按照问题的要求将其翻转到360度。当我必须添加90度时,这意味着什么
function angle(originX, originY, targetX, targetY) {
    var dx = originX - targetX;
    var dy = originY - targetY;

    // var theta = Math.atan2(dy, dx);  // [0, Ⲡ] then [-Ⲡ, 0]; clockwise; 0° = west
    // theta *= 180 / Math.PI;          // [0, 180] then [-180, 0]; clockwise; 0° = west
    // if (theta < 0) theta += 360;     // [0, 360]; clockwise; 0° = west

    // var theta = Math.atan2(-dy, dx); // [0, Ⲡ] then [-Ⲡ, 0]; anticlockwise; 0° = west
    // theta *= 180 / Math.PI;          // [0, 180] then [-180, 0]; anticlockwise; 0° = west
    // if (theta < 0) theta += 360;     // [0, 360]; anticlockwise; 0° = west

    // var theta = Math.atan2(dy, -dx); // [0, Ⲡ] then [-Ⲡ, 0]; anticlockwise; 0° = east
    // theta *= 180 / Math.PI;          // [0, 180] then [-180, 0]; anticlockwise; 0° = east
    // if (theta < 0) theta += 360;     // [0, 360]; anticlockwise; 0° = east

    var theta = Math.atan2(-dy, -dx); // [0, Ⲡ] then [-Ⲡ, 0]; clockwise; 0° = east
    theta *= 180 / Math.PI;           // [0, 180] then [-180, 0]; clockwise; 0° = east
    if (theta < 0) theta += 360;      // [0, 360]; clockwise; 0° = east

    return theta;
}
     -pi()/4*(2+sign(x))*sign(y)

     -sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
     -pi()/4*(2+sign(N))*sign(E)

     -sign(E*N)*atan((abs(N)-abs(E))/(abs(N)+abs(E)))