Monday, July 29, 2019

Can the solar system be accurately represented in 3d space using doubles (or longs)?


I would like know to how to best manage coordinates in a 3D game whose aim is to realistically model the entire solar system, yet be able to handle the smallest movements in a "ship" (ie: perhaps we can consider 1cm to be the smallest acceptable movement for a frame). Do 64-bit doubles (or 64-bit longs) support this, or do we run into overflow problems? If not, then should longs or doubles be used, or if so, then which alternative approach do you think is the most sensible for modelling positions in the solar system in a 3D game? (ie: only holding a bit of the system in the display at a time based on distance to ship, or having the system somehow represented in a different co-ordinate space etc)



Answer



There's already a good answer about integers, but I feel like floating-points shouldn't be eliminated. In his answer, Byte56 took the option to go for the maximum orbit of Pluto, probably taken from this excel sheet, so I'll stick to that.


That places the solar system boundaries at:


7,376,000,000 km = 7.376x10^9 km = 7.376x10^14 cm ≈ 7.4x10^14 cm


The Double-Precision floating-point format offers a maximum precision of 15 significant decimals. So you're lucky: if your origin is at the Sun's center and you use a position around Pluto, you can represent all centimeters, e.g. 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

So if you can limit your game to the orbit of Pluto, then congratulations! You've got just enough precision with doubles to represent it.


Beware though, that's enough to represent it in a simulation, but don't expect to render this painlessly. You'll have to convert to 32-bit floats, maybe change your origin so you get enough precision on the close objects, and you'll probably have to rely on some Z-buffer and camera frustum trickery to get all this to render properly.


Now, if you want your astronauts to visit some far away comets in the Oort cloud, which is way bigger, then it's over. Around 10^16 cm, you start loosing accuracy:



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

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


And it gets worse further on, of course.


So if you're in this case, you might want to try some more advanced solutions. I suggest you take a look at Peter Freeze's article in Game Programming Gems 4: "2.3 Solving Accuracy Problems in Large World Coordinates". IIRC, he suggest a system that might suit your needs, it's indeed some kind of multiple different co-ordinate spaces.


That's just some hints, you'll probably have to use some recipe of you own to get this running. Somebody that already implemented that kind of stuff might help you more. Why not firing an email to the guys behind Kerbal Space Program for instance?


Good luck with your game!


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...