Ich arbeite an einem räumlichen Analyseproblem, und ein Teil dieses Arbeitsablaufs besteht darin, den Winkel zwischen verbundenen Liniensegmenten zu berechnen.Berechnen von Winkeln zwischen Liniensegmenten (Python) mit math.atan2
Jedes Liniensegment besteht aus nur zwei Punkten und jeder Punkt hat ein Paar XY-Koordinaten (kartesisch). Hier ist das Bild von GeoGebra. Ich bin immer daran interessiert, einen positiven Winkel in 0 bis 180 Bereich zu bekommen. Ich bekomme jedoch alle möglichen Winkel abhängig von der Reihenfolge der Scheitelpunkte in den Eingabezeilensegmenten.
Die Eingangsdaten I mit Arbeit ist als Tupel von Koordinaten vorgesehen sind. Abhängig von der Scheitelpunkt-Erstellungsreihenfolge kann der letzte/Endpunkt für jedes Liniensegment unterschiedlich sein. Hier sind einige Fälle in Python-Code. Die Reihenfolge der Liniensegmente, in denen ich sie erhalte, ist zufällig, aber in einem Tupel-Tupel ist das erste Element der Startpunkt und das zweite Element ist der Endpunkt. 10 Liniensegment zum Beispiel hätte ((1,1.5),(2,2))
und (1,1.5)
ist der Startpunkt, weil es die erste Position im Koordinaten-Tupel hat.
Ich muss jedoch sicherstellen, dass ich den gleichen Winkel zwischen DE,DF
und ED,DF
und so weiter bekomme.
vertexType = "same start point; order 1"
#X, Y X Y coords
lineA = ((1,1.5),(2,2)) #DE
lineB = ((1,1.5),(2.5,0.5)) #DF
calcAngle(lineA, lineB,vertexType)
#flip lines order
vertexType = "same start point; order 2"
lineB = ((1,1.5),(2,2)) #DE
lineA = ((1,1.5),(2.5,0.5)) #DF
calcAngle(lineA, lineB,vertexType)
vertexType = "same end point; order 1"
lineA = ((2,2),(1,1.5)) #ED
lineB = ((2.5,0.5),(1,1.5)) #FE
calcAngle(lineA, lineB,vertexType)
#flip lines order
vertexType = "same end point; order 2"
lineB = ((2,2),(1,1.5)) #ED
lineA = ((2.5,0.5),(1,1.5)) #FE
calcAngle(lineA, lineB,vertexType)
vertexType = "one line after another - down; order 1"
lineA = ((2,2),(1,1.5)) #ED
lineB = ((1,1.5),(2.5,0.5)) #DF
calcAngle(lineA, lineB,vertexType)
#flip lines order
vertexType = "one line after another - down; order 2"
lineB = ((2,2),(1,1.5)) #ED
lineA = ((1,1.5),(2.5,0.5)) #DF
calcAngle(lineA, lineB,vertexType)
vertexType = "one line after another - up; line order 1"
lineA = ((1,1.5),(2,2)) #DE
lineB = ((2.5,0.5),(1,1.5)) #FD
calcAngle(lineA, lineB,vertexType)
#flip lines order
vertexType = "one line after another - up; line order 2"
lineB = ((1,1.5),(2,2)) #DE
lineA = ((2.5,0.5),(1,1.5)) #FD
calcAngle(lineA, lineB,vertexType)
Ich habe eine winzige Funktion geschrieben, die Kombinationen der Zeilen als Argumente akzeptiert und den Winkel zwischen ihnen berechnet. Ich benutze die math.atan2
, die dafür am besten geeignet schien.
def calcAngle(lineA,lineB,vertexType):
line1Y1 = lineA[0][1]
line1X1 = lineA[0][0]
line1Y2 = lineA[1][1]
line1X2 = lineA[1][0]
line2Y1 = lineB[0][1]
line2X1 = lineB[0][0]
line2Y2 = lineB[1][1]
line2X2 = lineB[1][0]
#calculate angle between pairs of lines
angle1 = math.atan2(line1Y1-line1Y2,line1X1-line1X2)
angle2 = math.atan2(line2Y1-line2Y2,line2X1-line2X2)
angleDegrees = (angle1-angle2) * 360/(2*math.pi)
print angleDegrees, vertexType
Der Ausgang ich erhalte, ist:
> -299.744881297 same start point; order 1
> 299.744881297 same start point; order 2
> 60.2551187031 same end point; order 1
> -60.2551187031 same end point; order 2
> -119.744881297 one line after another - down; order 1
> 119.744881297 one line after another - down; order 2
> -119.744881297 one line after another - up; line order 1
> 119.744881297 one line after another - up; line order 2
Wie Sie sehen können, bin ich unterschiedliche Werte immer in einem Liniensegment und Liniensegmente, um in der Größenordnung von Eckpunkten abhängig. Ich habe versucht, die Winkel nachzubearbeiten, indem ich herausgefunden habe, welche Art von Beziehung die Quelllinie hatte und die Linien änderte, den Winkel änderte usw. Ich habe mit einem Dutzend solcher Fälle geendet und irgendwann beginnen sie sich zu überlappen und ich kann nicht, ob -119,744 herausfinden, mehr sollte 60,255 (spitzer Winkel) oder gelassen werden, da 119,744 (stumpfer Winkel) wird usw.
gibt es eine diskrete Art und Weise die Ausgangswinkelwert I erhalten von math.atan2
bekommen nur einen zu verarbeiten positiver Wert im Bereich von 0 bis 180?Wenn nicht, welche Art von anderen Ansatz sollte ich nehmen?
Der Kern des Test-Code und Ausgabe ist [hier] (https://gist.github.com/abhinavrk/2100332f7d7f4c127b8c) –
danke für das Code-Snippet, groß, um mit zu beginnen. Das Problem mit dem Code ist, dass er keine stumpfen Winkel meldet (> 90). Versuchen Sie sich mit der '' lineA = ((0.6,3,6), (1,6,3)) lineB = ((1,6,3), (2,3,6)) ". Es meldet 87,27, sollte aber 92,73 sein. Was könnte getan werden, um das zu beheben? –
Ich habe meinen Beitrag bearbeitet. Ich glaube, ich habe es behoben, um auch stumpfe Winkel zu geben. Schau mal. –