16
\$\begingroup\$

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)

\$\endgroup\$
5
  • \$\begingroup\$ What language are you targeting: C/C++? Java? Something else? \$\endgroup\$ Commented May 22, 2012 at 19:45
  • 4
    \$\begingroup\$ @lorancou: Irrelevant, he explicitly specified the size of long. \$\endgroup\$
    – DeadMG
    Commented May 22, 2012 at 19:53
  • \$\begingroup\$ @DeadMG Which can be 32-bit in C/C++. 64-bit is more of a long long. But yeah, whatever, call it nitpicking if you want. \$\endgroup\$ Commented May 22, 2012 at 21:52
  • \$\begingroup\$ Just use BigInteger. Most languages have some variant of it -- an unlimited size integer value (usage is O(log(n))) \$\endgroup\$
    – ashes999
    Commented May 23, 2012 at 0:09
  • \$\begingroup\$ That could be an answer, provided the game is not too heavy on computing. \$\endgroup\$ Commented May 23, 2012 at 8:11

3 Answers 3

11
\$\begingroup\$

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!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This answer is good because it maps more easily into 3d floating point space used by the likes of OpenGL and DirectX, and has good references. Therefore, I have marked it as the answer :) \$\endgroup\$ Commented May 26, 2012 at 21:23
  • \$\begingroup\$ Cool :) As a bonus, as this is all very approximate, you'll find some more in-depth infos about floats in Bruce Dawson's blog: randomascii.wordpress.com/2012/05/20/…. \$\endgroup\$ Commented May 27, 2012 at 23:12
17
\$\begingroup\$

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.

\$\endgroup\$
11
  • 3
    \$\begingroup\$ Pretty spot on. Short version: Float accuracy is the least of your worries. \$\endgroup\$ Commented May 22, 2012 at 20:01
  • 1
    \$\begingroup\$ You will get overflows with integers, even 64-bit. Spaceship orbits around Pluto. Tries to compute distance from spaceship to sun. Squaring. Boom. \$\endgroup\$ Commented May 22, 2012 at 23:22
  • 3
    \$\begingroup\$ I disagree strongly with the assertion in the last paragraph - the OP's question makes perfect sense as is, and one doesn't need to expect to actually have items in every (cubic) centimeter to care about an accuracy of 1cm on positions. \$\endgroup\$ Commented May 23, 2012 at 0:28
  • 1
    \$\begingroup\$ @StevenStadnicki Fair enough, but even at the kilometer scale it's still 164,029,188 gigabytes for 1 bit per cubic kilometer. It's akin to asking for atomic precision in your car speedometer. That's just way more accurate than it needs to be. \$\endgroup\$
    – House
    Commented May 23, 2012 at 0:50
  • 1
    \$\begingroup\$ Well, going to the AU or light year scale is too imprecise. Since we're talking about the solar system. Light years or parsecs would be better for something larger, like a large nebula. \$\endgroup\$
    – House
    Commented May 23, 2012 at 15:19
2
\$\begingroup\$

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 n.

Java and C# have it; I'm sure other languages do. If not, you can decompile and reimplement it without too much hardship.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .