GeodesicExact.hpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /**
  2. * \file GeodesicExact.hpp
  3. * \brief Header for GeographicLib::GeodesicExact 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_GEODESICEXACT_HPP)
  10. #define GEOGRAPHICLIB_GEODESICEXACT_HPP 1
  11. #include <GeographicLib/Constants.hpp>
  12. #include <GeographicLib/EllipticFunction.hpp>
  13. #if !defined(GEOGRAPHICLIB_GEODESICEXACT_ORDER)
  14. /**
  15. * The order of the expansions used by GeodesicExact.
  16. **********************************************************************/
  17. # define GEOGRAPHICLIB_GEODESICEXACT_ORDER 30
  18. #endif
  19. namespace GeographicLib {
  20. class GeodesicLineExact;
  21. /**
  22. * \brief Exact geodesic calculations
  23. *
  24. * The equations for geodesics on an ellipsoid can be expressed in terms of
  25. * incomplete elliptic integrals. The Geodesic class expands these integrals
  26. * in a series in the flattening \e f and this provides an accurate solution
  27. * for \e f &isin; [-0.01, 0.01]. The GeodesicExact class computes the
  28. * ellitpic integrals directly and so provides a solution which is valid for
  29. * all \e f. However, in practice, its use should be limited to about
  30. * <i>b</i>/\e a &isin; [0.01, 100] or \e f &isin; [&minus;99, 0.99].
  31. *
  32. * For the WGS84 ellipsoid, these classes are 2--3 times \e slower than the
  33. * series solution and 2--3 times \e less \e accurate (because it's less easy
  34. * to control round-off errors with the elliptic integral formulation); i.e.,
  35. * the error is about 40 nm (40 nanometers) instead of 15 nm. However the
  36. * error in the series solution scales as <i>f</i><sup>7</sup> while the
  37. * error in the elliptic integral solution depends weakly on \e f. If the
  38. * quarter meridian distance is 10000 km and the ratio <i>b</i>/\e a = 1
  39. * &minus; \e f is varied then the approximate maximum error (expressed as a
  40. * distance) is <pre>
  41. * 1 - f error (nm)
  42. * 1/128 387
  43. * 1/64 345
  44. * 1/32 269
  45. * 1/16 210
  46. * 1/8 115
  47. * 1/4 69
  48. * 1/2 36
  49. * 1 15
  50. * 2 25
  51. * 4 96
  52. * 8 318
  53. * 16 985
  54. * 32 2352
  55. * 64 6008
  56. * 128 19024
  57. * </pre>
  58. *
  59. * The computation of the area in these classes is via a 30th order series.
  60. * This gives accurate results for <i>b</i>/\e a &isin; [1/2, 2]; the
  61. * accuracy is about 8 decimal digits for <i>b</i>/\e a &isin; [1/4, 4].
  62. *
  63. * See \ref geodellip for the formulation. See the documentation on the
  64. * Geodesic class for additional information on the geodesic problems.
  65. *
  66. * Example of use:
  67. * \include example-GeodesicExact.cpp
  68. *
  69. * <a href="GeodSolve.1.html">GeodSolve</a> is a command-line utility
  70. * providing access to the functionality of GeodesicExact and
  71. * GeodesicLineExact (via the -E option).
  72. **********************************************************************/
  73. class GEOGRAPHICLIB_EXPORT GeodesicExact {
  74. private:
  75. typedef Math::real real;
  76. friend class GeodesicLineExact;
  77. static const int nC4_ = GEOGRAPHICLIB_GEODESICEXACT_ORDER;
  78. static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2;
  79. static const unsigned maxit1_ = 20;
  80. unsigned maxit2_;
  81. real tiny_, tol0_, tol1_, tol2_, tolb_, xthresh_;
  82. enum captype {
  83. CAP_NONE = 0U,
  84. CAP_E = 1U<<0,
  85. // Skip 1U<<1 for compatibility with Geodesic (not required)
  86. CAP_D = 1U<<2,
  87. CAP_H = 1U<<3,
  88. CAP_C4 = 1U<<4,
  89. CAP_ALL = 0x1FU,
  90. CAP_MASK = CAP_ALL,
  91. OUT_ALL = 0x7F80U,
  92. OUT_MASK = 0xFF80U, // Includes LONG_UNROLL
  93. };
  94. static real CosSeries(real sinx, real cosx, const real c[], int n);
  95. static real Astroid(real x, real y);
  96. real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2;
  97. real _C4x[nC4x_];
  98. void Lengths(const EllipticFunction& E,
  99. real sig12,
  100. real ssig1, real csig1, real dn1,
  101. real ssig2, real csig2, real dn2,
  102. real cbet1, real cbet2, unsigned outmask,
  103. real& s12s, real& m12a, real& m0,
  104. real& M12, real& M21) const;
  105. real InverseStart(EllipticFunction& E,
  106. real sbet1, real cbet1, real dn1,
  107. real sbet2, real cbet2, real dn2,
  108. real lam12, real slam12, real clam12,
  109. real& salp1, real& calp1,
  110. real& salp2, real& calp2, real& dnm) const;
  111. real Lambda12(real sbet1, real cbet1, real dn1,
  112. real sbet2, real cbet2, real dn2,
  113. real salp1, real calp1, real slam120, real clam120,
  114. real& salp2, real& calp2, real& sig12,
  115. real& ssig1, real& csig1, real& ssig2, real& csig2,
  116. EllipticFunction& E,
  117. real& domg12, bool diffp, real& dlam12) const;
  118. real GenInverse(real lat1, real lon1, real lat2, real lon2,
  119. unsigned outmask, real& s12,
  120. real& salp1, real& calp1, real& salp2, real& calp2,
  121. real& m12, real& M12, real& M21, real& S12) const;
  122. // These are Maxima generated functions to provide series approximations to
  123. // the integrals for the area.
  124. void C4coeff();
  125. void C4f(real k2, real c[]) const;
  126. // Large coefficients are split so that lo contains the low 52 bits and hi
  127. // the rest. This choice avoids double rounding with doubles and higher
  128. // precision types. float coefficients will suffer double rounding;
  129. // however the accuracy is already lousy for floats.
  130. static Math::real reale(long long hi, long long lo) {
  131. using std::ldexp;
  132. return ldexp(real(hi), 52) + lo;
  133. }
  134. public:
  135. /**
  136. * Bit masks for what calculations to do. These masks do double duty.
  137. * They signify to the GeodesicLineExact::GeodesicLineExact constructor and
  138. * to GeodesicExact::Line what capabilities should be included in the
  139. * GeodesicLineExact object. They also specify which results to return in
  140. * the general routines GeodesicExact::GenDirect and
  141. * GeodesicExact::GenInverse routines. GeodesicLineExact::mask is a
  142. * duplication of this enum.
  143. **********************************************************************/
  144. enum mask {
  145. /**
  146. * No capabilities, no output.
  147. * @hideinitializer
  148. **********************************************************************/
  149. NONE = 0U,
  150. /**
  151. * Calculate latitude \e lat2. (It's not necessary to include this as a
  152. * capability to GeodesicLineExact because this is included by default.)
  153. * @hideinitializer
  154. **********************************************************************/
  155. LATITUDE = 1U<<7 | CAP_NONE,
  156. /**
  157. * Calculate longitude \e lon2.
  158. * @hideinitializer
  159. **********************************************************************/
  160. LONGITUDE = 1U<<8 | CAP_H,
  161. /**
  162. * Calculate azimuths \e azi1 and \e azi2. (It's not necessary to
  163. * include this as a capability to GeodesicLineExact because this is
  164. * included by default.)
  165. * @hideinitializer
  166. **********************************************************************/
  167. AZIMUTH = 1U<<9 | CAP_NONE,
  168. /**
  169. * Calculate distance \e s12.
  170. * @hideinitializer
  171. **********************************************************************/
  172. DISTANCE = 1U<<10 | CAP_E,
  173. /**
  174. * Allow distance \e s12 to be used as input in the direct geodesic
  175. * problem.
  176. * @hideinitializer
  177. **********************************************************************/
  178. DISTANCE_IN = 1U<<11 | CAP_E,
  179. /**
  180. * Calculate reduced length \e m12.
  181. * @hideinitializer
  182. **********************************************************************/
  183. REDUCEDLENGTH = 1U<<12 | CAP_D,
  184. /**
  185. * Calculate geodesic scales \e M12 and \e M21.
  186. * @hideinitializer
  187. **********************************************************************/
  188. GEODESICSCALE = 1U<<13 | CAP_D,
  189. /**
  190. * Calculate area \e S12.
  191. * @hideinitializer
  192. **********************************************************************/
  193. AREA = 1U<<14 | CAP_C4,
  194. /**
  195. * Unroll \e lon2 in the direct calculation.
  196. * @hideinitializer
  197. **********************************************************************/
  198. LONG_UNROLL = 1U<<15,
  199. /**
  200. * All capabilities, calculate everything. (LONG_UNROLL is not
  201. * included in this mask.)
  202. * @hideinitializer
  203. **********************************************************************/
  204. ALL = OUT_ALL| CAP_ALL,
  205. };
  206. /** \name Constructor
  207. **********************************************************************/
  208. ///@{
  209. /**
  210. * Constructor for a ellipsoid with
  211. *
  212. * @param[in] a equatorial radius (meters).
  213. * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
  214. * Negative \e f gives a prolate ellipsoid.
  215. * @exception GeographicErr if \e a or (1 &minus; \e f) \e a is not
  216. * positive.
  217. **********************************************************************/
  218. GeodesicExact(real a, real f);
  219. ///@}
  220. /** \name Direct geodesic problem specified in terms of distance.
  221. **********************************************************************/
  222. ///@{
  223. /**
  224. * Perform the direct geodesic calculation where the length of the geodesic
  225. * is specified in terms of distance.
  226. *
  227. * @param[in] lat1 latitude of point 1 (degrees).
  228. * @param[in] lon1 longitude of point 1 (degrees).
  229. * @param[in] azi1 azimuth at point 1 (degrees).
  230. * @param[in] s12 distance between point 1 and point 2 (meters); it can be
  231. * signed.
  232. * @param[out] lat2 latitude of point 2 (degrees).
  233. * @param[out] lon2 longitude of point 2 (degrees).
  234. * @param[out] azi2 (forward) azimuth at point 2 (degrees).
  235. * @param[out] m12 reduced length of geodesic (meters).
  236. * @param[out] M12 geodesic scale of point 2 relative to point 1
  237. * (dimensionless).
  238. * @param[out] M21 geodesic scale of point 1 relative to point 2
  239. * (dimensionless).
  240. * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
  241. * @return \e a12 arc length of between point 1 and point 2 (degrees).
  242. *
  243. * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]. The values of
  244. * \e lon2 and \e azi2 returned are in the range [&minus;180&deg;,
  245. * 180&deg;].
  246. *
  247. * If either point is at a pole, the azimuth is defined by keeping the
  248. * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;),
  249. * and taking the limit &epsilon; &rarr; 0+. An arc length greater that
  250. * 180&deg; signifies a geodesic which is not a shortest path. (For a
  251. * prolate ellipsoid, an additional condition is necessary for a shortest
  252. * path: the longitudinal extent must not exceed of 180&deg;.)
  253. *
  254. * The following functions are overloaded versions of GeodesicExact::Direct
  255. * which omit some of the output parameters. Note, however, that the arc
  256. * length is always computed and returned as the function value.
  257. **********************************************************************/
  258. Math::real Direct(real lat1, real lon1, real azi1, real s12,
  259. real& lat2, real& lon2, real& azi2,
  260. real& m12, real& M12, real& M21, real& S12)
  261. const {
  262. real t;
  263. return GenDirect(lat1, lon1, azi1, false, s12,
  264. LATITUDE | LONGITUDE | AZIMUTH |
  265. REDUCEDLENGTH | GEODESICSCALE | AREA,
  266. lat2, lon2, azi2, t, m12, M12, M21, S12);
  267. }
  268. /**
  269. * See the documentation for GeodesicExact::Direct.
  270. **********************************************************************/
  271. Math::real Direct(real lat1, real lon1, real azi1, real s12,
  272. real& lat2, real& lon2)
  273. const {
  274. real t;
  275. return GenDirect(lat1, lon1, azi1, false, s12,
  276. LATITUDE | LONGITUDE,
  277. lat2, lon2, t, t, t, t, t, t);
  278. }
  279. /**
  280. * See the documentation for GeodesicExact::Direct.
  281. **********************************************************************/
  282. Math::real Direct(real lat1, real lon1, real azi1, real s12,
  283. real& lat2, real& lon2, real& azi2)
  284. const {
  285. real t;
  286. return GenDirect(lat1, lon1, azi1, false, s12,
  287. LATITUDE | LONGITUDE | AZIMUTH,
  288. lat2, lon2, azi2, t, t, t, t, t);
  289. }
  290. /**
  291. * See the documentation for GeodesicExact::Direct.
  292. **********************************************************************/
  293. Math::real Direct(real lat1, real lon1, real azi1, real s12,
  294. real& lat2, real& lon2, real& azi2, real& m12)
  295. const {
  296. real t;
  297. return GenDirect(lat1, lon1, azi1, false, s12,
  298. LATITUDE | LONGITUDE | AZIMUTH | REDUCEDLENGTH,
  299. lat2, lon2, azi2, t, m12, t, t, t);
  300. }
  301. /**
  302. * See the documentation for GeodesicExact::Direct.
  303. **********************************************************************/
  304. Math::real Direct(real lat1, real lon1, real azi1, real s12,
  305. real& lat2, real& lon2, real& azi2,
  306. real& M12, real& M21)
  307. const {
  308. real t;
  309. return GenDirect(lat1, lon1, azi1, false, s12,
  310. LATITUDE | LONGITUDE | AZIMUTH | GEODESICSCALE,
  311. lat2, lon2, azi2, t, t, M12, M21, t);
  312. }
  313. /**
  314. * See the documentation for GeodesicExact::Direct.
  315. **********************************************************************/
  316. Math::real Direct(real lat1, real lon1, real azi1, real s12,
  317. real& lat2, real& lon2, real& azi2,
  318. real& m12, real& M12, real& M21)
  319. const {
  320. real t;
  321. return GenDirect(lat1, lon1, azi1, false, s12,
  322. LATITUDE | LONGITUDE | AZIMUTH |
  323. REDUCEDLENGTH | GEODESICSCALE,
  324. lat2, lon2, azi2, t, m12, M12, M21, t);
  325. }
  326. ///@}
  327. /** \name Direct geodesic problem specified in terms of arc length.
  328. **********************************************************************/
  329. ///@{
  330. /**
  331. * Perform the direct geodesic calculation where the length of the geodesic
  332. * is specified in terms of arc length.
  333. *
  334. * @param[in] lat1 latitude of point 1 (degrees).
  335. * @param[in] lon1 longitude of point 1 (degrees).
  336. * @param[in] azi1 azimuth at point 1 (degrees).
  337. * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
  338. * be signed.
  339. * @param[out] lat2 latitude of point 2 (degrees).
  340. * @param[out] lon2 longitude of point 2 (degrees).
  341. * @param[out] azi2 (forward) azimuth at point 2 (degrees).
  342. * @param[out] s12 distance between point 1 and point 2 (meters).
  343. * @param[out] m12 reduced length of geodesic (meters).
  344. * @param[out] M12 geodesic scale of point 2 relative to point 1
  345. * (dimensionless).
  346. * @param[out] M21 geodesic scale of point 1 relative to point 2
  347. * (dimensionless).
  348. * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
  349. *
  350. * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]. The values of
  351. * \e lon2 and \e azi2 returned are in the range [&minus;180&deg;,
  352. * 180&deg;].
  353. *
  354. * If either point is at a pole, the azimuth is defined by keeping the
  355. * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;),
  356. * and taking the limit &epsilon; &rarr; 0+. An arc length greater that
  357. * 180&deg; signifies a geodesic which is not a shortest path. (For a
  358. * prolate ellipsoid, an additional condition is necessary for a shortest
  359. * path: the longitudinal extent must not exceed of 180&deg;.)
  360. *
  361. * The following functions are overloaded versions of GeodesicExact::Direct
  362. * which omit some of the output parameters.
  363. **********************************************************************/
  364. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  365. real& lat2, real& lon2, real& azi2, real& s12,
  366. real& m12, real& M12, real& M21, real& S12)
  367. const {
  368. GenDirect(lat1, lon1, azi1, true, a12,
  369. LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
  370. REDUCEDLENGTH | GEODESICSCALE | AREA,
  371. lat2, lon2, azi2, s12, m12, M12, M21, S12);
  372. }
  373. /**
  374. * See the documentation for GeodesicExact::ArcDirect.
  375. **********************************************************************/
  376. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  377. real& lat2, real& lon2) const {
  378. real t;
  379. GenDirect(lat1, lon1, azi1, true, a12,
  380. LATITUDE | LONGITUDE,
  381. lat2, lon2, t, t, t, t, t, t);
  382. }
  383. /**
  384. * See the documentation for GeodesicExact::ArcDirect.
  385. **********************************************************************/
  386. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  387. real& lat2, real& lon2, real& azi2) const {
  388. real t;
  389. GenDirect(lat1, lon1, azi1, true, a12,
  390. LATITUDE | LONGITUDE | AZIMUTH,
  391. lat2, lon2, azi2, t, t, t, t, t);
  392. }
  393. /**
  394. * See the documentation for GeodesicExact::ArcDirect.
  395. **********************************************************************/
  396. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  397. real& lat2, real& lon2, real& azi2, real& s12)
  398. const {
  399. real t;
  400. GenDirect(lat1, lon1, azi1, true, a12,
  401. LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
  402. lat2, lon2, azi2, s12, t, t, t, t);
  403. }
  404. /**
  405. * See the documentation for GeodesicExact::ArcDirect.
  406. **********************************************************************/
  407. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  408. real& lat2, real& lon2, real& azi2,
  409. real& s12, real& m12) const {
  410. real t;
  411. GenDirect(lat1, lon1, azi1, true, a12,
  412. LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
  413. REDUCEDLENGTH,
  414. lat2, lon2, azi2, s12, m12, t, t, t);
  415. }
  416. /**
  417. * See the documentation for GeodesicExact::ArcDirect.
  418. **********************************************************************/
  419. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  420. real& lat2, real& lon2, real& azi2, real& s12,
  421. real& M12, real& M21) const {
  422. real t;
  423. GenDirect(lat1, lon1, azi1, true, a12,
  424. LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
  425. GEODESICSCALE,
  426. lat2, lon2, azi2, s12, t, M12, M21, t);
  427. }
  428. /**
  429. * See the documentation for GeodesicExact::ArcDirect.
  430. **********************************************************************/
  431. void ArcDirect(real lat1, real lon1, real azi1, real a12,
  432. real& lat2, real& lon2, real& azi2, real& s12,
  433. real& m12, real& M12, real& M21) const {
  434. real t;
  435. GenDirect(lat1, lon1, azi1, true, a12,
  436. LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
  437. REDUCEDLENGTH | GEODESICSCALE,
  438. lat2, lon2, azi2, s12, m12, M12, M21, t);
  439. }
  440. ///@}
  441. /** \name General version of the direct geodesic solution.
  442. **********************************************************************/
  443. ///@{
  444. /**
  445. * The general direct geodesic calculation. GeodesicExact::Direct and
  446. * GeodesicExact::ArcDirect are defined in terms of this function.
  447. *
  448. * @param[in] lat1 latitude of point 1 (degrees).
  449. * @param[in] lon1 longitude of point 1 (degrees).
  450. * @param[in] azi1 azimuth at point 1 (degrees).
  451. * @param[in] arcmode boolean flag determining the meaning of the second
  452. * parameter.
  453. * @param[in] s12_a12 if \e arcmode is false, this is the distance between
  454. * point 1 and point 2 (meters); otherwise it is the arc length between
  455. * point 1 and point 2 (degrees); it can be signed.
  456. * @param[in] outmask a bitor'ed combination of GeodesicExact::mask values
  457. * specifying which of the following parameters should be set.
  458. * @param[out] lat2 latitude of point 2 (degrees).
  459. * @param[out] lon2 longitude of point 2 (degrees).
  460. * @param[out] azi2 (forward) azimuth at point 2 (degrees).
  461. * @param[out] s12 distance between point 1 and point 2 (meters).
  462. * @param[out] m12 reduced length of geodesic (meters).
  463. * @param[out] M12 geodesic scale of point 2 relative to point 1
  464. * (dimensionless).
  465. * @param[out] M21 geodesic scale of point 1 relative to point 2
  466. * (dimensionless).
  467. * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
  468. * @return \e a12 arc length of between point 1 and point 2 (degrees).
  469. *
  470. * The GeodesicExact::mask values possible for \e outmask are
  471. * - \e outmask |= GeodesicExact::LATITUDE for the latitude \e lat2;
  472. * - \e outmask |= GeodesicExact::LONGITUDE for the latitude \e lon2;
  473. * - \e outmask |= GeodesicExact::AZIMUTH for the latitude \e azi2;
  474. * - \e outmask |= GeodesicExact::DISTANCE for the distance \e s12;
  475. * - \e outmask |= GeodesicExact::REDUCEDLENGTH for the reduced length \e
  476. * m12;
  477. * - \e outmask |= GeodesicExact::GEODESICSCALE for the geodesic scales \e
  478. * M12 and \e M21;
  479. * - \e outmask |= GeodesicExact::AREA for the area \e S12;
  480. * - \e outmask |= GeodesicExact::ALL for all of the above;
  481. * - \e outmask |= GeodesicExact::LONG_UNROLL to unroll \e lon2 instead of
  482. * wrapping it into the range [&minus;180&deg;, 180&deg;].
  483. * .
  484. * The function value \e a12 is always computed and returned and this
  485. * equals \e s12_a12 is \e arcmode is true. If \e outmask includes
  486. * GeodesicExact::DISTANCE and \e arcmode is false, then \e s12 = \e
  487. * s12_a12. It is not necessary to include GeodesicExact::DISTANCE_IN in
  488. * \e outmask; this is automatically included is \e arcmode is false.
  489. *
  490. * With the GeodesicExact::LONG_UNROLL bit set, the quantity \e lon2
  491. * &minus; \e lon1 indicates how many times and in what sense the geodesic
  492. * encircles the ellipsoid.
  493. **********************************************************************/
  494. Math::real GenDirect(real lat1, real lon1, real azi1,
  495. bool arcmode, real s12_a12, unsigned outmask,
  496. real& lat2, real& lon2, real& azi2,
  497. real& s12, real& m12, real& M12, real& M21,
  498. real& S12) const;
  499. ///@}
  500. /** \name Inverse geodesic problem.
  501. **********************************************************************/
  502. ///@{
  503. /**
  504. * Perform the inverse geodesic calculation.
  505. *
  506. * @param[in] lat1 latitude of point 1 (degrees).
  507. * @param[in] lon1 longitude of point 1 (degrees).
  508. * @param[in] lat2 latitude of point 2 (degrees).
  509. * @param[in] lon2 longitude of point 2 (degrees).
  510. * @param[out] s12 distance between point 1 and point 2 (meters).
  511. * @param[out] azi1 azimuth at point 1 (degrees).
  512. * @param[out] azi2 (forward) azimuth at point 2 (degrees).
  513. * @param[out] m12 reduced length of geodesic (meters).
  514. * @param[out] M12 geodesic scale of point 2 relative to point 1
  515. * (dimensionless).
  516. * @param[out] M21 geodesic scale of point 1 relative to point 2
  517. * (dimensionless).
  518. * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
  519. * @return \e a12 arc length of between point 1 and point 2 (degrees).
  520. *
  521. * \e lat1 and \e lat2 should be in the range [&minus;90&deg;, 90&deg;].
  522. * The values of \e azi1 and \e azi2 returned are in the range
  523. * [&minus;180&deg;, 180&deg;].
  524. *
  525. * If either point is at a pole, the azimuth is defined by keeping the
  526. * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;),
  527. * and taking the limit &epsilon; &rarr; 0+.
  528. *
  529. * The following functions are overloaded versions of
  530. * GeodesicExact::Inverse which omit some of the output parameters. Note,
  531. * however, that the arc length is always computed and returned as the
  532. * function value.
  533. **********************************************************************/
  534. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  535. real& s12, real& azi1, real& azi2, real& m12,
  536. real& M12, real& M21, real& S12) const {
  537. return GenInverse(lat1, lon1, lat2, lon2,
  538. DISTANCE | AZIMUTH |
  539. REDUCEDLENGTH | GEODESICSCALE | AREA,
  540. s12, azi1, azi2, m12, M12, M21, S12);
  541. }
  542. /**
  543. * See the documentation for GeodesicExact::Inverse.
  544. **********************************************************************/
  545. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  546. real& s12) const {
  547. real t;
  548. return GenInverse(lat1, lon1, lat2, lon2,
  549. DISTANCE,
  550. s12, t, t, t, t, t, t);
  551. }
  552. /**
  553. * See the documentation for GeodesicExact::Inverse.
  554. **********************************************************************/
  555. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  556. real& azi1, real& azi2) const {
  557. real t;
  558. return GenInverse(lat1, lon1, lat2, lon2,
  559. AZIMUTH,
  560. t, azi1, azi2, t, t, t, t);
  561. }
  562. /**
  563. * See the documentation for GeodesicExact::Inverse.
  564. **********************************************************************/
  565. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  566. real& s12, real& azi1, real& azi2)
  567. const {
  568. real t;
  569. return GenInverse(lat1, lon1, lat2, lon2,
  570. DISTANCE | AZIMUTH,
  571. s12, azi1, azi2, t, t, t, t);
  572. }
  573. /**
  574. * See the documentation for GeodesicExact::Inverse.
  575. **********************************************************************/
  576. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  577. real& s12, real& azi1, real& azi2, real& m12)
  578. const {
  579. real t;
  580. return GenInverse(lat1, lon1, lat2, lon2,
  581. DISTANCE | AZIMUTH | REDUCEDLENGTH,
  582. s12, azi1, azi2, m12, t, t, t);
  583. }
  584. /**
  585. * See the documentation for GeodesicExact::Inverse.
  586. **********************************************************************/
  587. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  588. real& s12, real& azi1, real& azi2,
  589. real& M12, real& M21) const {
  590. real t;
  591. return GenInverse(lat1, lon1, lat2, lon2,
  592. DISTANCE | AZIMUTH | GEODESICSCALE,
  593. s12, azi1, azi2, t, M12, M21, t);
  594. }
  595. /**
  596. * See the documentation for GeodesicExact::Inverse.
  597. **********************************************************************/
  598. Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
  599. real& s12, real& azi1, real& azi2, real& m12,
  600. real& M12, real& M21) const {
  601. real t;
  602. return GenInverse(lat1, lon1, lat2, lon2,
  603. DISTANCE | AZIMUTH |
  604. REDUCEDLENGTH | GEODESICSCALE,
  605. s12, azi1, azi2, m12, M12, M21, t);
  606. }
  607. ///@}
  608. /** \name General version of inverse geodesic solution.
  609. **********************************************************************/
  610. ///@{
  611. /**
  612. * The general inverse geodesic calculation. GeodesicExact::Inverse is
  613. * defined in terms of this function.
  614. *
  615. * @param[in] lat1 latitude of point 1 (degrees).
  616. * @param[in] lon1 longitude of point 1 (degrees).
  617. * @param[in] lat2 latitude of point 2 (degrees).
  618. * @param[in] lon2 longitude of point 2 (degrees).
  619. * @param[in] outmask a bitor'ed combination of GeodesicExact::mask values
  620. * specifying which of the following parameters should be set.
  621. * @param[out] s12 distance between point 1 and point 2 (meters).
  622. * @param[out] azi1 azimuth at point 1 (degrees).
  623. * @param[out] azi2 (forward) azimuth at point 2 (degrees).
  624. * @param[out] m12 reduced length of geodesic (meters).
  625. * @param[out] M12 geodesic scale of point 2 relative to point 1
  626. * (dimensionless).
  627. * @param[out] M21 geodesic scale of point 1 relative to point 2
  628. * (dimensionless).
  629. * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
  630. * @return \e a12 arc length of between point 1 and point 2 (degrees).
  631. *
  632. * The GeodesicExact::mask values possible for \e outmask are
  633. * - \e outmask |= GeodesicExact::DISTANCE for the distance \e s12;
  634. * - \e outmask |= GeodesicExact::AZIMUTH for the latitude \e azi2;
  635. * - \e outmask |= GeodesicExact::REDUCEDLENGTH for the reduced length \e
  636. * m12;
  637. * - \e outmask |= GeodesicExact::GEODESICSCALE for the geodesic scales \e
  638. * M12 and \e M21;
  639. * - \e outmask |= GeodesicExact::AREA for the area \e S12;
  640. * - \e outmask |= GeodesicExact::ALL for all of the above.
  641. * .
  642. * The arc length is always computed and returned as the function value.
  643. **********************************************************************/
  644. Math::real GenInverse(real lat1, real lon1, real lat2, real lon2,
  645. unsigned outmask,
  646. real& s12, real& azi1, real& azi2,
  647. real& m12, real& M12, real& M21, real& S12) const;
  648. ///@}
  649. /** \name Interface to GeodesicLineExact.
  650. **********************************************************************/
  651. ///@{
  652. /**
  653. * Set up to compute several points on a single geodesic.
  654. *
  655. * @param[in] lat1 latitude of point 1 (degrees).
  656. * @param[in] lon1 longitude of point 1 (degrees).
  657. * @param[in] azi1 azimuth at point 1 (degrees).
  658. * @param[in] caps bitor'ed combination of GeodesicExact::mask values
  659. * specifying the capabilities the GeodesicLineExact object should
  660. * possess, i.e., which quantities can be returned in calls to
  661. * GeodesicLineExact::Position.
  662. * @return a GeodesicLineExact object.
  663. *
  664. * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
  665. *
  666. * The GeodesicExact::mask values are
  667. * - \e caps |= GeodesicExact::LATITUDE for the latitude \e lat2; this is
  668. * added automatically;
  669. * - \e caps |= GeodesicExact::LONGITUDE for the latitude \e lon2;
  670. * - \e caps |= GeodesicExact::AZIMUTH for the azimuth \e azi2; this is
  671. * added automatically;
  672. * - \e caps |= GeodesicExact::DISTANCE for the distance \e s12;
  673. * - \e caps |= GeodesicExact::REDUCEDLENGTH for the reduced length \e m12;
  674. * - \e caps |= GeodesicExact::GEODESICSCALE for the geodesic scales \e M12
  675. * and \e M21;
  676. * - \e caps |= GeodesicExact::AREA for the area \e S12;
  677. * - \e caps |= GeodesicExact::DISTANCE_IN permits the length of the
  678. * geodesic to be given in terms of \e s12; without this capability the
  679. * length can only be specified in terms of arc length;
  680. * - \e caps |= GeodesicExact::ALL for all of the above.
  681. * .
  682. * The default value of \e caps is GeodesicExact::ALL which turns on all
  683. * the capabilities.
  684. *
  685. * If the point is at a pole, the azimuth is defined by keeping \e lon1
  686. * fixed, writing \e lat1 = &plusmn;(90 &minus; &epsilon;), and taking the
  687. * limit &epsilon; &rarr; 0+.
  688. **********************************************************************/
  689. GeodesicLineExact Line(real lat1, real lon1, real azi1,
  690. unsigned caps = ALL) const;
  691. /**
  692. * Define a GeodesicLineExact in terms of the inverse geodesic problem.
  693. *
  694. * @param[in] lat1 latitude of point 1 (degrees).
  695. * @param[in] lon1 longitude of point 1 (degrees).
  696. * @param[in] lat2 latitude of point 2 (degrees).
  697. * @param[in] lon2 longitude of point 2 (degrees).
  698. * @param[in] caps bitor'ed combination of GeodesicExact::mask values
  699. * specifying the capabilities the GeodesicLineExact object should
  700. * possess, i.e., which quantities can be returned in calls to
  701. * GeodesicLineExact::Position.
  702. * @return a GeodesicLineExact object.
  703. *
  704. * This function sets point 3 of the GeodesicLineExact to correspond to
  705. * point 2 of the inverse geodesic problem.
  706. *
  707. * \e lat1 and \e lat2 should be in the range [&minus;90&deg;, 90&deg;].
  708. **********************************************************************/
  709. GeodesicLineExact InverseLine(real lat1, real lon1, real lat2, real lon2,
  710. unsigned caps = ALL) const;
  711. /**
  712. * Define a GeodesicLineExact in terms of the direct geodesic problem
  713. * specified in terms of distance.
  714. *
  715. * @param[in] lat1 latitude of point 1 (degrees).
  716. * @param[in] lon1 longitude of point 1 (degrees).
  717. * @param[in] azi1 azimuth at point 1 (degrees).
  718. * @param[in] s12 distance between point 1 and point 2 (meters); it can be
  719. * negative.
  720. * @param[in] caps bitor'ed combination of GeodesicExact::mask values
  721. * specifying the capabilities the GeodesicLineExact object should
  722. * possess, i.e., which quantities can be returned in calls to
  723. * GeodesicLineExact::Position.
  724. * @return a GeodesicLineExact object.
  725. *
  726. * This function sets point 3 of the GeodesicLineExact to correspond to
  727. * point 2 of the direct geodesic problem.
  728. *
  729. * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
  730. **********************************************************************/
  731. GeodesicLineExact DirectLine(real lat1, real lon1, real azi1, real s12,
  732. unsigned caps = ALL) const;
  733. /**
  734. * Define a GeodesicLineExact in terms of the direct geodesic problem
  735. * specified in terms of arc length.
  736. *
  737. * @param[in] lat1 latitude of point 1 (degrees).
  738. * @param[in] lon1 longitude of point 1 (degrees).
  739. * @param[in] azi1 azimuth at point 1 (degrees).
  740. * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
  741. * be negative.
  742. * @param[in] caps bitor'ed combination of GeodesicExact::mask values
  743. * specifying the capabilities the GeodesicLineExact object should
  744. * possess, i.e., which quantities can be returned in calls to
  745. * GeodesicLineExact::Position.
  746. * @return a GeodesicLineExact object.
  747. *
  748. * This function sets point 3 of the GeodesicLineExact to correspond to
  749. * point 2 of the direct geodesic problem.
  750. *
  751. * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
  752. **********************************************************************/
  753. GeodesicLineExact ArcDirectLine(real lat1, real lon1, real azi1, real a12,
  754. unsigned caps = ALL) const;
  755. /**
  756. * Define a GeodesicLineExact in terms of the direct geodesic problem
  757. * specified in terms of either distance or arc length.
  758. *
  759. * @param[in] lat1 latitude of point 1 (degrees).
  760. * @param[in] lon1 longitude of point 1 (degrees).
  761. * @param[in] azi1 azimuth at point 1 (degrees).
  762. * @param[in] arcmode boolean flag determining the meaning of the \e
  763. * s12_a12.
  764. * @param[in] s12_a12 if \e arcmode is false, this is the distance between
  765. * point 1 and point 2 (meters); otherwise it is the arc length between
  766. * point 1 and point 2 (degrees); it can be negative.
  767. * @param[in] caps bitor'ed combination of GeodesicExact::mask values
  768. * specifying the capabilities the GeodesicLineExact object should
  769. * possess, i.e., which quantities can be returned in calls to
  770. * GeodesicLineExact::Position.
  771. * @return a GeodesicLineExact object.
  772. *
  773. * This function sets point 3 of the GeodesicLineExact to correspond to
  774. * point 2 of the direct geodesic problem.
  775. *
  776. * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
  777. **********************************************************************/
  778. GeodesicLineExact GenDirectLine(real lat1, real lon1, real azi1,
  779. bool arcmode, real s12_a12,
  780. unsigned caps = ALL) const;
  781. ///@}
  782. /** \name Inspector functions.
  783. **********************************************************************/
  784. ///@{
  785. /**
  786. * @return \e a the equatorial radius of the ellipsoid (meters). This is
  787. * the value used in the constructor.
  788. **********************************************************************/
  789. Math::real EquatorialRadius() const { return _a; }
  790. /**
  791. * @return \e f the flattening of the ellipsoid. This is the
  792. * value used in the constructor.
  793. **********************************************************************/
  794. Math::real Flattening() const { return _f; }
  795. /**
  796. * @return total area of ellipsoid in meters<sup>2</sup>. The area of a
  797. * polygon encircling a pole can be found by adding
  798. * GeodesicExact::EllipsoidArea()/2 to the sum of \e S12 for each side of
  799. * the polygon.
  800. **********************************************************************/
  801. Math::real EllipsoidArea() const
  802. { return 4 * Math::pi() * _c2; }
  803. /**
  804. * \deprecated An old name for EquatorialRadius().
  805. **********************************************************************/
  806. GEOGRAPHICLIB_DEPRECATED("Use EquatorialRadius()")
  807. Math::real MajorRadius() const { return EquatorialRadius(); }
  808. ///@}
  809. /**
  810. * A global instantiation of GeodesicExact with the parameters for the
  811. * WGS84 ellipsoid.
  812. **********************************************************************/
  813. static const GeodesicExact& WGS84();
  814. };
  815. } // namespace GeographicLib
  816. #endif // GEOGRAPHICLIB_GEODESICEXACT_HPP