Hi Kranioklast,
deine Lösung wird Probleme haben, falls winkel nah bei 0° oder 360° liegt und die berechnung mit plusminus 360° über- bzw. 0° unterschreitet.
Passt nicht da 359°+10° = 369° ist was 9° entspricht. Das könntest Du jetzt mit einer ganzen Reihe von IFs testen und für jeden Sonderfall eine Sonderbehandlung programmieren oder halt eine besser Möglichkeit suchen.
Du kannst z.B. den Winkel zwischen a und b leicht ausrechnen indem du b von a abziehst (vorausgesetzt b < a sonst a von b abziehen) und die Differenz mit plusminus vergleichst.
Code: Alles auswählen
def etwa_gleich(testwinkel, winkel, plusminus):
if testwinkel >= winkel:
abstand = testwinkel-winkel
else:
abstand = winkel-testwinkel
return abstand <= plusminus
so das löst aber noch nicht obiges Problem wenn der Bereich zwischen testwinkel und winkel die 0° bzw 360° überschneidet.
Hier hilft uns der Modulo, der dafür sorgen kann, daß der Bereich immer zwischen 0 und 360° bleibt. Da Irgendeinwinklel % 360 immer im Bereich 0 - 359 ist.
Schauen wir uns nochmal ein Beispiel an:
Hier haben wir 2 Gerade die einen Winkel Bilden. Bei genauer Betrachtung gibt es 2 Winkel, einmal obenlinks einen Winkel < 180° und einen untenrechts > 180° Da wir den kleineren Winkel vergleichen wollen, berechnen wir beide und nehmen den kleineren.
Um die Unter-/Überschreitung von 0° bzw. 360° zu kompensieren nehmen wir das jeweilige Ergebnis % 360.0 Da
5 - 355 = -350
und
-350 % 360 = 10
ist.
Code: Alles auswählen
def etwa_gleich(testwinkel, winkel, plusminus):
abstand1 = (testwinkel-winkel)%360.0
abstand2 = (winkel-testwinkel)%360.0
if abstand1 < abstand2:
return abstand1 <= plusminus
else:
return abstand2 <= plusminus
Die if-Abfrage können wir auch durch die eingebaute Funktion min() ersetzen, die aus zwei oder mehr Werten den kleinsten zurückgibt
Code: Alles auswählen
def etwa_gleich(testwinkel, winkel, plusminus):
abstand1 = (testwinkel-winkel)%360.0
abstand2 = (winkel-testwinkel)%360.0
return min(abstand1, abstand2) <= plusminus
Wenn wir jetzt noch auf die Variablen 'abstand1' und 'abstand2' verzichten und die Ausdrücke '(testwinkel-winkel)%360.0' und '(winkel-testwinkel)%360.0' direkt als Parameter an min() übergeben sind wir wieder bei meiner zuerst geposteten Lösung.
Zum Testen noch ein kleines Codestück:
Code: Alles auswählen
def test():
for i in xrange(0, 360, 10):
for j in xrange(0, 360, 10):
print "etwa_gleich(%i, %i, 20) -> %s " % (i, j, str(etwa_gleich(i, j, 20))),
print
Gruß
Dookie