Autor |
Beitrag |
knittel
      
Beiträge: 71
Erhaltene Danke: 2
Win XP, Win7, openSUSE
Delphi 7
|
Verfasst: Mi 21.08.13 01:44
Hallo allerseits,
Ich hab um einen beliebigen Winkel in der Rahmen von 0 und 360 zu bringen den module Operator verwendet. Einfach result := Winkel mod 360.
Doch sobald es zu negativen Zahlen kommt, ist der Winkel stattdessen
_________________ "Wir können nicht fliehen!" "Wieso nicht?" "Sie haben mir die Schnürsenkel zusammengebunden!" "Die Schweine."
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mi 21.08.13 04:21
Bei x mod y bekommst Du nur ganzzahlige Werte, da Du nur ganzzahlige Werte einsetzen darfst. Aber unabhängig davon, mit
Delphi-Quelltext
solltest Du das gewünschte Ergebnis bekommen.
Und für nicht integer:
Delphi-Quelltext 1:
| y := abs(x - int(x/360)*360); |
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Mi 21.08.13 06:03
oder aber
Delphi-Quelltext 1: 2:
| while (x<0) x:=x+360; x:=x mod 360; |
Für bessere Performance evtl. die 360 durch größere Zahlen ersetzen, z.B. ((maxint div 360)*360)
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Mi 21.08.13 09:13
Für diesen Beitrag haben gedankt: FinnO
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 21.08.13 10:10
Habe nur ich das Gefühl, dass hier mit Kanonen auf Spatzen geschossen wir?
Delphi-Quelltext 1: 2: 3:
| NeuerWinkel := AlterWinkel mod 360; if NeuerWinkel < 0 then NeuerWinkel := NeuerWinkel + 360; |
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mi 21.08.13 11:17
Fast, ich würde sagen:
Delphi-Quelltext 1: 2: 3:
| NeuerWinkel := AlterWinkel mod 360; while NeuerWinkel < 0 do NeuerWinkel := NeuerWinkel + 360; |
Aber das hatte Boldar schon so in etwa
oder ganz ohne mod:
Delphi-Quelltext 1: 2: 3: 4:
| while NeuerWinkel >= 360 do NeuerWinkel := NeuerWinkel - 360; while NeuerWinkel < 0 do NeuerWinkel := NeuerWinkel + 360; |
Das Ding heißt übrigens nicht module sondern modulo
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 21.08.13 11:21
@Xion:
Das while ist unnötig, da das vorherige Modulo schon dafür sorgt, dass der neue Winkel im richtigen Bereich ist. 
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Mi 21.08.13 11:24
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mi 21.08.13 11:29
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 21.08.13 11:58
@Gammatester:
Modulo ist für ganzzahligen Werte. knittel nutzt das ja schon. Sollten allerdings auch nicht-ganzzahlige Typen verwendet werden, hast du natürlich Recht.
@Xion:
Bei XE2 funktioniert Modulo auch bei negativen Werten.
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mi 21.08.13 12:47
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
knittel 
      
Beiträge: 71
Erhaltene Danke: 2
Win XP, Win7, openSUSE
Delphi 7
|
Verfasst: Mi 21.08.13 13:09
ui^^ ne ganze Mengen Antworten. Danke an alle schonmal!
Es war zwar garnicht so sehr das Problem wie ich das löse, dafür verwende ich:
Delphi-Quelltext 1: 2: 3: 4: 5:
| function ClampToAngle(const A: single): single; begin result := Trunc(A) mod 360 + Frac(A); if result < 0 then result := result + 360; end; |
(auf while wollte ich aus Performance-Gründen verzichten)
Ich hab mich nur gefragt warum mod so arbeitet. Ich dachte immer mod würde (an einem Zahlenstrahl erklärt) so arbeiten:
x mod 4
Quelltext 1: 2:
| x: -9|-8|-7|-6|-5|-4|-3|-2|-1|0|1|2|3|4|5| y: 3| 0| 1| 2| 3| 0| 1| 2| 3|0|1|2|3|0|1| |
_________________ "Wir können nicht fliehen!" "Wieso nicht?" "Sie haben mir die Schnürsenkel zusammengebunden!" "Die Schweine."
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Mi 21.08.13 13:39
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Mi 21.08.13 14:20
Hallo,
so ein ähnliches Problem kenne ich bei der Berechnung des Wochentages mit der Zellerschen Formel.
Meine Lösung war (auf Dein Problem angewendet):
Delphi-Quelltext 1: 2: 3: 4:
| result := (winkel + 360) mod 360; oder result := (winkel + 3600) mod 360; oder noch größere Summanden |
Da habe ich kein if, while usw. drin, sondern "nur" eine Addition.
Wahrscheinlich ist das wieder nicht so elegant, aber es funktioniert.
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Mi 21.08.13 14:42
Mathematiker hat folgendes geschrieben : | Da habe ich kein if, while usw. drin, sondern "nur" eine Addition.
Wahrscheinlich ist das wieder nicht so elegant, aber es funktioniert. |
Wie wir inzwischen erfahren haben, will knittel ja doch eigentlich Singlewinkel normalisieren und wählt einen Weg über trunc() mod 360 + frac(). Selbst wenn man Deinen Ansatz einsetzen würde, hätte man
Delphi-Quelltext 1:
| result := (Trunc(A) + 3600) mod 360 + Frac(A) | Trotzdem käme man wegen des möglichen negativen Frac(A) praktisch nicht um ein if herum, weil das Ergebnis noch negativ sein kann (oder man müßte noch mehr Aufwand treiben um ein if zu vermeiden).
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mi 21.08.13 15:03
Gammatester hat folgendes geschrieben : | Tranx hat folgendes geschrieben : | Alternativ: Um die FALSCHE Formel zu verbessern: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| y := abs(x - int(x/360)*360); if y <0.0 then y := y + 360;
korrekt: if x<0.0 then y := 360.0 + x - 360*int(x/360) else y := x - 360*int(x/360); | | Das ist nun definitiv Unsinn. y=abs() kann nicht negativ sein, also bringt die if-Anweisung überhaupt nichts, und -30 wird immer noch in +30 umgewandelt und nicht in 330. |
Entschuldigung, dass ich das abs nicht gelöscht hatte
bei 30 ergibt das 30 - 360*0 = 30 bei -30 : 360 - 30 - 360*0 = 330
bei 750 ergibt das 750 - 360*2 = 30 bei -750: 360 - 750 - 360*-2 = 330
Das sollte nun korrekt sein.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mi 21.08.13 15:17
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Mi 21.08.13 15:18
Langsam glaube ich auch an die Kanonen/Spatzen-Theorie von jasocul. Alles wäre einfacher, wenn Delphi ein mathematisch korrektes mod hätte, das auch für Fließkommazahlen definiert wäre, ähnlich fmod in C. Man kann es natürlich mit floor aus der Math-Unit nachbilden und hätte dann (ohne if):
Delphi-Quelltext 1: 2: 3: 4:
| function ClampToAngle(const A: single): single; begin result := A - floor(A/360.0)*360.0; end; |
Für diesen Beitrag haben gedankt: knittel
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mi 21.08.13 15:21
ok, gammatester hat wohl damit den thread beendet
das ist die einfachste und warscheinlich schnellste methode
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Mi 21.08.13 15:26
IhopeonlyReader hat folgendes geschrieben : | Gammetester.. es bleibt dabei -0,12° <> 0,12° sondern = 359,88° ! |
Huh  Meine Funktion liefert die 359,88°, vielleicht hast Du nicht mitbekommen, daß 0,12° nicht das gewünschte Ergebnis ist. - Oder ich bin im Tran und mache dann besser Schluß für heute.
(Noch'n Mist): Ist wohl durch ein Edit von IhopeonlyReader überholt.
|
|