![]() |
interpolating mapping searching |
|
Point: A point on a sphere is typically designated by it's latitude and longitude. Oddly that (lat, lon) is a two dimensional coordinate system sometimes leads people to forget spheres are three dimensional. The third dimension, r, is constant for points on a sphere so it get's dropped.
In the spheres package the basic strategy is to convert everything to cartesian space where the complexities of spherical trigonometry become simple algebra. Whatever trigonometry there is in the spheres package is restricted to the Point class where points are created as both Cartesian and spherical.
lat = 90 - degrees(acos(z/r))
lon = degrees(atan2(y, x))
x = r*cos(radians(lon))*cos(radians(lat))
y = r*sin(radians(lon))*cos(radians(lat))
z = r*sin(radians(lat))
Longitudes are generally in the range [-180,
180], but sometimes that's not convenient. Longitude ranges in the spheres package
always start within the
range [-180, 180] and go west to east regardless of the orientation of the
feature. For example a feature that starts at longitude 178, goes west
and eventually crosses the dateline, but ends shy of 178 (say 179) would have a longitude
range of [179, 538]
The Sphere class itself doesn't get used much, but a lot of the other classes are extensions of the Sphere class. Consequently common methods that a lot of the sub-classes need are contained in the Sphere class. Generally these are just utility methods.
normalize(lon) - returns a longitude between [-180, 180]. For various reasons it is often convenient to work with longitudes outside the normal range, usually when some line segment or arc crosses the dateline.
radians(degrees) - converts degrees to radians.
degrees(radians) - converts radians to degrees.
scalarTripleProductTest(given_point, start_point, end_point) - determines on which side of the line (defined by start_point, end_point) the given point is. This get's used for the point-in-polygon algorithm in the SphericalPolygon class and probably should be a method in that class instead. I thought it might be of more general use, but not so far.
contains(Point) - determine if this spherical polygon contains a given point .overlaps(SphericalPolygon) - determine if this spherical polygon overlaps another.
overlaps(LatLonBoundingBox) - determine if this spherical polygon overlaps a Lat/Lon Bounding Box .
overlaps(Scene) - determine if this spherical polygon overlaps a scene.
Lat/lon bounding boxes are typically defined by one set of opposite corner points which is sufficient to define the minimum and maximum latitude and longitude. Typically those two points are refered to as upper-left and lower-right which is only accurate if one assumes the Earth is flat. Those two points are actually the Northwest corner and the Southeast corner.
Lat/lon bounding boxes are widely used because they are easy to work with. Part of the reason the spheres package was written was to make working with projection neutral areas on the sphere just as easy. We included a class for lat/lon bounding boxes in the spheres package primarily because so many legacy systems have come to depend on it.
A lat/lon bounding box is just a range, defined by four numbers; {lat_min, lat_max, lon_min, lon_max}. Beyond that there are a number of things one might want to find out about a lat/lon bounding box.
contains(Point) - determine if this lat/lon bounding box contains a given point.
overlaps(SphericalPolygon) - determine if this lat/lon bounding box overlaps a spherical polygon.overlaps(LatLonBoundingBox) - determine if this lat/lon bounding box overlaps another.
overlaps(Scene) - determine if this lat/lon bounding box overlaps a scene.
toSphericalPolygon(num_points) - convert the lat/lon bounding box to a spherical polygon with the given number of vertices.
Please send suggestions, comments, and questions regarding the Spheres project to swick@nsidc.org
Last modified: Wed Dec 10 17:06:59 2003