Как рассчитать угол из точек? - PullRequest
37 голосов
/ 08 марта 2012

Я хочу получить простое решение для вычисления угла линии (как указатель часов).

У меня есть 2 балла:

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

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

Какая функция способна обеспечить это значение?

Ответы [ 5 ]

84 голосов
/ 08 марта 2012

Требуется арктангенс:

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

. Заметьте, что приведенное выше явно не компилирует код Javascript.Вам нужно будет просмотреть документацию для функции arctangent .

Редактировать: Использование 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;
}
11 голосов
/ 30 июня 2015

Запускаемая версия Ответ Кристиана .

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]
  return theta;
}
function angle360(cx, cy, ex, ey) {
  var theta = angle(cx, cy, ex, ey); // range (-180, 180]
  if (theta < 0) theta = 360 + theta; // range [0, 360)
  return theta;
}

show("right", 0, 0, 1, 0);
show("top right", 0, 0, 1, 1);
show("top", 0, 0, 0, 1);
show("top left", 0, 0, -1, 1);
show("left", 0, 0, -1, 0);
show("bottom left", 0, 0, -1, -1);
show("bottom", 0, 0, 0, -1);
show("bottom right", 0, 0, 1, -1);

// IGNORE BELOW HERE (all presentational stuff)
table {
  border-collapse: collapse;
}
table, th, td {
  border: 1px solid black;
  padding: 2px 4px;
}
tr > td:not(:first-child) {
  text-align: center;
}
tfoot {
  font-style: italic;
}
<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>
2 голосов
/ 05 декабря 2017

Если вы используете холст, вы заметите (если вы этого еще не сделали), что холст использует вращение по часовой стрелке (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;
}
0 голосов
/ 13 ноября 2018

Здесь вы найдете две формулы: одну от положительной оси x и против часовой стрелки

и один с севера и по часовой стрелке.

Существует x = x2-x1 и y = y2 = y1. Есть E = E2-E1 и N = N2-N1.

Формулы работают для любых значений x, y, E и N.

Для x = y = 0 или E = N = 0 результат не определен.

Р (х, у) = р () - пи () / 2 * (1 + знак (х)) * (1-знак (у ^ 2))

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

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

F (E, N) = р () - пи () / 2 * (1 + знак (N)) * (1-знак (Е ^ 2)) * * 1014

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

     -sign(E*N)*atan((abs(N)-abs(E))/(abs(N)+abs(E)))
0 голосов
/ 03 декабря 2016

Одной из проблем получения угла между двумя точками или любым углом является используемая вами ссылка.

В математике мы используем тригонометрический круг с началом координат справа от круга (точка в х= радиус, 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;
    }
...