Hallo Kollegen, ich hänge an einem Problem fest, welches sich so darstellt: Ich muß zu einem laufenden Winkel (Sägezahn 0...2PI) einen Offset hinzu addieren. Das Ergebniss muß dann wieder auf 0...2PI begrenzt sein (Winkelüberlauf). Bis jetzt habe ich die "Begrenzung" so gelöst: if (winkel > PI2) winkel = winkel - PI2 if (winkel < 0.0) winkel = winkel + PI2 was rein mathematisch funktioniert. Jedoch: Wenn der Ursprungs-Sägezahn auf Null springt, dann bekomme ich für einen Zyklus eine umgekehrte Spitze in mein Ergebniss. Ich habe schon viel versucht, jedoch kommt hier das klassische Brett vorm Kopf zum Tragen & ich brauche Unterstützung... Vielen Dank für Eure Ideen! Gruss & frohe Ostern! Frank
Ich verstehe noch nicht so ganz, was der Winkeloffset mit einem Sägezahn zu tun haben soll.
Welche Programmiersprache? Welche Datentypen? Welcher Prozessor? Und evtl. wäre eine Skizze/Foto/Bild nicht schlecht...
Hallo Kollegen, ich verwende einen TriCore 1796, programmiere in C und verwende Float als Datentyp. @Simon: Wenn Du Dir einen Sägezahn mit einer Phasenlage vorstellst und Du aber zum weiteren rechnen soll dieser Sägezahn aber eine andere Phasenlage besitzen. Dazu addiert man einen Offset und man erhält eine neuen Sägezahn jedoch mit einer Phasenverschiebung. Gruss Frank
Hallo Frank, Frank Mayer schrieb: > if (winkel > PI2) winkel = winkel - PI2 > if (winkel < 0.0) winkel = winkel + PI2 Ich nehme an, vorher machst Du die Addition von Winkel und Offset. Dann verstehe ich die zweite Zeile nicht - der Winkel (Sägezahn), kann nicht negativ werden. Aber vielleicht habe ich das Problem noch nicht richtig verstanden. Ich würde es so machen (Pseudocode):
1 | winkel := winkel + Offset |
2 | wenn (winkel > PI2) dann winkel = winkel - PI2 |
oder, falls Offset > PI2 sein kann:
1 | winkel := winkel + Offset |
2 | solange (winkel > PI2) mache |
3 | winkel = winkel - PI2 |
Gruß HolgerT
Für solche Fragestellungen gibts in C den Modulo-Operator. Als Wertebereich des Ergebnisses würde dann z.b. 0<=winkel<PI2 herauskommen.
Hallo Kollegen, wenn ich die Modulo Funktion verwende, die Helmut angesprochen hat: (als Pseudo-Code) winkel = winkel + Offset; winkel = modulo(winkel,PI2); Wie sieht das den in C aus? Danke! Gruss Frank
kann es sein dass PI2 0,5 Pi entspricht? Sieht ähnlich in der cmath Lib aus (glaub ich): PI_2 ist da Pi halbe Schreib mal 2*PI hin, damit die Schreibweise eindeutig ist.
Frank Mayer schrieb:
> Wie sieht das den in C aus?
Zwei Varianten:
1.
winkel = winkel + Offset;
winkel = (winkel < PI2) : winkel ? winkel - PI2;
2.
winkel = winkel + Offset;
if(winkel > PI2)
winkel -= PI2;
Hi Flo, ich kann auch 6.28 oder die Zahl X einführen, was ja dem Rechengang nichts abnimmt. Gruss, Frank
Geht das nicht einfacher mit dem Modulo Operator welcher in C normalerweise Verwendung findet? so in etwa dann: winkel = winkel % (2*pi); oder kurz winkel %= (2*pi); Dann braucht man sich auch nicht drum kümmern wenn der Winkel ein Vielfaches von 2Pi größer ist. Mfg
> Modulo Operator
Der ist in C nur für Integertypen definiert, nicht aber für
Fliesskommazahlen.
> Jedoch: > Wenn der Ursprungs-Sägezahn auf Null springt, dann bekomme ich für einen > Zyklus eine umgekehrte Spitze in mein Ergebniss. Jede Wette: Dein Sägezahn mag zwar auf 0 springen, in deinem float steht aber keine 0, sondern irgendwas in der Form -1E-12. Also eine sehr kleine negative Zahl. Und die ist nun mal kleiner als 0. Willkommen in der realen Welt, in der naive Anwendung von float oder double sofort mit 'seltsamen Verhalten' bestraft wird. Natürlicht nicht sofort, sondern erst dann wenn der Kunde das erste mal zusieht. Bei Fliesskommarechnungen immer ein Epsilon einplanen! Wer float so vergleicht if( irgendwas == wasanderes ) sollte sofort eine mit dem nassen Fetzen übergezogen bekommen if( fabs( irgendwas - wasanderes ) < epsilon ) ist die Art und Weise wie man Fliesskommazahlen miteinander auf Gleichheit vergleicht. Ähnliches gilt auch für < und > Vergleiche. Für Epsilon muss man sich überlegen, wie gross der Rechenfehler an der betreffenden Stelle sein kann und dementsprechend ein Epsilon auswählen.
Okay, sorry das wusste ich nicht. Somit würde ich mich dan bzgl. der Lösung am 2ten Vorschlag von Georg anhalten und es um ne Schleife ergänzen, um sicherzustellen, dass der resultierende Winkel immer zwischen 0 und 2pi liegt. Das könnte dann etwa so aussehen: winkel = winkel + Offset; while(winkel > 2*PI) winkel -= 2*PI; mfg
Hallo Kollegen, um nun die erste Runde zusammenzufassen: - modulo Operator gibt ist hierfür nicht (nur für int) - man muß beide Richtungen abfragen(abfangen) liege ich mit meinem: if (winkel > 2*PI) winkel = winkel - 2*PI if (winkel < 0.0) winkel = winkel + 2*PI so weit neben drann? Zugegeben muß diese Schreibweise einen Fehler beinhalten. Jedenfalls für den Fall, daß der Referenz-Sägezahn gegen Null springt, sonst hätte ich diesen Rücksprung für diesen Zyklus nicht. Ist es etwa die zweite Zeile? Ich versuche es mit dem Vorschlag von stokes.. Vielen Dank für die vielfältige Hilfe! Gruss, Frank
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.