Winkel zwischen Liniensegmenten berechnen (Python) mit math.atan2

Ich arbeite an einem räumlichen Analyseproblem und Teil dieses Workflows ist die Berechnung des Winkels zwischen verbundenen Liniensegmenten.

Jedes Liniensegment besteht aus nur zwei Punkten, und jeder Punkt hat ein Paar von XY-Koordinaten (kartesisch). Hier ist das Bild von GeoGebra.Ich bin immer daran interessiert, einen positiven Winkel im Bereich von 0 bis 180 zu erhalten. Ich erhalte jedoch alle möglichen Winkel, abhängig von der Reihenfolge der Eckpunkte in den Eingabezeilensegmenten.

Die Eingabedaten, mit denen ich arbeite, werden als Tupel von Koordinaten angegeben. Abhängig von der Scheitelpunkterstellungsreihenfolge kann der letzte / Endpunkt für jedes Liniensegment unterschiedlich sein. Hier sind einige der Fälle im Python-Code. Die Reihenfolge der Liniensegmente, in der ich sie erhalte, ist zufällig, aber in einem Tupel von Tupeln ist das erste Element der Startpunkt und das zweite der Endpunkt.DE Liniensegment hätte zum Beispiel((1,1.5),(2,2)) und die(1,1.5) ist der Startpunkt, da er die erste Position im Tupel der Koordinaten hat.

Ich muss jedoch sicherstellen, dass ich den gleichen Winkel zwischen @ bekomDE,DF undED,DF und so weiter

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 Linien als Argumente verwendet und den Winkel zwischen ihnen berechnet. Ich benutze dasmath.atan2 das schien am besten dafür geeignet zu sein.

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

Die Ausgabe, die 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, erhalte ich abhängig von der Reihenfolge der Eckpunkte in einem Liniensegment und der Reihenfolge der Liniensegmente unterschiedliche Werte. Ich habe versucht, die Winkel nachzubearbeiten, indem ich herausgefunden habe, welche Beziehung die Quelllinie hatte, die Linien gekippt, den Winkel bearbeitet usw. Ich habe mit einem Dutzend solcher Fälle geendet und irgendwann fangen sie an, sich zu überlappen, und ich kann nicht mehr herausfinden, ob -119.744 zu 60.255 (spitzer Winkel) oder zu 119.744 (stumpfer Winkel) usw. werden soll.

ibt es eine diskrete Möglichkeit, die von @ empfangenen Ausgangswinkelwerte zu verarbeitemath.atan2 um nur einen positiven Wert im Bereich von 0 bis 180 zu erhalten? Wenn nicht, welchen anderen Ansatz soll ich wählen?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage