NETGeographicLib  1.51
Ellipsoid.h
Go to the documentation of this file.
1 /**
2  * \file NETGeographicLib/Ellipsoid.h
3  * \brief Header for NETGeographicLib::Ellipsoid class
4  *
5  * NETGeographicLib is copyright (c) Scott Heiman (2013)
6  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
7  * <charles@karney.com> and licensed under the MIT/X11 License.
8  * For more information, see
9  * https://geographiclib.sourceforge.io/
10  **********************************************************************/
11 #pragma once
12 
13 namespace NETGeographicLib
14 {
15  /**
16  * \brief .NET wrapper for GeographicLib::Ellipsoid.
17  *
18  * This class allows .NET applications to access GeographicLib::Ellipsoid.
19  *
20  * This class returns various properties of the ellipsoid and converts
21  * between various types of latitudes. The latitude conversions are also
22  * possible using the various projections supported by %GeographicLib; but
23  * Ellipsoid provides more direct access (sometimes using private functions
24  * of the projection classes). Ellipsoid::RectifyingLatitude,
25  * Ellipsoid::InverseRectifyingLatitude, and Ellipsoid::MeridianDistance
26  * provide functionality which can be provided by the Geodesic class.
27  * However Geodesic uses a series approximation (valid for abs \e f < 1/150),
28  * whereas Ellipsoid computes these quantities using EllipticFunction which
29  * provides accurate results even when \e f is large. Use of this class
30  * should be limited to &minus;3 < \e f < 3/4 (i.e., 1/4 < b/a < 4).
31  *
32  * C# Example:
33  * \include example-Ellipsoid.cs
34  * Managed C++ Example:
35  * \include example-Ellipsoid.cpp
36  * Visual Basic Example:
37  * \include example-Ellipsoid.vb
38  *
39  * <B>INTERFACE DIFFERENCES:</B><BR>
40  * A default constructor has been provided that assumes a WGS84 ellipsoid.
41  *
42  * The following functions are implemented as properties:
43  * EquatorialRadius, MinorRadius, QuarterMeridian, Area, Volume, Flattening,
44  * SecondFlattening, ThirdFlattening, EccentricitySq, SecondEccentricitySq,
45  * and ThirdEccentricitySq.
46  **********************************************************************/
47  public ref class Ellipsoid
48  {
49  private:
50  // A pointer to the unmanaged GeographicLib::Ellipsoid
51  GeographicLib::Ellipsoid* m_pEllipsoid;
52 
53  // The finalizer frees the unmanaged memory when the object is destroyed.
54  !Ellipsoid();
55  public:
56  /** \name Constructor
57  **********************************************************************/
58  ///@{
59 
60  /**
61  * Constructor for a WGS84 ellipsoid
62  **********************************************************************/
63  Ellipsoid();
64 
65  /**
66  * Constructor for a ellipsoid with
67  *
68  * @param[in] a equatorial radius (meters).
69  * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
70  * Negative \e f gives a prolate ellipsoid.
71  * @exception GeographicErr if \e a or (1 &minus; \e f ) \e a is not
72  * positive.
73  **********************************************************************/
74  Ellipsoid(double a, double f);
75  ///@}
76 
77  /** The destructor calls the finalizer.
78  **********************************************************************/
80  { this->!Ellipsoid(); }
81 
82  /** \name %Ellipsoid dimensions.
83  **********************************************************************/
84  ///@{
85 
86  /**
87  * @return \e a the equatorial radius of the ellipsoid (meters). This is
88  * the value used in the constructor.
89  **********************************************************************/
90  property double EquatorialRadius { double get(); }
91 
92  /**
93  * @return \e b the polar semi-axis (meters).
94  **********************************************************************/
95  property double MinorRadius { double get(); }
96 
97  /**
98  * @return \e L the distance between the equator and a pole along a
99  * meridian (meters). For a sphere \e L = (&pi;/2) \e a. The radius
100  * of a sphere with the same meridian length is \e L / (&pi;/2).
101  **********************************************************************/
102  property double QuarterMeridian { double get(); }
103 
104  /**
105  * @return \e A the total area of the ellipsoid (meters<sup>2</sup>). For
106  * a sphere \e A = 4&pi; <i>a</i><sup>2</sup>. The radius of a sphere
107  * with the same area is sqrt(\e A / (4&pi;)).
108  **********************************************************************/
109  property double Area { double get(); }
110 
111  /**
112  * @return \e V the total volume of the ellipsoid (meters<sup>3</sup>).
113  * For a sphere \e V = (4&pi; / 3) <i>a</i><sup>3</sup>. The radius of
114  * a sphere with the same volume is cbrt(\e V / (4&pi;/3)).
115  **********************************************************************/
116  property double Volume { double get(); }
117  ///@}
118 
119  /** \name %Ellipsoid shape
120  **********************************************************************/
121  ///@{
122 
123  /**
124  * @return \e f = (\e a &minus; \e b) / \e a, the flattening of the
125  * ellipsoid. This is the value used in the constructor. This is zero,
126  * positive, or negative for a sphere, oblate ellipsoid, or prolate
127  * ellipsoid.
128  **********************************************************************/
129  property double Flattening { double get(); }
130 
131  /**
132  * @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening of
133  * the ellipsoid. This is zero, positive, or negative for a sphere,
134  * oblate ellipsoid, or prolate ellipsoid.
135  **********************************************************************/
136  property double SecondFlattening { double get(); }
137 
138  /**
139  * @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third flattening
140  * of the ellipsoid. This is zero, positive, or negative for a sphere,
141  * oblate ellipsoid, or prolate ellipsoid.
142  **********************************************************************/
143  property double ThirdFlattening { double get(); }
144 
145  /**
146  * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
147  * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity squared
148  * of the ellipsoid. This is zero, positive, or negative for a sphere,
149  * oblate ellipsoid, or prolate ellipsoid.
150  **********************************************************************/
151  property double EccentricitySq { double get(); }
152 
153  /**
154  * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
155  * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity
156  * squared of the ellipsoid. This is zero, positive, or negative for a
157  * sphere, oblate ellipsoid, or prolate ellipsoid.
158  **********************************************************************/
159  property double SecondEccentricitySq { double get(); }
160 
161  /**
162  * @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
163  * <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</sup>),
164  * the third eccentricity squared of the ellipsoid. This is zero,
165  * positive, or negative for a sphere, oblate ellipsoid, or prolate
166  * ellipsoid.
167  **********************************************************************/
168  property double ThirdEccentricitySq { double get(); }
169  ///@}
170 
171  /** \name Latitude conversion.
172  **********************************************************************/
173  ///@{
174 
175  /**
176  * @param[in] phi the geographic latitude (degrees).
177  * @return &beta; the parametric latitude (degrees).
178  *
179  * The geographic latitude, &phi;, is the angle beween the equatorial
180  * plane and a vector normal to the surface of the ellipsoid.
181  *
182  * The parametric latitude (also called the reduced latitude), &beta;,
183  * allows the cartesian coordinated of a meridian to be expressed
184  * conveniently in parametric form as
185  * - \e R = \e a cos &beta;
186  * - \e Z = \e b sin &beta;
187  * .
188  * where \e a and \e b are the equatorial radius and the polar semi-axis.
189  * For a sphere &beta; = &phi;.
190  *
191  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
192  * result is undefined if this condition does not hold. The returned value
193  * &beta; lies in [&minus;90&deg;, 90&deg;].
194  **********************************************************************/
195  double ParametricLatitude(double phi);
196 
197  /**
198  * @param[in] beta the parametric latitude (degrees).
199  * @return &phi; the geographic latitude (degrees).
200  *
201  * &beta; must lie in the range [&minus;90&deg;, 90&deg;]; the
202  * result is undefined if this condition does not hold. The returned value
203  * &phi; lies in [&minus;90&deg;, 90&deg;].
204  **********************************************************************/
205  double InverseParametricLatitude(double beta);
206 
207  /**
208  * @param[in] phi the geographic latitude (degrees).
209  * @return &theta; the geocentric latitude (degrees).
210  *
211  * The geocentric latitude, &theta;, is the angle beween the equatorial
212  * plane and a line between the center of the ellipsoid and a point on the
213  * ellipsoid. For a sphere &theta; = &phi;.
214  *
215  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
216  * result is undefined if this condition does not hold. The returned value
217  * &theta; lies in [&minus;90&deg;, 90&deg;].
218  **********************************************************************/
219  double GeocentricLatitude(double phi);
220 
221  /**
222  * @param[in] theta the geocentric latitude (degrees).
223  * @return &phi; the geographic latitude (degrees).
224  *
225  * &theta; must lie in the range [&minus;90&deg;, 90&deg;]; the
226  * result is undefined if this condition does not hold. The returned value
227  * &phi; lies in [&minus;90&deg;, 90&deg;].
228  **********************************************************************/
229  double InverseGeocentricLatitude(double theta);
230 
231  /**
232  * @param[in] phi the geographic latitude (degrees).
233  * @return &mu; the rectifying latitude (degrees).
234  *
235  * The rectifying latitude, &mu;, has the property that the distance along
236  * a meridian of the ellipsoid between two points with rectifying latitudes
237  * &mu;<sub>1</sub> and &mu;<sub>2</sub> is equal to
238  * (&mu;<sub>2</sub> - &mu;<sub>1</sub>) \e L / 90&deg;,
239  * where \e L = QuarterMeridian(). For a sphere &mu; = &phi;.
240  *
241  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
242  * result is undefined if this condition does not hold. The returned value
243  * &mu; lies in [&minus;90&deg;, 90&deg;].
244  **********************************************************************/
245  double RectifyingLatitude(double phi);
246 
247  /**
248  * @param[in] mu the rectifying latitude (degrees).
249  * @return &phi; the geographic latitude (degrees).
250  *
251  * &mu; must lie in the range [&minus;90&deg;, 90&deg;]; the
252  * result is undefined if this condition does not hold. The returned value
253  * &phi; lies in [&minus;90&deg;, 90&deg;].
254  **********************************************************************/
255  double InverseRectifyingLatitude(double mu);
256 
257  /**
258  * @param[in] phi the geographic latitude (degrees).
259  * @return &xi; the authalic latitude (degrees).
260  *
261  * The authalic latitude, &xi;, has the property that the area of the
262  * ellipsoid between two circles with authalic latitudes
263  * &xi;<sub>1</sub> and &xi;<sub>2</sub> is equal to (sin
264  * &xi;<sub>2</sub> - sin &xi;<sub>1</sub>) \e A / 2, where \e A
265  * = Area(). For a sphere &xi; = &phi;.
266  *
267  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
268  * result is undefined if this condition does not hold. The returned value
269  * &xi; lies in [&minus;90&deg;, 90&deg;].
270  **********************************************************************/
271  double AuthalicLatitude(double phi);
272 
273  /**
274  * @param[in] xi the authalic latitude (degrees).
275  * @return &phi; the geographic latitude (degrees).
276  *
277  * &xi; must lie in the range [&minus;90&deg;, 90&deg;]; the
278  * result is undefined if this condition does not hold. The returned value
279  * &phi; lies in [&minus;90&deg;, 90&deg;].
280  **********************************************************************/
281  double InverseAuthalicLatitude(double xi);
282 
283  /**
284  * @param[in] phi the geographic latitude (degrees).
285  * @return &chi; the conformal latitude (degrees).
286  *
287  * The conformal latitude, &chi;, gives the mapping of the ellipsoid to a
288  * sphere which which is conformal (angles are preserved) and in which the
289  * equator of the ellipsoid maps to the equator of the sphere. For a
290  * sphere &chi; = &phi;.
291  *
292  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
293  * result is undefined if this condition does not hold. The returned value
294  * &chi; lies in [&minus;90&deg;, 90&deg;].
295  **********************************************************************/
296  double ConformalLatitude(double phi);
297 
298  /**
299  * @param[in] chi the conformal latitude (degrees).
300  * @return &phi; the geographic latitude (degrees).
301  *
302  * &chi; must lie in the range [&minus;90&deg;, 90&deg;]; the
303  * result is undefined if this condition does not hold. The returned value
304  * &phi; lies in [&minus;90&deg;, 90&deg;].
305  **********************************************************************/
306  double InverseConformalLatitude(double chi);
307 
308  /**
309  * @param[in] phi the geographic latitude (degrees).
310  * @return &psi; the isometric latitude (degrees).
311  *
312  * The isometric latitude gives the mapping of the ellipsoid to a plane
313  * which which is conformal (angles are preserved) and in which the equator
314  * of the ellipsoid maps to a straight line of constant scale; this mapping
315  * defines the Mercator projection. For a sphere &psi; =
316  * sinh<sup>&minus;1</sup> tan &phi;.
317  *
318  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
319  * result is undefined if this condition does not hold.
320  **********************************************************************/
321  double IsometricLatitude(double phi);
322 
323  /**
324  * @param[in] psi the isometric latitude (degrees).
325  * @return &phi; the geographic latitude (degrees).
326  *
327  * The returned value &phi; lies in [&minus;90&deg;, 90&deg;].
328  **********************************************************************/
329  double InverseIsometricLatitude(double psi);
330  ///@}
331 
332  /** \name Other quantities.
333  **********************************************************************/
334  ///@{
335 
336  /**
337  * @param[in] phi the geographic latitude (degrees).
338  * @return \e R = \e a cos &beta; the radius of a circle of latitude
339  * &phi; (meters). \e R (&pi;/180&deg;) gives meters per degree
340  * longitude measured along a circle of latitude.
341  *
342  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
343  * result is undefined if this condition does not hold.
344  **********************************************************************/
345  double CircleRadius(double phi);
346 
347  /**
348  * @param[in] phi the geographic latitude (degrees).
349  * @return \e Z = \e b sin &beta; the distance of a circle of latitude
350  * &phi; from the equator measured parallel to the ellipsoid axis
351  * (meters).
352  *
353  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
354  * result is undefined if this condition does not hold.
355  **********************************************************************/
356  double CircleHeight(double phi);
357 
358  /**
359  * @param[in] phi the geographic latitude (degrees).
360  * @return \e s the distance along a meridian
361  * between the equator and a point of latitude &phi; (meters). \e s is
362  * given by \e s = &mu; \e L / 90&deg;, where \e L =
363  * QuarterMeridian()).
364  *
365  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
366  * result is undefined if this condition does not hold.
367  **********************************************************************/
368  double MeridianDistance(double phi);
369 
370  /**
371  * @param[in] phi the geographic latitude (degrees).
372  * @return &rho; the meridional radius of curvature of the ellipsoid at
373  * latitude &phi; (meters); this is the curvature of the meridian. \e
374  * rho is given by &rho; = (180&deg;/&pi;) d\e s / d&phi;,
375  * where \e s = MeridianDistance(); thus &rho; (&pi;/180&deg;)
376  * gives meters per degree latitude measured along a meridian.
377  *
378  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
379  * result is undefined if this condition does not hold.
380  **********************************************************************/
381  double MeridionalCurvatureRadius(double phi);
382 
383  /**
384  * @param[in] phi the geographic latitude (degrees).
385  * @return &nu; the transverse radius of curvature of the ellipsoid at
386  * latitude &phi; (meters); this is the curvature of a curve on the
387  * ellipsoid which also lies in a plane perpendicular to the ellipsoid
388  * and to the meridian. &nu; is related to \e R = CircleRadius() by \e
389  * R = &nu; cos &phi;.
390  *
391  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
392  * result is undefined if this condition does not hold.
393  **********************************************************************/
394  double TransverseCurvatureRadius(double phi);
395 
396  /**
397  * @param[in] phi the geographic latitude (degrees).
398  * @param[in] azi the angle between the meridian and the normal section
399  * (degrees).
400  * @return the radius of curvature of the ellipsoid in the normal
401  * section at latitude &phi; inclined at an angle \e azi to the
402  * meridian (meters).
403  *
404  * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
405  * result is undefined if this condition does not hold.
406  **********************************************************************/
407  double NormalCurvatureRadius(double phi, double azi);
408  ///@}
409 
410  /** \name Eccentricity conversions.
411  **********************************************************************/
412  ///@{
413 
414  /**
415  * @param[in] fp = \e f ' = (\e a &minus; \e b) / \e b, the second
416  * flattening.
417  * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
418  *
419  * \e f ' should lie in (&minus;1, &infin;).
420  * The returned value \e f lies in (&minus;&infin;, 1).
421  **********************************************************************/
422  static double SecondFlatteningToFlattening(double fp);
423 
424  /**
425  * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
426  * @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening.
427  *
428  * \e f should lie in (&minus;&infin;, 1).
429  * The returned value \e f ' lies in (&minus;1, &infin;).
430  **********************************************************************/
431  static double FlatteningToSecondFlattening(double f);
432 
433  /**
434  * @param[in] n = (\e a &minus; \e b) / (\e a + \e b), the third
435  * flattening.
436  * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
437  *
438  * \e n should lie in (&minus;1, 1).
439  * The returned value \e f lies in (&minus;&infin;, 1).
440  **********************************************************************/
441  static double ThirdFlatteningToFlattening(double n);
442 
443  /**
444  * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
445  * @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third
446  * flattening.
447  *
448  * \e f should lie in (&minus;&infin;, 1).
449  * The returned value \e n lies in (&minus;1, 1).
450  **********************************************************************/
451  static double FlatteningToThirdFlattening(double f);
452 
453  /**
454  * @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
455  * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity
456  * squared.
457  * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
458  *
459  * <i>e</i><sup>2</sup> should lie in (&minus;&infin;, 1).
460  * The returned value \e f lies in (&minus;&infin;, 1).
461  **********************************************************************/
462  static double EccentricitySqToFlattening(double e2);
463 
464  /**
465  * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
466  * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
467  * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity
468  * squared.
469  *
470  * \e f should lie in (&minus;&infin;, 1).
471  * The returned value <i>e</i><sup>2</sup> lies in (&minus;&infin;, 1).
472  **********************************************************************/
473  static double FlatteningToEccentricitySq(double f);
474 
475  /**
476  * @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
477  * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity
478  * squared.
479  * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
480  *
481  * <i>e'</i> <sup>2</sup> should lie in (&minus;1, &infin;).
482  * The returned value \e f lies in (&minus;&infin;, 1).
483  **********************************************************************/
484  static double SecondEccentricitySqToFlattening(double ep2);
485 
486  /**
487  * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
488  * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
489  * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity
490  * squared.
491  *
492  * \e f should lie in (&minus;&infin;, 1).
493  * The returned value <i>e'</i> <sup>2</sup> lies in (&minus;1, &infin;).
494  **********************************************************************/
495  static double FlatteningToSecondEccentricitySq(double f);
496 
497  /**
498  * @param[in] epp2 = <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup>
499  * &minus; <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> +
500  * <i>b</i><sup>2</sup>), the third eccentricity squared.
501  * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
502  *
503  * <i>e''</i> <sup>2</sup> should lie in (&minus;1, 1).
504  * The returned value \e f lies in (&minus;&infin;, 1).
505  **********************************************************************/
506  static double ThirdEccentricitySqToFlattening(double epp2);
507 
508  /**
509  * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
510  * @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
511  * <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</sup>),
512  * the third eccentricity squared.
513  *
514  * \e f should lie in (&minus;&infin;, 1).
515  * The returned value <i>e''</i> <sup>2</sup> lies in (&minus;1, 1).
516  **********************************************************************/
517  static double FlatteningToThirdEccentricitySq(double f);
518  };
519 } // namespace NETGeographicLib
double RectifyingLatitude(double phi)
static double ThirdFlatteningToFlattening(double n)
static double FlatteningToThirdFlattening(double f)
double InverseIsometricLatitude(double psi)
double AuthalicLatitude(double phi)
double CircleRadius(double phi)
static double SecondEccentricitySqToFlattening(double ep2)
double InverseConformalLatitude(double chi)
double CircleHeight(double phi)
static double FlatteningToSecondFlattening(double f)
static double ThirdEccentricitySqToFlattening(double epp2)
double ConformalLatitude(double phi)
double InverseRectifyingLatitude(double mu)
static double FlatteningToSecondEccentricitySq(double f)
double GeocentricLatitude(double phi)
static double EccentricitySqToFlattening(double e2)
double InverseAuthalicLatitude(double xi)
double TransverseCurvatureRadius(double phi)
double InverseGeocentricLatitude(double theta)
static double FlatteningToThirdEccentricitySq(double f)
.NET wrapper for GeographicLib::Ellipsoid.
Definition: Ellipsoid.h:47
static double FlatteningToEccentricitySq(double f)
double MeridionalCurvatureRadius(double phi)
double NormalCurvatureRadius(double phi, double azi)
double ParametricLatitude(double phi)
static double SecondFlatteningToFlattening(double fp)
double InverseParametricLatitude(double beta)
double MeridianDistance(double phi)
double IsometricLatitude(double phi)