Finden Sie zuerst den Unterschied zwischen dem Startpunkt und dem Endpunkt (hier handelt es sich eher um ein gerichtetes Liniensegment, nicht um eine "Linie", da sich Linien unendlich erstrecken und nicht an einem bestimmten Punkt beginnen).
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
Berechnen Sie dann den Winkel (der von der positiven X-Achse bei P1
zur positiven Y-Achse bei verläuft P1
).
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
Dies ist jedoch arctan
möglicherweise nicht ideal, da durch die Aufteilung der Unterschiede auf diese Weise die Unterscheidung aufgehoben wird, die zur Unterscheidung des Quadranten erforderlich ist, in dem sich der Winkel befindet (siehe unten). Verwenden Sie stattdessen Folgendes, wenn Ihre Sprache eine atan2
Funktion enthält:
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
BEARBEITEN (22. Februar 2017): Im Allgemeinen wird jedoch atan2(deltaY,deltaX)
nur aufgerufen , um den richtigen Winkel für cos
und sin
möglicherweise unelegant zu finden. In diesen Fällen können Sie stattdessen häufig Folgendes tun:
- Behandeln Sie
(deltaX, deltaY)
als Vektor.
- Normalisieren Sie diesen Vektor zu einem Einheitsvektor. Teilen Sie dazu
deltaX
und deltaY
durch die Länge des Vektors ( sqrt(deltaX*deltaX+deltaY*deltaY)
), es sei denn, die Länge ist 0.
- Danach ist
deltaX
nun der Kosinus des Winkels zwischen dem Vektor und der horizontalen Achse (in Richtung von der positiven X- zur positiven Y-Achse bei P1
).
- Und
deltaY
wird jetzt der Sinus dieses Winkels sein.
- Wenn die Länge des Vektors 0 ist, hat er keinen Winkel zwischen ihm und der horizontalen Achse (also keinen aussagekräftigen Sinus und Cosinus).
EDIT (28. Februar 2017): Auch ohne Normalisierung (deltaX, deltaY)
:
- Das Vorzeichen von
deltaX
zeigt an, ob der in Schritt 3 beschriebene Cosinus positiv oder negativ ist.
- Das Vorzeichen von
deltaY
zeigt an, ob der in Schritt 4 beschriebene Sinus positiv oder negativ ist.
- Die Vorzeichen
deltaX
und deltaY
geben an, in welchem Quadranten sich der Winkel in Bezug auf die positive X-Achse befindet P1
:
+deltaX
, +deltaY
: 0 bis 90 Grad.
-deltaX
, +deltaY
: 90 bis 180 Grad.
-deltaX
, -deltaY
: 180 bis 270 Grad (-180 bis -90 Grad).
+deltaX
, -deltaY
: 270 bis 360 Grad (-90 bis 0 Grad).
Eine Implementierung in Python mit Bogenmaß (bereitgestellt am 19. Juli 2015 von Eric Leschinski, der meine Antwort bearbeitet hat):
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
Alle Tests bestehen. Siehe https://en.wikipedia.org/wiki/Unit_circle