View Full Version : Cartesian to Spherical Position

05-24-2004, 01:50 AM
I have an animation path defined in cartesian (planar) coordinates around a flat earth. Now I want to go spherical and follow this path so that it would look like I am moving along the ground of the sphere.

The problem, is that I can't orient the camera to give the right up vector. To better phrase the question, given a yaw/pitch in cartesian lat/lon coordinates, how can I get a yaw/pitch/roll or quaternion for representing that same planar angle on a sphere.

The easiest thing that comes to mind, if we forget the pith for now, is to create a quaternion using axis angle. We have the axis, which would be the normalized vector of our location on the sphere relative to the origin of the sphere, but how would we get the proper look angle?

05-27-2004, 08:30 AM
Intriguing problem :)
Here's a sketch of an idea that I've never tried...

If you let the origin of your flatland
map to the north pole of your sphere,
then you could view the length of any point
P from the pole as an arc length on the sphere,
and a subtended angle could be defined as

|P| |P|
a = (-------- 2 pi) mod (2 pi) = ----- mod 2 pi
2 pi r r

where a is the angle subtended, r is the radius
of the sphere, and |P| is the distance of P from
the origin in flatland.

If we rotate around a vector orthogonal to the
direction of P in flatland, this would give us a
mapping dependent only on the position of P.

If (0,0,1) is your north pole vector, for
example, the rotation axis would be

axis = (0,0,1) x P/|P| = (-P.y,P.x,0)

The idea is to carry out your rotations and
translations normally in the plane; then, when
you want to move to the sphere, apply the angle
axis transformation. In other words, just "bend"
the current orientation onto the sphere in the
direction of P.

Hmmm, I've probably missed something... edit:

made a correction

05-27-2004, 10:25 AM
Sorry for not posting the reply here as well (I asked on flipcode also), but I came up with a method which gave me exactly what I was looking for. Here is the post.

After trying many methods, I finally found a method which works perfectly. Given your lat/lon position, heading(yaw), and pitch/roll, you can calculate an equivalent spherical rotation as follows.

SphericalPosition is a function that returns the lat/lon position with height projected onto a sphere of a given radius.

I tried using the forum code stuff, but it messed up my formating (got rid of spaces), so here it is as is.

/* Get the origin */
Vector3 ORIGIN = SphericalPosition( lon, lat, 0 );

/* Generate the up vector */
Vector3 UP = SphericalPosition( lon, lat, 100 );

/* Generate the forward vector */
double radius = 0.01 (keep relatively small since we are dealing with lat/lon coordinates)
double cs = cos(heading)*radius;
double sn = sin(heading)*radius;
Vector3 FORWARD = SphericalPosition( lon+cs, lat+sn, 0 );

/* Generate the right vector */
heading += 90*RADIAN; /* Rotate the heading by 90 degrees to get the right vector */
radius = 0.01 (keep relatively small since we are dealing with lat/lon coordinates)
cs = cos(heading)*radius;
sn = sin(heading)*radius;
Vector3 RIGHT = SphericalPosition( lon+cs, lat+sn, 0 );

** Pitch is applied by rotating the up and forward vector around the right vector.
UP = RotateAroundVector( pitch, RIGHT, UP );
FORWARD = RotateAroundVector( pitch, RIGHT, FORWARD );

/* Roll will be something similar, but a rotation around the forward axis */

** Now you have your right/forward/up vector. Use that to compute
** a transformation matrix, and now you have seamless
** cartesian/spherical roaming. Pretty sweet.