Winkel zwischen allen Kanten für jeden Knoten in einem Netzwerk berechnen
Verfasst: Dienstag 15. März 2016, 12:10
Hallo liebe Community,
ich habe folgendes Problem, das ich an einem Beispiel vereinfacht habe:
Es gibt ein Netzwerk mit 7 Knoten mit Koordinaten sowie Kanten zwischen den Knoten, dargestellt durch eine Liste mit Tuples der Knoten und x-, y-Koordinate sowie ein Dictionary mit den Verbindungen von jedem Knoten ausgehend:
Ich möchte für jeden Knoten alle umliegenden Winkel ausrechnen, d.h. den Winkel zwischen nebeneinanderleigenden Kanten die vom Knoten ausgehen. Die Summe der Winkel um einen Knoten muss dementsprechend 360° betragen.
Ich habe das ganze mal noch grafisch veranschaulicht. An Knoten 6 sieht man z.B., dass drei Winkel berechnet werden müssten, bei Knoten 5 wären es aber ganze fünf:

Die Winkelberechnung vom Knoten a (origin_a) zu zwei anderen Punkten b und c lässt sich leicht über den Kosinussatz berechnen:
Klar ist, dass über jeden Knoten im connections_from_nodes Dictionary iteriert werden muss um die Winkel für jeden Knoten zu erhalten.
Die Winkel sollten wiederum in einem Dictionary nach gleichem Schema mit {Knoten1: [Winkel1, Winkel2, ...], Knoten2: ...} gespeichert werden.
Jetzt brauche ich nur noch einen Algorithmus, der mir auch wirklich nur die gesuchten Winkel zurückgibt und das für Knoten mit beliebig vielen angrenzenden Kanten.
Bisher habe ich es nur geschafft die Winkel von jeder Kante zu jeder anderen Kante von einem Knoten zu berechnen. Das Problem ist, dass ich nicht weiß, in welcher Reihenfolge die Kanten um einen Punkt auftreten. Z.B. bei Knoten 6, sehe ich, dass ich die Winkel Zwischen 7 und 5, 5 und 1 sowie 1 und 7 berechnen muss, aber wie finde ich das für jeden Knoten algorithmisch heraus?
Problematisch ist auch, dass die Winkelfunktion oben immer einen Winkel < 180° zurückgibt, sodass man bei einigen Winkeln diese noch von 360° abziehen müsste.
Vielleicht hat ja jemand eine Idee...
Danke euch schon mal,
Michael
ich habe folgendes Problem, das ich an einem Beispiel vereinfacht habe:
Es gibt ein Netzwerk mit 7 Knoten mit Koordinaten sowie Kanten zwischen den Knoten, dargestellt durch eine Liste mit Tuples der Knoten und x-, y-Koordinate sowie ein Dictionary mit den Verbindungen von jedem Knoten ausgehend:
Code: Alles auswählen
nodes = [(1, 1, 2), (2, 7, 2), (3, 7, 1), (4, 9, 6), (5, 3, 4), (6, 2, 6), (7, 6, 7)]
connections_from_nodes = {1: [6, 5, 2], 2: [1, 5, 4, 3], 3: [2, 4], 4: [7, 5, 2, 3], 5: [1, 2, 4, 7, 6], 6: [1, 5, 7], 7: [5, 6, 4]}
Ich habe das ganze mal noch grafisch veranschaulicht. An Knoten 6 sieht man z.B., dass drei Winkel berechnet werden müssten, bei Knoten 5 wären es aber ganze fünf:

Die Winkelberechnung vom Knoten a (origin_a) zu zwei anderen Punkten b und c lässt sich leicht über den Kosinussatz berechnen:
Code: Alles auswählen
def get_angle(origin_a, point_b, point_c, nodes):
a = math.sqrt((nodes[point_b][1] - nodes[point_c][1])**2 + (nodes[point_b][2] - nodes[point_c][2])**2)
b = math.sqrt((nodes[origin_a][1] - nodes[point_c][1])**2 + (nodes[origin_a][2] - nodes[point_c][2])**2)
c = math.sqrt((nodes[origin_a][1] - nodes[point_b][1])**2 + (nodes[origin_a][2] - nodes[point_b][2])**2)
cos_alpha = (b**2 + c**2 - a**2) / (2*b*c)
alpha = math.degrees(math.acos(cos_alpha))
return alpha
Die Winkel sollten wiederum in einem Dictionary nach gleichem Schema mit {Knoten1: [Winkel1, Winkel2, ...], Knoten2: ...} gespeichert werden.
Jetzt brauche ich nur noch einen Algorithmus, der mir auch wirklich nur die gesuchten Winkel zurückgibt und das für Knoten mit beliebig vielen angrenzenden Kanten.
Bisher habe ich es nur geschafft die Winkel von jeder Kante zu jeder anderen Kante von einem Knoten zu berechnen. Das Problem ist, dass ich nicht weiß, in welcher Reihenfolge die Kanten um einen Punkt auftreten. Z.B. bei Knoten 6, sehe ich, dass ich die Winkel Zwischen 7 und 5, 5 und 1 sowie 1 und 7 berechnen muss, aber wie finde ich das für jeden Knoten algorithmisch heraus?
Problematisch ist auch, dass die Winkelfunktion oben immer einen Winkel < 180° zurückgibt, sodass man bei einigen Winkeln diese noch von 360° abziehen müsste.
Vielleicht hat ja jemand eine Idee...
Danke euch schon mal,
Michael