Quote: "Posted by ZeroGravity
You may find this useful -
http://www.gamasutra.com/features/20000228/ulrich_02.htm
.. at least, thats how I'm going about it, just as soon as I work out how to go to a spherical coordinate system."
Hmm, I'll look into that article a little more closely. I was only able to glance at it during my brief time before I came here to work, so I'll give it a good perusal later tonight when I get back home.
Primarily, I wanted to come here and post a response I received from the alt.fan.elite newsgroup from someone going by "Nagy Daniel", where I also asked this question. While I haven't tried his method (just got it this morning as well), it looks promising and the guy gave a pretty good description. He also used C source, but it's the concept that's important, I think. Here's his response in full (it's somewhat long):
Quote: "from alt.fan.elite by Nagy Daniel
Hi,
The main problem in this case is that planets are "supported" by their
centers, and you calculate your distance relative to this center, while you are in space.
In the amosphere (few dozen kilometers above the surface, while the
planet's diameter is more than ten thousand kilometers), that approach
doesn't work, because of floating-point instability.
In these cases you want to set your origin to some point on the surface, like in a flight simulator. In order to have seamless transition, your surface cannot be a plane, because the horizon is still quite curved when the planet centered frame of reference starts wreaking numerical havoc. This switching is actually quite noticable in Frontier, but other numerical problems (like floating mountains and buildings) dwarf it.
My solution to this problem are the following two short fuctions (feel
free to replace float by double, but if you get everything right, you
don't have to):
/* parallel projection onto a unit sphere */
float belowHorizon(float rsquare)
{
return ((((rsquare/24)*rsquare+0.0625)*rsquare+0.125)*rsquare+0.5)*rsquare;
}
/* stereographic projection onto a unit sphere */
float aboveSurface(float rsquare)
{
return ((((rsquare*-0.0390625)*rsquare+0.0625)*rsquare-0.125)*rsquare+0.5)*$
}
Both deal with the transformation (bending) of a surface-based cartesian frame of reference. Throughout the following discussion I use a frame of reference such that the z axis is radial (vertical), x and y axes are perpendicular to each other and tangential (horizontal). rsquare denotes the sum of the squares of x and y.
The first function tells you how much below your horizon is the ground at a given distance. In other words, it returns a z coordinate such that that (x,y,-z) is a point on the surface.
The second one is a bit trickier to grasp, but it is equally useful. It tells you what the altitude of (x,y,0) is. Note, that the two are NOT the same, because the altitude of (x,y,0) is measured towards the center of the planet and not in a direction that is parallel to your "down" (z).
Of course, as rsquare approaches zero, these two return increasingly
similar results. During the final approach (a few kilometers above the
ground), you can use rsquare/2 for both to speed things up. This way you will have two transitions: a space->stratosphere and a stratosphere->thick atmosphere transition, both perfectly seamless.
The first function, however, implements 1-sqrt(1-rsquare), while the
second one implements sqrt(rsquare+1)-1. If you code them directly, you will face the probem mentioned in the beginning: the differences are several orders of magnitude smaller than 1, so you suffer a loss of significant digits.
In the proposed implementation, everything is measured in planet radius, but multiplication (rescaling) by a constant does not cause any numerical problems, as long as you don't overflow or underflow with the exponent, which is fairly unlikely even with a float precision and meters as a unit (ten thousand kilometers and micrometers are 13 orders of magnitude apart which is still well within 18 orders of magnitude limit -- and I doubt that you need micrometer precision)
You can safely switch to "atmosphere mode" while your altitude is about 1/2 of the planet radius. At this distance, the old planet centered system still works fine, while the proposed approximation works correctly as well. If you are too far away, and rsquare has a chance of exceeding 1/2, you may experience problems with the aproximation. As said before, as you descend further, you can switch to a speedier approximation. Even cheaper would be to switch to 0 (Flat Earth Model) at a later point, but that would be noticable, IMO.
In a final remark, let me tell you that the line of the horizon, which
starts off as a circle, becomes an ellipsis, then a parabola (for a
moment), then a hyperbola, which approaches the straight line, as your
altitude decreases. This may be important if you want to make a dawn
effect.
Good luck with your game!
--
Daniel
"
I'm going to try and fiddle with it later tonight, so hopefully I'll have some luck.
Hopefully they may help some others here, as well, just in case.