Ellipsoid.hpp 24 KB

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