Kann das Sonnensystem im 3D-Raum mit Doppeln (oder Longs) genau dargestellt werden?

15

Ich würde gerne wissen, wie man Koordinaten in einem 3D-Spiel am besten verwaltet, um das gesamte Sonnensystem realistisch zu modellieren, aber auch die kleinsten Bewegungen in einem "Schiff" zu bewältigen (dh vielleicht können wir 1 cm als das kleinste betrachten) akzeptable Bewegung für einen Rahmen). Unterstützen 64-Bit-Doubles (oder 64-Bit-Longs) dies oder treten Überlaufprobleme auf? Wenn nicht, sollten Longs oder Doubles verwendet werden, oder wenn ja, welcher alternative Ansatz ist Ihrer Meinung nach am sinnvollsten, um Positionen im Sonnensystem in einem 3D-Spiel zu modellieren? (dh es wird immer nur ein Teil des Systems auf dem Display angezeigt, basierend auf der Entfernung zum Schiff, oder das System wird irgendwie in einem anderen Koordinatenraum dargestellt usw.)

Nicholas Hill
quelle
Auf welche Sprache zielen Sie ab: C / C ++? Java? Etwas anderes?
Laurent Couvidou
4
@lorancou: Irrelevant, er hat die Größe von explizit angegeben long.
DeadMG
@DeadMG Kann in C / C ++ 32-Bit sein. 64-Bit ist eher ein long long. Aber ja, wie auch immer, nenn es Nitpicking, wenn du willst.
Laurent Couvidou
Verwenden Sie einfach BigInteger. Die meisten Sprachen haben eine Variante davon - ein Ganzzahlwert mit unbegrenzter Größe (Verwendung ist O (log (n)))
ashes999
Das könnte eine Antwort sein, vorausgesetzt das Spiel ist nicht zu rechenintensiv.
Laurent Couvidou

Antworten:

11

Es gibt bereits eine gute Antwort zu ganzen Zahlen, aber ich bin der Meinung, dass Gleitkommazahlen nicht beseitigt werden sollten. In seiner Antwort hat Byte56 die Option gewählt, die maximale Umlaufbahn von Pluto anzustreben, die wahrscheinlich aus dieser Excel-Tabelle stammt , also werde ich mich daran halten.

Das setzt die Grenzen des Sonnensystems an:

7,376,000,000 km = 7,376 × 10 9 km = 7,376 × 10 14 cm × 7,4 × 10 14 cm

Das Gleitkommaformat mit doppelter Genauigkeit bietet eine maximale Genauigkeit von 15 signifikanten Dezimalstellen. Sie haben also Glück: Wenn Ihr Ursprung im Zentrum der Sonne liegt und Sie eine Position um Pluto verwenden, können Sie alle Zentimeter darstellen, z. B. in C ++:

printf("%.0Lf\n", 7.4e14);
printf("%.0Lf\n", 7.4e14 + 1.0);
printf("%.0Lf\n", 7.4e14 + 2.0);

Output:
-------
740000000000000
740000000000001
740000000000002

Wenn Sie Ihr Spiel also auf die Umlaufbahn von Pluto beschränken können, dann herzlichen Glückwunsch! Du hast gerade genug Präzision mit Doppel, um es darzustellen.

Beachten Sie jedoch, dass genug ist es in einer darzustellen Simulation , aber erwarten Sie nicht machen dies schmerzlos. Sie müssen in 32-Bit-Floats konvertieren, möglicherweise Ihren Ursprung ändern, damit Sie eine ausreichende Präzision für die nahen Objekte erzielen, und Sie müssen sich wahrscheinlich auf einige Z-Buffer- und Kamerastumpf-Tricks verlassen, um das alles richtig rendern zu können .

Wenn Sie möchten, dass Ihre Astronauten einige weit entfernte Kometen in der Oort-Wolke besuchen , die viel größer ist, dann ist es vorbei. Ab 10 ^ 16 cm verlieren Sie an Genauigkeit:

printf("%.0Lf\n", 1.0e16);
printf("%.0Lf\n", 1.0e16 + 1.0);
printf("%.0Lf\n", 1.0e16 + 2.0);

Output:
-------
10000000000000000
10000000000000000 <-- oops
10000000000000002

Und es wird natürlich weiter schlimmer.

In diesem Fall möchten Sie möglicherweise einige weiterführende Lösungen ausprobieren. Ich schlage vor, Sie werfen einen Blick auf Peter Freezes Artikel in Game Programming Gems 4: "2.3 Lösen von Genauigkeitsproblemen in großen Weltkoordinaten". IIRC, schlägt er ein System vor, das Ihren Anforderungen entspricht, es ist in der Tat eine Art von mehreren verschiedenen Koordinatenräumen.

Das sind nur ein paar Tipps, wahrscheinlich müssen Sie ein eigenes Rezept verwenden, um dies zum Laufen zu bringen. Jemand, der solche Dinge bereits implementiert hat, könnte Ihnen mehr helfen. Warum nicht zum Beispiel eine E-Mail an die Jungs hinter dem Kerbal Space Program schicken?

Viel Glück mit deinem Spiel!

Laurent Couvidou
quelle
1
Diese Antwort ist gut, weil sie leichter in den 3D-Fließkomma-Raum abgebildet werden kann, der von OpenGL und DirectX verwendet wird, und gute Referenzen hat. Deshalb habe ich es als Antwort markiert :)
Nicholas Hill
Cool :) Als Bonus, da dies alles sehr ungefähr ist, finden Sie in Bruce Dawsons Blog einige ausführlichere Informationen zu Floats: randomascii.wordpress.com/2012/05/20/… .
Laurent Couvidou
17

Angenommen, Pluto ist der "Rand" des Sonnensystems (obwohl einige sagen, dass es bis zu 3 Lichtjahre entfernt ist). Pluto ist in seiner maximalen Umlaufbahn etwa 7.376.000.000 Kilometer von der Sonne entfernt. Das sind 7.37600 × 10 ^ 14 Zentimeter. Verdoppeln Sie den Wert , um den Durchmesser zu erhalten, und Sie erhalten 1.475.200.000.000.000 Zentimeter. Das liegt im Bereich der maximalen Größe von 64-Bit-Längen. Da die Höhe des Sonnensystems im Vergleich zu seinem Durchmesser vernachlässigbar ist, können wir das ignorieren.

Also ja, Sie könnten eine lange verwenden, um Ihre Position im Sonnensystem darzustellen. Tatsächlich könnten Sie Positionen von bis zu 9,75 Lichtjahren mit einer vorzeichenbehafteten Long-Position (double für unsigned) haben.

Beachten Sie, dass dies beim Auffinden von Entfernungen nicht der Fall ist. Die maximale Entfernung, die Sie finden können, ist die Quadratwurzel der maximalen Entfernung, die Sie zurücklegen können. Dies kann durch die Verwendung eines Detaillierungsgradsystems zum Auffinden von Entfernungen überwunden werden. Sie können einige einfache Überprüfungen durchführen, um zu erraten, wie weit die Entfernungen entfernt sind (vergleichen Sie ihre x- und y-Werte). Verwenden Sie dann 1.000.000-Kilometer-Inkremente für große Entfernungen bis hinunter zu Zentimeter-Inkrementen für kleine Entfernungen.

Natürlich stellt sich die Frage, wollen Sie das wirklich? 99,999% des Sonnensystems ist ein völlig uninteressanter leerer Raum. Wenn Sie das Sonnensystem genau abbilden, hoffe ich, dass Sie die Physik nicht genau abbilden. Es dauert lange, um sich im Sonnensystem zurechtzufinden. Viel zu lange für die meisten Leute, um interessiert zu bleiben.

Und warum sollte man überhaupt eine so feine Genauigkeit haben, wenn man nicht auch die Objekte im Sonnensystem mit dieser Genauigkeit modelliert? Hier geraten Sie in Schwierigkeiten. Das Volumen der Sonne beträgt 1.40900 × 10 ^ 18 Kubikkilometer. Auf der Kubikzentimeter-Skala nimmt die Verwendung eines einzelnen Bits zum Darstellen, dass dieser Raum "belegt" ist, 1,4 × 10 ^ 33 Bits oder 1,6 × 10 ^ 23 Gigabyte in Anspruch. Ich denke, Sie haben nicht so viel RAM.

MichaelHouse
quelle
3
Ziemlich genau richtig. Kurzfassung: Schwimmergenauigkeit ist die geringste Sorge.
aaaaaaaaaaa
1
Sie werden mit ganzen Zahlen erhalten überläuft, sogar 64-bit. Raumschiff umkreist Pluto. Versucht die Entfernung vom Raumschiff zur Sonne zu berechnen. Quadrieren. Boom.
Laurent Couvidou
3
Ich bin mit der Behauptung im letzten Absatz nicht einverstanden - die Frage des OP ist so wie sie ist absolut sinnvoll, und man muss nicht damit rechnen, dass tatsächlich Artikel in jedem (Kubik-) Zentimeter vorhanden sind, um eine Genauigkeit von 1 cm auf Positionen zu gewährleisten.
Steven Stadnicki
1
@StevenStadnicki Ziemlich gut, aber selbst im Kilometerbereich sind es immer noch 164.029.188 Gigabyte für 1 Bit pro Kubikkilometer. Es ist vergleichbar mit der Frage nach atomarer Präzision in Ihrem Autotacho. Das ist viel genauer als es sein muss.
MichaelHouse
1
Es ist zu ungenau, auf die AU- oder Lichtjahreskala zu gehen. Da wir über das Sonnensystem sprechen. Lichtjahre oder Parsec wären besser für etwas Größeres, wie einen großen Nebel.
MichaelHouse
2

Sie können verwenden BigInteger, wie auch immer Ihre Programmiersprache es nennt. Es ist eine Ganzzahl mit unbegrenzter Größe. Es lässt sich gut skalieren - im Allgemeinen wird der log(n)Speicher für eine ganze Zahl von Größen verwendet n.

Java und C # haben es; Ich bin sicher, dass andere Sprachen es tun. Wenn nicht, können Sie es dekompilieren und erneut implementieren, ohne zu viel Mühe zu haben.

ashes999
quelle