Hi, folgendes Problem: Im Kreis (0°-359°) wird in einer beliebigen Ausrichtung gestartet. Von diesem Punkt aus wird ein Minimum (start-45°) und Maximum (start+45°) berechnet. Soweit so gut. Jetzt kommt eine Eingabe a: 0°-359°. Wie kann man feststellen, ob diese Eingabe zwischen dem Minimum und Maximum liegt. Im normalen Zahlenraum wäre das ja trivial: if(a > min && a < max) ... Wie macht man das beim Kreis? Danke
kreis schrieb: > Im Kreis (0°-359°) wird in einer beliebigen Ausrichtung gestartet. > Von diesem Punkt aus wird ein Minimum (start-45°) und Maximum > (start+45°) berechnet. Keine Ahnung warum ein Minimum bei Start-45 und ein maximum bei Start+45 sein soll aber egal. kreis schrieb: > Jetzt kommt eine Eingabe a: 0°-359°. Wie kann man feststellen, ob diese > Eingabe zwischen dem Minimum und Maximum liegt. Im normalen Zahlenraum > wäre das ja trivial: if(a > min && a < max) ... Ebenfalls mit '<' und '>'. Du musst nur alle Werten die hereinkommen oder die du berechnest normieren. Also auf einen Wert von 0 - 360 oder -180 - +180 bringen.
Das mit dem Minimum ist Applikationsabhängig. Die Werte kommen ja schon normiert rein, oder ich verstehe dich falsch. Beispiel: Start: 30° Min: 30-45 = 344° Max: 30+45 = 75° Jetzt kommt zb 0° rein. Das lässt sich noch prüfen: min< 0 < max Klappt aber bei 350° so nicht mehr: min < 350 !< max
Wenn das Ergebnis kleiner als 0 ist, dann addierst du 360 zu deinem Ergebnis dazu und wenn es größer als 360 ist ziehst du 360 ab. Ganz einfach.
U. B. schrieb im Beitrag #3158534: > sein läßt, statt auf eine positive Gradzahl umzurechnen, dann "überlebt" > die Eigenschaft daß min < max ist und > > (min == -15) < (start == 30 ) < (max == 75) > > schaut dann doch gut aus. Ein Winkel von 350° würde in diesem 90° Sektor liegen. Aber für 350 gilt nicht 340 > min && 340 < max > ...im Zweifel erzähl einfach ein bissl mehr vom Kontext, dann wird wohl > vielleicht noch deutlicher was Du brauchst... Jep. Die ganze Sache kann am Kreis tatsächlich sehr unangenehm sein. Manchmal ist es möglich einen Schritt zurückzutreten, und geometrische Operationen am Kreis von vorne herein gleich zu vermeiden. Kommt aber auf die eigentliche Aufgabenstellung an. Im Falle des TO wird es auf eine Fallunterscheidung rauslaufen, ob man ausgehend von start die 0° für die Berechnung von min oder max überschreiten musste oder nicht. Je nachdem muss dann auch der Winkelvergleich anders ausfallen. Aber wie gesagt: Gerade in der Geometrie lassen sich solche Dinge vermeiden, indem man nicht über Winkel rechnet, sondern in die Vektoralgebra mit Kreuz- und Skalarprodukt eintaucht.
Karl Heinz Buchegger schrieb: > Im Falle des TO wird es auf eine Fallunterscheidung rauslaufen, ob man > ausgehend von start die 0° für die Berechnung von min oder max > überschreiten musste oder nicht. Je nachdem muss dann auch der > Winkelvergleich anders ausfallen. Ohne das jetzt komplett durchdacht zu haben: Du rechnest dir min und max gar nicht explizit aus, sondern merkst dir nur start. Was du, anschaulich erklärt, dann mit deinem zu untersuchenden Winkel machst ist folgendes: Stell dir vor, du hättest eine drehbare Pappscheibe. Auf der markierst du erst mal den Winkel 'start'. Dann trägst du auch noch den zu untersuchenden Winkel ein. Anschliessend drehst du die Scheibe so, dass 'start' auf 0° zu liegen kommt und siehst dir an, ob der dadurch ebenfalls mitgedrehte zu untersuchende WInkel im Bereich +45° bis -45° zu liegen kommt. Also // Scheibe drehen verdreht = winkel - start // den so verdrehten Winkel wieder auf 0 ... 360 normieren while verdreht > 360 verdreht -= 360 while verdreht < 0 verdreht += 360 // und feststellen ob der verdrehte Winkel im 90° Sektor liegt if( verdreht < 45 && verdreht > (360-45) ) .... liegt drinnen Ich denke das müsste klappen, habs aber nicht ausprobiert. Wenn dir die Abfrage zu seltsam vorkommt (obwohl sie ganz logisch ist, wenn man sich die Sache aufzeichnet), kannst du auch den verdrehten Winkel auf -180 bis +180 normieren. Dann wird die Abfrage zu while verdreht > 180 verdreht -= 360 while verdreht < -180 verdreht += 360 if( verdreht > -45 && verdreht < +45 ) ...
Karl Heinz Buchegger schrieb: > // und feststellen ob der verdrehte Winkel im 90° Sektor liegt > if( verdreht < 45 && verdreht > (360-45) ) > .... liegt drinnen > > Ich denke das müsste klappen, habs aber nicht ausprobiert. Eher nicht. Es dürfte selten vorkommen, daß der Wert gleichzeitig kleiner als 45 und größer als 360-45 ist. Ich würde deshalb auch die Normierung auf +/-180° vorschlagen, da es etwas intuitiver ist.
Rolf Magnus schrieb: > Karl Heinz Buchegger schrieb: >> // und feststellen ob der verdrehte Winkel im 90° Sektor liegt >> if( verdreht < 45 && verdreht > (360-45) ) >> .... liegt drinnen >> >> Ich denke das müsste klappen, habs aber nicht ausprobiert. > > Eher nicht. Es dürfte selten vorkommen, daß der Wert gleichzeitig > kleiner als 45 und größer als 360-45 ist. Shit. Du hast natürlich recht. Da müsste ein Oder rein. if( verdreht < 45 || verdreht > (360-45) )
Hi, danke für die Tipps. Die Idee mit der Drehung finde ich gut - probiere ich gleich mal aus!
Kann man nicht intern einfach mit einen Ofset arbeiten? Ich würde da einfach immer 720 oder auch gleich 1000 dazuadieren. Da bleibt man immer im positiven Bereich. Selbst wenn Min = Start -359 und sogar Start selber = -359 ist
Jürgen D. schrieb: > Kann man nicht intern einfach mit einen Ofset arbeiten? > Ich würde da einfach immer 720 oder auch gleich 1000 dazuadieren. > Da bleibt man immer im positiven Bereich. Ob du den Durchgang durch den 0-Winkel jetzt bei 0 oder 360 hast, spielt keine Rolle. Das Problem bleibt weiterhin, dass du jeden Winkel durch beliebige Vielfache von Winkel + n*360 ausdrücken kannst. Und damit hast du dann das Problem, dass dein Minimum aus StartWinkel-45 und Startwinkel+45 numerisch größer als das Maximum sein kann. Bei solchen Sachen: Ausnahmslos immer mit konkreten Zahlenwerten durchprobieren und dabei nicht nur auf den Fall achten, in dem alles wie vorgesehen funktioniert, sondern speziell auch versuchen die Systematik zu Fall zu bringen. Meist wird man dabei recht schnell fündig.
Das lässt sich durch anderes "Verdrehen" vereinfachen. Die von Karl Heinz eingebrachte Pappscheibe wird nicht so verdreht, daß "Start" auf 0° zu liegen kommt, sondern daß "Start - 45°" auf 0° zu liegen kommt. Um zu testen, ob der gewünschte Winkel im Segment [Start - 45°] bis [Start + 45°] liegt, muss vom gewünschten Winkel also "Start - 45°" abgezogen werden. Das Ergebnis kann nun auf 360° normiert werden - ist es negativ, wird so lange 360 addiert, bis es positiv ist, ist es größer als 360, wird so lange 360 abgezogen, bis es kleiner als 360 ist. Damit dieses Resultat nun im Testsegment zu liegen kommt, muss es also kleiner sein als 90°. Beispiel: Start beträgt 75°, der zu testende Winkel beträgt 713°. Das Bezugssystem wird um 75° - 45° gedreht, also um 30°. Diese 30° werden von den 713° abgezogen, also ergeben sich 683°. Das ist noch etwas größer als 360°, die werden also auch noch davon abgezogen. Resultat sind 323°. Das ist größer als 90°, also gibt es keinen Treffer. Zweites Beispiel: Der zu testende Winkel beträgt -323° Durch die Rotation des Bezugssystemes werden daraus -353°. Da das negativ ist, werden 360° addiert, was 7° ergibt. Das ist größer als 0°, und kleiner als 90° -> Treffer.
Das funktioniert noch besser - danke! Zumal in meiner Anwendung die Winkel sich nur zwischen 0 und 359 bewegen können
Rufus Τ. Firefly schrieb: > Das lässt sich durch anderes "Verdrehen" vereinfachen. > > Die von Karl Heinz eingebrachte Pappscheibe wird nicht so verdreht, daß > "Start" auf 0° zu liegen kommt, sondern daß "Start - 45°" auf 0° zu > liegen kommt. gute Idee! Ich hab mich zu sehr auf die Symetrie um 0 herum gestürzt.
kreis schrieb: > Das funktioniert noch besser - danke! Zumal in meiner Anwendung die > Winkel sich nur zwischen 0 und 359 bewegen können schon klar. Aber durch ein Additionen und Subtraktionen bist du schnell mal aus dem Bereich draussen. Nimm start mal mit 350 an und dann teste ob 10 deinen Test bestehen wird. Du wirst negative Zwischenergebnisse kriegen. Daher auch der Rat, sowas immer mit konkreten Zahlenwerten am Papier durchzuprobieren. Nach den ersten paar selbst durchgerechneten (und durchüberlegten) Beispielen wird schnell klar, welche Zwischenergebnisse Probleme machen werden - wie die Zahlenkonstellation sein muss, damit man zwischendurch unangenehme Zwischenergebnisse kriegt.
Eine mögliche Codierung dieser Bedingung:
1 | ((f(w-wmin)>0) & (f(w-wmax)<0)) | ((f(w-wmin+2*pi)>0) & (f(w-wmax+2*pi)<0)) |
wobei w den Testwinkel bezeichnet und die Funktion f definiert ist als
1 | f(x) := x - 4*pi*Round(x/(4*pi)) |
Geht in die gleiche Richtung, deswegen frage ich mal auch hier: Wenn eine Eingabe in Grad kommt, wie kann man feststellen, ob der kürzere Weg links oder rechts herum ist? Ich hab´s im Moment so gelöst, bin aber nicht sicher, obs richtig ist: Start= aktuelle Position Max= start+180 offset=0 if(max>360) max=max-360 if(start>max) offset=360-start ziel=offset+eingabe if(ziel<start) DREHE LINKS if(ziel>start && ziel>max) DREHE LINKS if(ziel>start && ziel<max) DREHE RECHTS auf Papier scheints zu klappen, evtl findet jemand da einen Fehler?
kreis schrieb: > Geht in die gleiche Richtung, deswegen frage ich mal auch hier: > > Wenn eine Eingabe in Grad kommt, wie kann man feststellen, ob der > kürzere Weg links oder rechts herum ist? Wenn ich nachher sowieso auf Vektoren gehe, dann wandle ich die Grad sofort mal in einen Vektor um. Das Vorzeichen des Kreuzproduktes von Zielvektor und Startvektor verrät mir dann die gesuchte Information. Ansonsten: Differenz bilden. Auf 0..360 normieren. Bei 180 ist die Grenze, in welcher Richtung der kürzere Bogen liegt. PS: "Differenz bilden" ist im Grunde schon wieder mal nichts anderes als die bewusste Pappscheibe, die so gedreht wird, dass eine Markierung bei 0 zu liegen kommt und die andere Markierung mitgedreht wird. Anschaulich: wenn dann die andere Markierung zwischen 0 und 180 liegt, dann ist der Bogen gegen den Uhrzeiger kürzer, ansonsten der andere. Edit: Dieses Konzept: verändere die Situation, so dass ein wesentlicher Parameter zu 0 wird (0-Lage, 0-Rotation) findet sich oft in der geometrischen Arbeit. Du solltest seine Möglichkeiten nicht unterschätzen! Überleg dir, ob dein 'Problem' besonders einfach wird, wenn das Problemumfeld in 'Ausgangslage' (also 0-Koordinaten, 0-Lage, 0-Rotation) vorliegen würde. Wenn du da sofort eine (zumindest konzeptionell richtige) Lösung angeben kannst, dann ist genau das der Weg, den man geht. Zb: Schnittpunkte zwischen 2 beliebigen Kreisen in der Ebene finden. Hätte einer der beiden Kreise seinen Mittelpunkt im Koordinatenursprung, dann wird das Problem einfacher zu lösen. Liegt der Mittelpunkt des anderen Kreises dann auch noch zb auf der X-Achse, dann vereinfacht sich alles nochmal. Im allgemeinen Fall, mit beliebigen Mittelpunkten werden die Gleichungen ekelhaft, aber durch Verschieben eines Kreises in den Ursprung wird alles wieder einfacher handhabbar. Natürlich muss man die gefundenen Schnittpunkte dann wieder zurückverschieben. Aber im Vergleich zu den ekelhaften Gleichungen im allgemeinen Fall sind das Peanuts.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.