Say I have an arbitrary set of latitude and longitude pairs representing points on some simple, closed curve. In Cartesian space I could easily calculate the area enclosed by such a curve using Green's Theorem. What is the analogous approach to calculating the area on the surface of a sphere? I guess what I am after is (even some approximation of) the algorithm behind Matlab's areaint
function.
相关问题
- d3.js moving average with previous and next data v
- How to get a fixed number of evenly spaced points
- Check if a number is a perfect power of another nu
- How to determine +/- sign when calculating diagona
- Union of many (more than two) polygons without hol
相关文章
- ceil conterpart for Math.floorDiv in Java?
- why 48 bit seed in util Random class?
- Algorithm for partially filling a polygonal mesh
- Robust polygon normal calculation
- Algorithm for maximizing coverage of rectangular a
- Need help generating discrete random numbers from
- How do you create a formula that has diminishing r
- Math.Max vs Enumerable.Max
You could also have a look at this code of the
spherical_geometry
package: Here and here. It does provide two different methods for calculating the area of a spherical polygon.You mention "geography" in one of your tags so I can only assume you are after the area of a polygon on the surface of a geoid. Normally, this is done using a projected coordinate system rather than a geographic coordinate system (i.e. lon/lat). If you were to do it in lon/lat, then I would assume the unit-of-measure returned would be percent of sphere surface.
If you want to do this with a more "GIS" flavor, then you need to select an unit-of-measure for your area and find an appropriate projection that preserves area (not all do). Since you are talking about calculating an arbitrary polygon, I would use something like a Lambert Azimuthal Equal Area projection. Set the origin/center of the projection to be the center of your polygon, project the polygon to the new coordinate system, then calculate the area using standard planar techniques.
If you needed to do many polygons in a geographic area, there are likely other projections that will work (or will be close enough). UTM, for example, is an excellent approximation if all of your polygons are clustered around a single meridian.
I am not sure if any of this has anything to do with how Matlab's areaint function works.
I don't know anything about Matlab's function, but here we go. Consider splitting your spherical polygon into spherical triangles, say by drawing diagonals from a vertex. The surface area of a spherical triangle is given by
where
R
is the radius of the sphere, andA
,B
, andC
are the interior angles of the triangle (in radians). The quantity in the parentheses is known as the "spherical excess".Your
n
-sided polygon will be split inton-2
triangles. Summing over all the triangles, extracting the common factor ofR^2
, and bringing all of the\pi
together, the area of your polygon iswhere
S
is the angle sum of your polygon. The quantity in parentheses is again the spherical excess of the polygon.[edit] This is true whether or not the polygon is convex. All that matters is that it can be dissected into triangles.
You can determine the angles from a bit of vector math. Suppose you have three vertices
A
,B
,C
and are interested in the angle atB
. We must therefore find two tangent vectors (their magnitudes are irrelevant) to the sphere from pointB
along the great circle segments (the polygon edges). Let's work it out forBA
. The great circle lies in the plane defined byOA
andOB
, whereO
is the center of the sphere, so it should be perpendicular to the normal vectorOA x OB
. It should also be perpendicular toOB
since it's tangent there. Such a vector is therefore given byOB x (OA x OB)
. You can use the right-hand rule to verify that this is in the appropriate direction. Note also that this simplifies toOA * (OB.OB) - OB * (OB.OA) = OA * |OB| - OB * (OB.OA)
.You can then use the good ol' dot product to find the angle between sides:
BA'.BC' = |BA'|*|BC'|*cos(B)
, whereBA'
andBC'
are the tangent vectors fromB
along sides toA
andC
.[edited to be clear that these are tangent vectors, not literal between the points]
There several ways to do this.
1) Integrate the contributions from latitudinal strips. Here the area of each strip will be (Rcos(A)(B1-B0))(RdA), where A is the latitude, B1 and B0 are the starting and ending longitudes, and all angles are in radians.
2) Break the surface into spherical triangles, and calculate the area using Girard's Theorem, and add these up.
3) As suggested here by James Schek, in GIS work they use an area preserving projection onto a flat space and calculate the area in there.
From the description of your data, in sounds like the first method might be the easiest. (Of course, there may be other easier methods I don't know of.)
Edit – comparing these two methods:
On first inspection, it may seem that the spherical triangle approach is easiest, but, in general, this is not the case. The problem is that one not only needs to break the region up into triangles, but into spherical triangles, that is, triangles whose sides are great circle arcs. For example, latitudinal boundaries don't qualify, so these boundaries need to be broken up into edges that better approximate great circle arcs. And this becomes more difficult to do for arbitrary edges where the great circles require specific combinations of spherical angles. Consider, for example, how one would break up a middle band around a sphere, say all the area between lat 0 and 45deg into spherical triangles.
In the end, if one is to do this properly with similar errors for each method, method 2 will give fewer triangles, but they will be harder to determine. Method 1 gives more strips, but they are trivial to determine. Therefore, I suggest method 1 as the better approach.
I rewrote the MATLAB's "areaint" function in java, which has exactly the same result. "areaint" calculates the "suface per unit", so I multiplied the answer by Earth's Surface Area (5.10072e14 sq m).