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)
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!
Assuming Pluto for the "edge" of the solar system (though some say it's as far as 3 light years out). Pluto, at it's maximum orbit is about 7,376,000,000 kilometers from the sun. That's 7.37600 × 10^14 centimeters. Double that to get the diameter and you'll get 1,475,200,000,000,000 centimeters. That's well within the maximum size of a 64 bit long. Since the height of the solar system is negligible compared to its diameter, we can ignore that.
So yes, you could use a long to represent your position in the solar system. In fact, you could have positions out as far as 9.75 light years with an signed long (double for unsigned).
Note that this is not the case for finding distances. The maximum distance you can find is the square root of the maximum distance you can travel to. This can be overcome by using a level of detail system for finding distances. You can do some simple checks to guess how far away the distances are (compare their x values and y values), then use 1,000,000 kilometer increments for large distances down to centimeter increments for small distances.
Of course there's the question of, do you really want to? 99.999% of the solar system is totally uninteresting empty space. If you're accurately representing the solar system, I sure hope you're not accurately representing the physics. It takes a long time to get around the solar system. Way too long for most people to stay interested.
And why even have such fine accuracy unless you're also going to model the objects in the solar system with that accuracy? That's where you'll get into trouble. The volume of the sun is 1.40900 × 10^18 cubic kilometers. On the cubic centimeter scale, using a single bit to represent that that space is "occupied" takes up 1.4 × 10^33 bits or 1.6 × 10^23 gigabytes. I think you don't have that much RAM.
You can use
BigInteger, whatever your programming language calls it. It's an unlimited-sized integer; it scales well -- generally using
log(n) storage for an integer of size
Java and C# have it; I'm sure other languages do. If not, you can decompile and reimplement it without too much hardship.