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