# Movement On Sphere Surface

This topic is 3538 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm having difficulty solving a problem in the project I'm working on and was looking for a little help. I have a sphere (Earth) which I can add surface objects to with a given Latitude/Longitude. I'm adding an airplane object at any given Lat/Long, and want it to move with a constant speed towards a destination Latitude/Longitude. So given Speed, Current Location and Destination, how would I calculate the airplane's new Lat/Long each frame update so that it moves in the right direction at a constant speed? Any help is greatly appreciated.

##### Share on other sites
You should store your velocity as a vector with units of degrees/second. The first component represents latitudinal speed, the second longitudinal. Then it breaks down to (hopefully) familiar territory: position2 = position1 + velocity * Δt

##### Share on other sites
You could use quaternion slerp. That should give you a smooth interpolation over the surface of a sphere. Store the position of the source and destination points as quaternions and slerp between them.

##### Share on other sites
Quote:
 Original post by erissianYou should store your velocity as a vector with units of degrees/second. The first component represents latitudinal speed, the second longitudinal. Then it breaks down to (hopefully) familiar territory: position2 = position1 + velocity * Δt

I almost have this working, but I'm not calculating "a vector with units of degrees/second" properly (my current bad calculation has them flying more slowly around the poles, and quickly at the equator) -- could you go into more detail on how I would calculate this, given that I'm working only with Current & Target Longitude/Latitude and Speed?

My current understanding of this method is that it would work on a flattened map, but on the sphere one degree of Latitude or Longitude can be wildly different distances depending on where you are.

Thank you both for the replies.

##### Share on other sites
That's because the lines of longitude are closer at the poles, where lines of latitude are equidistant. You will need to factor in the distance from the axis for that particular component, when changing from angular coordinates to rectilinear position.

##### Share on other sites
What I would do:

quick and dirty:
pseudocode
vec3 airplane_pos=position from spherical coords(airplaneLatitude, airplaneLongitude);
vec3 target_pos=position from spherical coords(targetLatitude, targetLongitude);
vec3 delta=(target_pos-airplane_pos)
vec3 vel=Normalized(delta-delta*DotProd(Normalized(airplane_pos)))*speed;/// project the delta to be tangent to sphere, normalize, and multiply by speed.
airplane_pos+=vel*dt;
airplaneLatitude = latitude from position(airplane_pos)
airplaneLongitude = longitude from position(airplane_pos)

neat and mathy: find dPos/dLatitude and same for longitude, then from dPos/dt=(dPos/dLatitude) * (dLatitude/dt) + (dPos/dLongitude) * (dLongitude/dt) , solve for dLatitude/dt and dLongitude/dt (easy because those 2 dPos vectors are orthogonal), and use those to update latitude and longitude. Could work worse than above "quick and dirty" in practice. If you want I can write derivations for the neat method.

##### Share on other sites
Quote:
 Original post by Dmytrypseudocodevec3 airplane_pos=position from spherical coords(airplaneLatitude, airplaneLongitude);vec3 target_pos=position from spherical coords(targetLatitude, targetLongitude);vec3 delta=(target_pos-airplane_pos)vec3 vel=Normalized(delta-delta*DotProd(Normalized(airplane_pos)))*speed;/// project the delta to be tangent to sphere, normalize, and multiply by speed.airplane_pos+=vel*dt;airplaneLatitude = latitude from position(airplane_pos)airplaneLongitude = longitude from position(airplane_pos)

Okay, I've been trying to do this for the past day and have made some progress, but am currently stuck.

I'm using this to convert from Lat/Long to spherical coordinates (on my Geographic Position object):
            /// <summary>            /// Convert a geographical position to a point on a 3D sphere with given radius.            /// </summary>            public Vector3D ToSphere(Double radius)            {                Double longitudeRad = Longitude * Math.PI / 180d;                Double latitudeRad = Latitude * Math.PI / 180d;                Double y = radius * Math.Sin(latitudeRad);                Double r2 = radius * Math.Cos(latitudeRad);                Double x = r2 * Math.Cos(longitudeRad);                Double z = r2 * Math.Sin(longitudeRad);                return new Vector3D(x, y, z);            }

But I've had trouble finding/creating a method for converting from spherical coordinates back into Longitude/Latitude that I could get to work properly. Could anyone give me a push in the right direction with some pseudo-code?

The only other thing I've had trouble understanding is:
Quote:
 vec3 vel=Normalized(delta-delta*DotProd(Normalized(airplane_pos)))*speed;/// project the delta to be tangent to sphere, normalize, and multiply by speed.

I'm not exactly sure what's being done in this single line, and I'm afraid I'm not converting it correctly to code. Would it be possible to break it down by a step or two? My 3D math is pretty weak, and experience with this type of problem is zero.

I appreciate the responses and patience.

##### Share on other sites
Lat/long is spherical polar coordinates. I think what you mean is you lack the transform from Cartesian (XYZ) coordinates to lat/long,

Now, that depends what your XYZ axes are (which one is 'up') but as your spherical->cartesian transforms are:

y = r sin lat
x = r cos lat cos long
z = r cos lat sin long

I can infer that the inverse should be

lat = sin-1 y/r
long = tan-1 z/x

##### Share on other sites
Sounds like you've found what you need, but I would like to recommend the following book. It covers this subject quite well, but in a very general way:

Modern Differential Geometry of Curves and Surfaces with Mathematica

I have the second edition, but I can only assume that the third edition would be better.

##### Share on other sites
That worked perfectly, thank you.

The resulting C# for anyone in the future wanting a method to convert back and forth between Cartesian Coordinates and Longitude / Latitude Spherical Coordinates:

(This assumes a radius of 1. GeoPosition is just an object holding lat/long coordinates.)
static Vector3D ConvertGeoToCart(GeoPosition geoPosition){    double longitudeRad = DegreeToRadian(geoPosition.Longitude);    double latitudeRad = DegreeToRadian(geoPosition.Latitude);    double y = Math.Sin(latitudeRad);    double r2 = Math.Cos(latitudeRad);    double x = r2 * Math.Cos(longitudeRad);    double z = r2 * Math.Sin(longitudeRad);    return new Vector3D(x, y, z);}static GeoPosition ConvertCartToGeo(Vector3D position){    double latitude = Math.Asin(position.Y);    double longitude = Math.Atan2(position.Z , position.X);    return new GeoPosition(RadianToDegree(latitude), RadianToDegree(longitude));}static double DegreeToRadian(double degree){    return degree * Math.PI / 180.0;}static double RadianToDegree(double radian){    return radian / Math.PI * 180.0;}

1. 1
2. 2
Rutin
22
3. 3
4. 4
5. 5
frob
12

• 17
• 9
• 31
• 16
• 9
• ### Forum Statistics

• Total Topics
632615
• Total Posts
3007441

×