Welches Genauigkeit von PI brauche ich für 3D-Grafik?
-
Das hat nicht wirklich einen praktischen Nutzen für mich, sondern hat mich nur mal so interessiert. Wer z.B mit FixedPoint arbeitet muss sich ja auch zwangsläufig auf ein paar Stellen beschränken und mich interessiert halt ab welcher Stelle die Schwelle ist an der es zu Problemen kommen kann, also Ruckler zum Beispiel.
Wenn die Schwelle hier allerdings noch niemand probiert hat, kann auch niemand darauf konkret antworten. Meine Engine ist leider noch nicht so weit, als dass ich es schon selbst testen könnte und mit anderen will ich jetzt nicht rum spielen dafür.
-
Lichtweite schrieb:
Ok danke für die Antworten, dann gibt es anscheinend darauf keine klare Antwort.
Was ausreichend ist hängt stark davon ab welche Berechnungen du anstellst. Es gibt immer viele Möglichkeiten ein Problem anzugehen, man kann es doof machen oder schlau.
Wenn du es schlau machst ist für 3D Sachen float normalerweise ausreichend.
Wenn du es doof machst ist double zu wenig.
Dass in den Berechnungen Pi vorkommen oder nicht spielt dabei nicht wirklich eine Rolle.Und natürlich wirst du Pi mit der maximalen Genauigkeit des verwendeten Typs definieren - etwas anderes würde ja kaum Sinn machen.
-
Wieso fragst du nach Pi? Pi ist auch nur irgendeine Zahl wie jede andere auch.
Anstatt zu fragen "Welche Genauigkeit von PI brauche ich für 3D-Grafik?", kannst du fragen "Welche Genauigkeit von <Zahl> brauche ich für 3D-Grafik?".
Was eine Frage nach dem zu verwenden Datentypen ist: "Welche Genauigkeit brauche ich für 3D-Grafik?".Und das wurde schon mehrfach gesagt!
-
Pi ist mir nur eingefallen da man es und ein paar Terme damit als Konstanten definiert. Die Frage ging aber, wie du richtig erkannt hast, in die Richtung, wie viele Stellen nach dem Komma ich minimal brauche um noch vernünftig 3D Transformationen etc. machen zu können?
Ich bin mir mittlerweile schon gar nicht mehr sicher ob meine Frage überhaupt einen Sinn ergibt, wenn alle hier mit den Schultern zucken^^ Praktisch nutze ich jetzt Konstanten mit sechs Stellen hinter dem Komma.
-
Kannste abschätzen: guck die Kondition deiner Transformationsmatrizen an und mach ne Fehlerabschätzung.
-
const double PI = 4.0 * atan(1);
-
Th69 schrieb:
const double PI = 4.0 * atan(1);
Das ist jetzt hoffentlich nicht dein Ernst.
-
Lichtweite schrieb:
Praktisch nutze ich jetzt Konstanten mit sechs Stellen hinter dem Komma.
Warum nutzt du überhaupt Festkommazahlen?
-
Ich nutze FP für Fälle wo auf der Zielplattform keine FPU vorhanden ist únd ansonsten floats, wo ich aber auch PI und die üblichen Formen davon, wie PI Halbe, 1/PI etc gleich als Konstanten für Lookup-Tables oder schnelle Sinus-Annäherungen etc. verwende.
@ScottZhang: Interessant, inverse Matrix kenne ich, aber eine Normalform einer Matrix habe ich noch nie gebildet, geschweige denn aus deren Produkt dann die Kondition ausgerechnet.
-
Du schreibst 3D Anwendungen für embedded systems? Vielleicht solltest du mal etwas genauer beschreiben was du da eigentlich vor hast.
-
Ich schreibe eine kleine 3D-Engine von der Picke auf ohne Hardwareunterstützung, die halt auch mal eventuell auf verschiedenen Mikrocontrollern laufen soll. Es ist aber nur ein Lernprojekt und wird wahrscheinlich nie irgend jemanden nutzen. Wenn es meine Horizont für die 3D-Programmierung erweitert und ich durch dieses Projekt viel lernen kann, dann hat es sein Ziel schon erreicht.
Ich möchte es in C aber auch in C++ umsetzen, um so auch beide Sprachen mal wirklich an einem mittleren Projekt in Aktion zu erleben.
-
Hmja, ich mein nur. Mir scheint 3D Grafik ohne FPU irgendwie witzlos zu sein. Wobei - für Rotationen macht es sogar irgendwie Sinn, bei 360° fängt man ja wieder von vorne an. Und jetzt, wo ich drüber nachdenke, macht es eigentlich auch für Positionen Sinn, schließlich will man ja eine gleichverteilte Präzision, und keine die relativ zum Nullpunkt immer schlechter wird. Kann mir mal jemand erklären warum wir floats für den Quatsch nutzen?
Lichtweite schrieb:
Ich möchte es in C aber auch in C++ umsetzen, um so auch beide Sprachen mal wirklich an einem mittleren Projekt in Aktion zu erleben.
Könnte interessant werden - allerding leider nur wenn du auch beide Sprachen gut beherrschst.
-
Lichtweite schrieb:
Hi,
PI wird ja heute bis auf Millionen von Stellen nach dem Komma berechnet, tatsächlich braucht es aber für die meisten Berechnungen nur recht wenige Stellen. Wie viele Stellen sind denn eurer Meinung nach für die Berechnung von 3D Grafik notwendig, also für Rotationen etc.?
Wenn Du Berechnungen durchführst, spielt es keine Rolle, ob Du mit 3 rechnest, mit 3.14 oder einer Million Stellen. Eine Operation dauert so lange, wie eine Operation dauert. In ein Float oder Double passt eine gewisse Größe rein, nicht mehr. Nimmst Du weniger Stellen wird der Algorithmus nicht schneller. Willst Du mehr Stellen musst Du aufwendigere Geschichten fahren, das wird tierisch langsam. Das willst Du vermutlich auch nicht.
Bei Winkeln wirst Du sowieso schnell merken, dass Ungenauigkeiten im Kreis mit dem Radius zusammenlaufen. Ein Winkel wird bei maximaler Genauigkeit durch den Radius schnell in einen kritischen Bereich multipliziert, so dass Du hier schnell in aus der Epsilontik läufst und Deine Ergebnisse genauso gut Würfeln kannst.
Für die Frage gibt es also nur eine sinnvolle Antwort: Pack rein, was in Dein Register passt und hoffe dass es reicht. Dann wird es nämlich richtig interessant. ^^
-
@Xin Da er ja mit Festkommazahlen rechnet, wollte er wahrscheinlich wissen an welche Stelle er das Komma setzen soll - das ist ja nicht ganz klar auch bei gegebener Registergröße.
-
cooky451 schrieb:
@Xin Da er ja mit Festkommazahlen rechnet, wollte er wahrscheinlich wissen an welche Stelle er das Komma setzen soll - das ist ja nicht ganz klar auch bei gegebener Registergröße.
Double hat maximal 53 Nachkommastellen (binär). Das sind ca. 15 dezimale Stellen. Und das reicht nicht immer. Solange sich der Winkel im Bereich von 0 bis pi befindet, gehen vorne auch mal gleich 2 weitere Stellen verloren, bleiben also nur 51 binäre Stellen.
Wie immer ist die Frage mit welchen Größen er arbeitet und wie er sie verrechnet.
Vermutlich werden die Strecken weniger Nachkommastellen benötigen, als die Winkel, es stellt sich also schon die Frage, ob Winkel und Strecken mit dem gleichen Datentyp gespeichert werden sollten, weil sich das Komma an unterschiedlichen Punkten befindet, bzw. die Strecken und Winkel auf einen Wertebereich abgeglichen werden müssen.Diesen Abgleich macht man bei Fließkommazahlen mit dem Exponenten. Wenn man den einsparen kann, kann man natürlich größere Mantissen speichern. Dafür sollte bei Winkeln das Festkomma bei Bit 61 stehen. Die Strecken wird er aber vermutlich nicht im Bereich von -4.9 bis +4.9 halten wollen, dann würde ein Radius ihm auch kaum Probleme bereiten.
-
Doch Sone, das meine ich Ernst, s. z.B. http://stackoverflow.com/questions/1727881/how-to-use-the-pi-constant-in-c
Alternativ ebenconst double PI = acos(-1.0);
Der Compiler kann es eben exakt ausrechnen mit maximalen Nachkommastellen (je Architektur).
Natürlich nur sinnvoll, wenn Intrinsics aktiviert sind bzw. die Berechnung nur genau einmal am Anfang des Programms durchgeführt wird.Du kannst natürlich auch PI als Literal verwenden (3.14...). Aber entweder du gibst unnötigerweise zu viele Nachkommastellen an oder eben zu wenig. Wer weiß, vllt. gibt es in einigen Jahrzehnten den Datentyp 'double' mit 100 Nachkommastellen und dort steht dann nur PI = 3.14159265.
Dann würde mein Programmcode trotzdem mit bestmöglicher Genauigkeit arbeiten und der mit dem festdefinierten Literal nicht.
-
Gut, ich sehe ein, das macht doch Sinn.
-
Nur vorsichtig sein wegen dem Typ. Wenn du mit float Werten rechnest, willst du auf jeden Fall pi auch als float definieren und auf keinen Fall als double. float und double willst du nicht nur aus rein ästhetischen Gründen auf keinen Fall vermischen, sondern vor allem auch, da der Compiler sonst gezwungen ist, langsamen Code zu produzieren, was du wohl vor allem in einem Software-Renderer vermeiden willst...
Btw: Rotationswinkel kann man sehr elegant als Normalized Integer darstellen...
-
Th69 schrieb:
Doch Sone, das meine ich Ernst, s. z.B. http://stackoverflow.com/questions/1727881/how-to-use-the-pi-constant-in-c
Alternativ ebenconst double PI = acos(-1.0);
Der Compiler kann es eben exakt ausrechnen mit maximalen Nachkommastellen (je Architektur).
Natürlich nur sinnvoll, wenn Intrinsics aktiviert sind bzw. die Berechnung nur genau einmal am Anfang des Programms durchgeführt wird.Sorry, aber ich halte das auch für Unfug.
Es ist zwar "sicher", in dem Sinn dass keine Fehler passieren werden, aber es kann unnötigerweise bremsen.
Bzw. ich behaupte mal: es *wird* unnötigerweise bremsen. Mag sein dass einige Compiler schlau genug sind das optimieren zu können. Dem mit dem ich gerade arbeite (MSVC 2005) traue ich die Optimierung aber nicht zu.
Und vor allem garantiert dir keiner dass es vom Compiler deiner Wahl *immer* korrekt optimiert wird.
Irgendwann änderst du was und die Optimierung "bricht" und dann läuft dein Programm unnötiger weise langsamer.In den meisten Fällen wird es natürlich nicht viel ausmachen. Für Quatsch halte ich es trotzdem.
-
dot schrieb:
Nur vorsichtig sein wegen dem Typ. Wenn du mit float Werten rechnest, willst du auf jeden Fall pi auch als float definieren und auf keinen Fall als double. float und double willst du nicht nur aus rein ästhetischen Gründen auf keinen Fall vermischen, sondern vor allem auch, da der Compiler sonst gezwungen ist, langsamen Code zu produzieren, was du wohl vor allem in einem Software-Renderer vermeiden willst...
Btw: Rotationswinkel kann man sehr elegant als Normalized Integer darstellen...
Danke, nettes Forum, habe mich gleich mal angemeldet.