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