With the help of some initial work from a friend of mine and some research online I have implemented a way to accurately place objects on a sphere using latitude and longitude coordinates. However, we are not simply rotating the object with its pivot point at the center of the
sphere. We are actually converting the longitude and latitude coordinates to XYZ coordinates on the fly.
First, let me explain what Latitude and Longitude actually are. To explain this I will use the most logical subject, the Earth. We all know what the equator is… or at least I hope so. The equator is the line that divides the Earth’s northern hemisphere from its southern hemisphere. Remember this term. The second term needed to discuss Latitude/Longitude is the Prime Meridian. The Prime Meridian is the line that divides the Earth’s Eastern hemisphere from it’s Western hemisphere. While the equator is a natural defining division of the
Earth based on its rotation, the Prime Meridian is an arbitrary line that passes through Greenwhich, England and each of the Earth’s poles. The complimentary line to the Prime Meridian is the International Date Line which is on the opposite side of the Earth.
To start the description, Latitude describes the angle along the equator from the Prime Meridian. In fact the Prime Meridian defines 0
degrees Latitude. Longitude describes the angle along the Prime Meridian from the Equator. In fact, the Equator defines 0 degrees
Longitude. So, a Longitude and Latitude of 35, 106 describes 35 degrees off the Equator and 106 degrees off the Prime Meridian.
In computer graphics we often define objects in space by X, Y and Z coordinates based on the origin of 0, 0, 0. It makes sense then to want to get different coordinate systems into X, Y and Z rather than trying to define X, Y and Z into other systems. So how do we do that? Well, it’s all about trigonometry in this situation.
Here is the equation.
1
2
3
| tx = radiusOfSphere * cos(latitude) * cos(longitude);
ty = radiusOfSphere * -sin(latitude);
tz = radiusOfSphere * cos(latitude) * sin(longitude); |
I won’t go into why this works because it is kind of drawn out. If you want to know, Google it and you should find many mathematical papers describing this.
The only thing about this equation that is tricky is that it returns values in radians rather than degrees. Again, if you want to know the
difference, Google it.
So lets set it up in Maya.
Create the Earth geometry as a nurbs or poly sphere in Maya with a specific radius (say 25, and yes, I know the Earth isn’t a true sphere, but the difference is so small, we simply omit it for purposes of art and simplicity).
After applying the earth color texture map to the sphere you will need to rotate the sphere by 90 degrees in Y to get the texture lined
up with where it needs to be (don’t worry to much about this, just do it).
Create the object you want to place at a specific lat/long on the Earth. Add 3 custom float attributes to it.
latitude (controls the latitude of the object)
longitude (controls the longitude of the object)
altitude (controls the distance from the object’s center to the sphere’s surface, think of a radius offset)
Then create the following expression and apply it (notice the deg_to_rad function that converts the latitude and longitude degrees into radians before being calculated).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| float $radius = 25; //radius of the sphere or Earths surface in Maya</code>
float $altitude = $radius + pSphere1.alt; // distance from center of earth to center of object.
float $long = deg_to_rad(pSphere1.long)*-1; //longitude value in radians
float $lat = deg_to_rad(pSphere1.lat)*-1; //latitude value in radians
// the equation to do the conversion and placement.
pSphere1.translateX = $altitude * cos($lat) * cos($long);
pSphere1.translateY = $altitude * sin($lat) * -1;
pSphere1.translateZ = $altitude * cos($lat) * sin($long) |
Once applied to your object (a poly sphere in my case) will be placed on the Earth in the correct position at your given altitude.
**Special thanks to Adam Kugler for pointing out a discrepancy with the code. Thanks for the tip!
Try setting some keys on the attributes and see the object travel along the surface of the Earth.