Spherical coordinates for orbital motion

Started by
4 comments, last by apatriarca 11 years, 6 months ago
Hi, I've been working on getting some object to orbit around another object by using a spherical coordinate system. This has worked fine when the object is orbiting horizontally and vertically, however if you try to get the object orbiting diagonally it runs into issues with converting the spherical coordinates back to Cartesian coordinates.

All orbiting objects start with an initial theta, phi, and radius values and also a 2D heading vector to specify the orbit.

Then every frame this information is updated in the following way:


direction = Vector2.Normalize(direction);
theta += timeDelta * direction.X * orbitSpeed;
phi -= timeDelta * direction.Y * orbitSpeed;


pos.X = radius * (float)Math.Cos(theta) * (float)Math.Sin(phi);
pos.Y = radius * (float)Math.Cos(phi);
pos.Z = radius * (float)Math.Sin(theta) * (float)Math.Sin(phi);

pos.Normalize();
pos = radius * pos;


Where direction is the heading direction, radius is the distance away from the centre, timeDelta is the time since the last frame, orbit speed is a speed constant for the orbit, theta is the angle about the y-axis, phi is the angle about the x-axis, and pos is the final position vector for the object.

This works fine when direction = (1, 0) or (0, 1), however when it is made to equal (1, 1) then the object does weird orbits and it seems to be due pos.z not being calculated correctly.

Below is an image of the problem:

[attachment=11652:bad orbit.jpg]

The white repeating boxes show the motion of the bad orbit.

The expected orbit can be seen below:

[attachment=11653:expected orbit.jpg]

I will be very happy with any help I could get,

Thanks!
Advertisement
The problem is your setup for manipulating the values of [font=courier new,courier,monospace]phi[/font] and [font=courier new,courier,monospace]theta[/font]. The way you have it, if [font=courier new,courier,monospace]direction.y[/font] is ever not zero, then the satellite will always pass through the north and south poles (that is, the positions (0, 1, 0) and (0, -1, 0) assuming radius = 1 orbit) because [font=courier new,courier,monospace]phi[/font] will always exercise its full range of [0, pi], which if you look at the second picture, it's easy to see that [font=courier new,courier,monospace]phi[/font] never reaches 0 or pi (instead, [font=courier new,courier,monospace]phi[/font] looks like it's about in the range [pi / 4, 3 * pi / 4]). To properly model a circular orbit, most of the time [font=courier new,courier,monospace]phi[/font] doesn't exercise the full range [0, pi].

In other words, the way to properly manipulate [font=courier new,courier,monospace]phi[/font] and [font=courier new,courier,monospace]theta[/font] is much more complex than that. I don't have time to sit down and work it out though, as I have a test I'm supposed to be studying for. I just wanted to point out the problem so you/others can start investigating.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
You are changing the spherical coordinates linearly, and the first diagram is exactly what you get by doing that.
So any suggestions as to how I should go about manipulating phi and theta correctly to achieve the orbit in the second picture?
Really, it's going to be WAY easier to just not use spherical coordinates.

For ideal circular orbit (and 'very' easily expandable to elliptical orbits), in a circle defined by an axis of rotation (y) through the planet, you can describe the position of the orbiting body with:

r * (x * cos(theta) + z * sin(theta)) where (x, y, z) is a basis determined by y, and a radius r.
I wouldn't use the spherical coordinates, but store the radius and the rotation mapping the object in (radius, 0, 0) and tangent space basis (0, 1, 0), (0, 0, 1) to the current position and orientation (where I suppose that the first basis vector is the direction the object is heading). To move the object you either define how the current rotation change in time or simply compose the current rotation with the new local one.

If all you want is an object orbiting around a point/planet maintaining some fixed perpendicular vector, you can simply define the current rotation as rotations around that vector with increasing angles.

This topic is closed to new replies.

Advertisement