Wie berechnet man einen Winkel aus Punkten?

Lesezeit: 6 Minuten

Benutzeravatar von durumdara
durumdara

Ich möchte eine einfache Lösung, um den Winkel einer Linie zu berechnen (wie ein Zeiger einer Uhr).

Ich habe 2 Punkte:

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

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

Welche Funktion kann diesen Wert liefern?

  • Sie benötigen mindestens drei Punkte, um einen Winkel zu berechnen. Welche bist du 3.? Die x-Achse oder die y-Achse?

    – Sirko

    8. März 2012 um 7:19 Uhr

  • Siehe auch: Dieselbe Frage für Python

    – Martin Thoma

    20. Juni 2020 um 17:34 Uhr

Benutzeravatar von Christian Mann
Christian Mann

Sie wollen den Arkustangens:

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

Ähm, beachten Sie, dass das Obige offensichtlich keinen Javascript-Code kompiliert. Sie müssen in der Dokumentation nachsehen Arkustangens Funktion.

Bearbeiten: Verwenden Math.atan2(y,x) behandelt alle Sonderfälle und zusätzliche Logik für Sie:

Funktion angle(cx, cy, ex, ey) { var dy = ey - cy;  var dx = ex - cx;  var theta = Math.atan2 (dy, dx);  // Bereich (-PI, PI]Theta *= 180 / Math.PI; // Rad in Grad, Bereich (-180, 180]//if (Theta < 0) Theta = 360 + Theta; // Bereich [0, 360)
  return theta;
}

  • Note that to avoid division by 0, you should test if dx == 0 first; if it is, then return 90 degrees if dy > 0 and 270 degrees if dy < 0.

    – Etienne Perot

    Mar 8, 2012 at 7:20

  • @EtiennePerot: I remembered another useful function and updated my answer to use that instead.

    – Christian Mann

    Mar 8, 2012 at 7:24

  • You may also want to convert the result to degrees, it sounds like that's what the OP wants.

    – Etienne Perot

    Mar 8, 2012 at 7:26

  • Almost, there is a little error in it: theta*=180/Math.PI is correct. You also don't need to worry about zero division, when using atan2(), it returns correct value with 0 too.

    – Teemu

    Mar 8, 2012 at 7:36

  • Added (optional) code to flip it to 360 range as the question asked.

    – TWiStErRob

    Jun 30, 2015 at 11:12

TWiStErRob's user avatar
TWiStErRob

Runnable version of Christian's answer.

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;  // Rad in Grad, Bereich (-180, 180]gib Theta zurück; } function angle360(cx, cy, ex, ey) { var theta = angle(cx, cy, ex, ey); // Bereich (-180, 180]if (Theta < 0) Theta = 360 + Theta; // Bereich [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] + "";  Zeile += "" + [ex, ey] + "";  Zeile += "" + Winkel(cx, cy, ex, ey) + "";  Zeile += "" + angle360(cx, cy, ex, ey) + "";  Zeile += "";  document.getElementById("Winkel").innerHTML += row;  } 

Wenn Sie Leinwand verwenden, werden Sie feststellen (falls Sie dies noch nicht getan haben), dass die Leinwand im Uhrzeigersinn gedreht wird(MDN) und y Achse wird umgedreht. Um konsistente Ergebnisse zu erzielen, müssen Sie Ihre optimieren angle Funktion.

Von Zeit zu Zeit muss ich diese Funktion schreiben und jedes Mal nachschlagen, weil ich nie auf den Grund der Berechnung komme.

Die vorgeschlagenen Lösungen funktionieren zwar, berücksichtigen jedoch nicht das Canvas-Koordinatensystem. Untersuchen Sie die folgende Demo:

Winkel aus Punkten berechnen - 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;
}

  • Was bedeutet es, wenn ich 90 Grad zur Antwort hinzufügen muss, um die richtige Drehung zu erhalten?

    – 1,21 Gigawatt

    15. August 2019 um 21:37 Uhr


  • Und wie heißen die Koordinatensysteme? Kartesischer Koordinatenbeweger nach rechts und oben en.wikipedia.org/wiki/Cartesian_coordinates. Wie nennt man es, wenn sich positive Werte nach rechts und unten bewegen?

    – 1,21 Gigawatt

    15. August 2019 um 21:41 Uhr

  • @ 1,21 Gigawatt Zitierst du mich mit "müssen 90 Grad zur Antwort hinzufügen, um die richtige Drehung zu erhalten" (weil ich so etwas nicht gesagt habe) oder ist es etwas anderes und du versuchst es zu verstehen? Hmm, ich bin mir nicht sicher, ob es einen Namen hat. Der einzige Unterschied zwischen den beiden ist die Drehrichtung. Canvas verwendet auch ein kartesisches Koordinatensystem. Es ist nur im Uhrzeigersinn statt gegen den Uhrzeigersinn. Untersuchen Sie den Abschnitt "Quadranten und Oktanten" auf der Seite, die Sie verlinkt haben. Drehen Sie die y Achse, das ist Schalter I und II Quadranten mit IV und III, beziehungsweise. Jetzt ist es im Uhrzeigersinn.

    – akinuri

    16. August 2019 um 7:25 Uhr


  • Ich versuche zu verstehen, warum das Hinzufügen von 90 Grad zum Ergebnis in meinem Fall funktioniert. Ich habe gerade in der @pasx-Antwort bemerkt, dass er einen Kommentar hat a -= (Math.PI/2); //shift by 90deg und ich habe die Erwähnung von 90 Grad an anderer Stelle gesehen.

    – 1,21 Gigawatt

    16. August 2019 um 14:33 Uhr


  • @ 1,21 Gigawatt, gleich. Abweichen um 90°.

    – Jeff Fischer

    24. September 2020 um 17:34 Uhr

Eines der Probleme beim Ermitteln des Winkels zwischen zwei Punkten oder einem beliebigen Winkel ist die von Ihnen verwendete Referenz.

In der Mathematik verwenden wir einen trigonometrischen Kreis mit dem Ursprung rechts vom Kreis (ein Punkt in x = Radius, y = 0) und zählen den Winkel gegen den Uhrzeigersinn von 0 bis 2PI.

In der Geographie ist der Ursprung der Norden bei 0 Grad und wir gehen im Uhrzeigersinn von bis 360 Grad.

Der folgende Code (in C #) erhält den Winkel im Bogenmaß und konvertiert ihn dann in einen geografischen Winkel:

    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;
    }

Sie finden hier zwei Formeln, eine von der positiven Achse x und eine gegen den Uhrzeigersinn

und eine von Norden und im Uhrzeigersinn.

Es gibt x=x2-x1 und y=y2=y1. Es gibt E=E2-E1 und N=N2-N1.

Die Formeln funktionieren für jeden Wert von x, y, E und N.

Für x=y=0 oder E=N=0 ist das Ergebnis undefiniert.

f(x,y)=pi()-pi()/2*(1+sign(x))*(1-sign(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+Zeichen(N))*(1-Zeichen(E^2))

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

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

1434470cookie-checkWie berechnet man einen Winkel aus Punkten?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy