javascript-如何从点计算角度?

我想要一个简单的解决方案来计算线的角度(如时钟的指针)。

我有2分:

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

The result is angle (0 <= a < 360).

哪个功能可以提供此值?

durumdara asked 2020-08-10T04:28:15Z
5个解决方案
90 votes

您需要反正切:

dy = ey - cy
dx = ex - cx
theta = arctan(dy/dx)
theta *= 180/pi // rads to degs

嗯,请注意,以上内容显然不是在编译Javascript代码。 您必须仔细阅读反正切函数的文档。

编辑:使用Math.atan2(y,x)将为您处理所有特殊情况和额外的逻辑:

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;
}
Christian Mann answered 2020-08-10T04:28:30Z
12 votes

可运行版本的克里斯汀的答案。

<table>
  <thead>
    <tr><th>Direction*</th><th>Start</th><th>End</th><th>Angle</th><th>Angle 360</th></tr>
  </thead>
  <tfoot>
     <tr><td colspan="5">* Cartesian coordinate system<br>positive x pointing right, and positive y pointing up.</td>
  </tfoot>
  <tbody id="angles">
  </tbody>
</table>
<script>
function show(label, cx, cy, ex, ey) {
  var row = "<tr>";
  row += "<td>" + label + "</td>";
  row += "<td>" + [cx, cy] + "</td>";
  row += "<td>" + [ex, ey] + "</td>";
  row += "<td>" + angle(cx, cy, ex, ey) + "</td>";
  row += "<td>" + angle360(cx, cy, ex, ey) + "</td>";
  row += "</tr>";
  document.getElementById("angles").innerHTML += row;
}
</script>
<table>
  <thead>
    <tr><th>Direction*</th><th>Start</th><th>End</th><th>Angle</th><th>Angle 360</th></tr>
  </thead>
  <tfoot>
     <tr><td colspan="5">* Cartesian coordinate system<br>positive x pointing right, and positive y pointing up.</td>
  </tfoot>
  <tbody id="angles">
  </tbody>
</table>
<script>
function show(label, cx, cy, ex, ey) {
  var row = "<tr>";
  row += "<td>" + label + "</td>";
  row += "<td>" + [cx, cy] + "</td>";
  row += "<td>" + [ex, ey] + "</td>";
  row += "<td>" + angle(cx, cy, ex, ey) + "</td>";
  row += "<td>" + angle360(cx, cy, ex, ey) + "</td>";
  row += "</tr>";
  document.getElementById("angles").innerHTML += row;
}
</script>
<table>
  <thead>
    <tr><th>Direction*</th><th>Start</th><th>End</th><th>Angle</th><th>Angle 360</th></tr>
  </thead>
  <tfoot>
     <tr><td colspan="5">* Cartesian coordinate system<br>positive x pointing right, and positive y pointing up.</td>
  </tfoot>
  <tbody id="angles">
  </tbody>
</table>
<script>
function show(label, cx, cy, ex, ey) {
  var row = "<tr>";
  row += "<td>" + label + "</td>";
  row += "<td>" + [cx, cy] + "</td>";
  row += "<td>" + [ex, ey] + "</td>";
  row += "<td>" + angle(cx, cy, ex, ey) + "</td>";
  row += "<td>" + angle360(cx, cy, ex, ey) + "</td>";
  row += "</tr>";
  document.getElementById("angles").innerHTML += row;
}
</script>

TWiStErRob answered 2020-08-10T04:28:50Z
5 votes

如果您使用的是画布,则会注意到(如果尚未使用)画布使用顺时针旋转(MDN),并且y轴被翻转了。 为了获得一致的结果,您需要调整angle功能。

有时,我需要编写此函数,并且每次都需要查找它,因为我从不深入计算。

尽管建议的解决方案有效,但它们并未考虑画布坐标系。 检查以下演示:

从点计算角度-JSFiddle

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;
}
akinuri answered 2020-08-10T04:29:25Z
1 votes

获取两点或任意角度之间的角度的问题之一是您使用的参考。

在数学中,我们使用三角圆,其原点在圆的右边(x =半径,y = 0的点),并从0到2PI逆时针计数角度。

在地理上,原点是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;
    }
pasx answered 2020-08-10T04:29:58Z
1 votes

您可以在此处找到两个公式,一个是从正轴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))

     -pi()/4*(2+sign(x))*sign(y)

     -sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))

f(e,n)= pi()-pi()/ 2 *(1 + sig(n))*(1-sig(e ^ 2))

     -pi()/4*(2+sign(N))*sign(E)

     -sign(E*N)*atan((abs(N)-abs(E))/(abs(N)+abs(E)))
theodore panagos answered 2020-08-10T04:30:45Z
translate from https://stackoverflow.com:/questions/9614109/how-to-calculate-an-angle-from-points