GeographicLib  1.41
Rhumb.hpp
Go to the documentation of this file.
1 /**
2  * \file Rhumb.hpp
3  * \brief Header for GeographicLib::Rhumb and GeographicLib::RhumbLine classes
4  *
5  * Copyright (c) Charles Karney (2014-2015) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_RHUMB_HPP)
11 #define GEOGRAPHICLIB_RHUMB_HPP 1
12 
15 
16 #if !defined(GEOGRAPHICLIB_RHUMBAREA_ORDER)
17 /**
18  * The order of the series approximation used in rhumb area calculations.
19  * GEOGRAPHICLIB_RHUMBAREA_ORDER can be set to any integer in [4, 8].
20  **********************************************************************/
21 # define GEOGRAPHICLIB_RHUMBAREA_ORDER \
22  (GEOGRAPHICLIB_PRECISION == 2 ? 6 : \
23  (GEOGRAPHICLIB_PRECISION == 1 ? 4 : 8))
24 #endif
25 
26 namespace GeographicLib {
27 
28  class RhumbLine;
29  template <class T> class PolygonAreaT;
30 
31  /**
32  * \brief Solve of the direct and inverse rhumb problems.
33  *
34  * The path of constant azimuth between two points on a ellipsoid at (\e
35  * lat1, \e lon1) and (\e lat2, \e lon2) is called the rhumb line (also
36  * called the loxodrome). Its length is \e s12 and its azimuth is \e azi12.
37  * (The azimuth is the heading measured clockwise from north.)
38  *
39  * Given \e lat1, \e lon1, \e azi12, and \e s12, we can determine \e lat2,
40  * and \e lon2. This is the \e direct rhumb problem and its solution is
41  * given by the function Rhumb::Direct.
42  *
43  * Given \e lat1, \e lon1, \e lat2, and \e lon2, we can determine \e azi12
44  * and \e s12. This is the \e inverse rhumb problem, whose solution is given
45  * by Rhumb::Inverse. This finds the shortest such rhumb line, i.e., the one
46  * that wraps no more than half way around the earth. If the end points are
47  * on opposite meridians, there are two shortest rhumb lines and the
48  * east-going one is chosen.
49  *
50  * These routines also optionally calculate the area under the rhumb line, \e
51  * S12. This is the area, measured counter-clockwise, of the rhumb line
52  * quadrilateral with corners (<i>lat1</i>,<i>lon1</i>), (0,<i>lon1</i>),
53  * (0,<i>lon2</i>), and (<i>lat2</i>,<i>lon2</i>).
54  *
55  * Note that rhumb lines may be appreciably longer (up to 50%) than the
56  * corresponding Geodesic. For example the distance between London Heathrow
57  * and Tokyo Narita via the rhumb line is 11400 km which is 18% longer than
58  * the geodesic distance 9600 km.
59  *
60  * For more information on rhumb lines see \ref rhumb.
61  *
62  * Example of use:
63  * \include example-Rhumb.cpp
64  **********************************************************************/
65 
67  private:
68  typedef Math::real real;
69  friend class RhumbLine;
70  template <class T> friend class PolygonAreaT;
71  Ellipsoid _ell;
72  bool _exact;
73  real _c2;
74  static const int tm_maxord = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER;
75  static const int maxpow_ = GEOGRAPHICLIB_RHUMBAREA_ORDER;
76  // _R[0] unused
77  real _R[maxpow_ + 1];
78  static inline real overflow() {
79  // Overflow value s.t. atan(overflow_) = pi/2
80  static const real
81  overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
82  return overflow;
83  }
84  static inline real tano(real x) {
85  using std::abs; using std::tan;
86  // Need the volatile declaration for optimized builds on 32-bit centos
87  // with g++ 4.4.7
88  GEOGRAPHICLIB_VOLATILE real y = 2 * abs(x);
89  return
90  y == Math::pi() ? (x < 0 ? - overflow() : overflow()) : tan(x);
91  }
92  static inline real gd(real x)
93  { using std::atan; using std::sinh; return atan(sinh(x)); }
94 
95  // Use divided differences to determine (mu2 - mu1) / (psi2 - psi1)
96  // accurately
97  //
98  // Definition: Df(x,y,d) = (f(x) - f(y)) / (x - y)
99  // See:
100  // W. M. Kahan and R. J. Fateman,
101  // Symbolic computation of divided differences,
102  // SIGSAM Bull. 33(3), 7-28 (1999)
103  // https://dx.doi.org/10.1145/334714.334716
104  // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf
105 
106  static inline real Dlog(real x, real y) {
107  real t = x - y;
108  return t ? 2 * Math::atanh(t / (x + y)) / t : 1 / x;
109  }
110  static inline real Dtan(real x, real y) {
111  real d = x - y, tx = tano(x), ty = tano(y), txy = tx * ty;
112  return d ? (2 * txy > -1 ? (1 + txy) * tano(d) : tx - ty) / d :
113  1 + txy;
114  }
115  static inline real Datan(real x, real y) {
116  using std::atan;
117  real d = x - y, xy = x * y;
118  return d ? (2 * xy > -1 ? atan( d / (1 + xy) ) : atan(x) - atan(y)) / d :
119  1 / (1 + xy);
120  }
121  static inline real Dsin(real x, real y) {
122  using std::sin; using std::cos;
123  real d = (x - y) / 2;
124  return cos((x + y)/2) * (d ? sin(d) / d : 1);
125  }
126  static inline real Dsinh(real x, real y) {
127  using std::sinh; using std::cosh;
128  real d = (x - y) / 2;
129  return cosh((x + y) / 2) * (d ? sinh(d) / d : 1);
130  }
131  static inline real Dcosh(real x, real y) {
132  using std::sinh;
133  real d = (x - y) / 2;
134  return sinh((x + y) / 2) * (d ? sinh(d) / d : 1);
135  }
136  static inline real Dasinh(real x, real y) {
137  real d = x - y,
138  hx = Math::hypot(real(1), x), hy = Math::hypot(real(1), y);
139  return d ? Math::asinh(x*y > 0 ? d * (x + y) / (x*hy + y*hx) :
140  x*hy - y*hx) / d :
141  1 / hx;
142  }
143  static inline real Dgd(real x, real y) {
144  using std::sinh;
145  return Datan(sinh(x), sinh(y)) * Dsinh(x, y);
146  }
147  static inline real Dgdinv(real x, real y) {
148  return Dasinh(tano(x), tano(y)) * Dtan(x, y);
149  }
150  // Copied from LambertConformalConic...
151  // e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0
152  // - sqrt(-e2) * atan( sqrt(-e2) * x) if f < 0
153  inline real eatanhe(real x) const {
154  using std::atan;
155  return _ell._f >= 0 ? _ell._e * Math::atanh(_ell._e * x) :
156  - _ell._e * atan(_ell._e * x);
157  }
158  // Copied from LambertConformalConic...
159  // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y)
160  inline real Deatanhe(real x, real y) const {
161  real t = x - y, d = 1 - _ell._e2 * x * y;
162  return t ? eatanhe(t / d) / t : _ell._e2 / d;
163  }
164  // (E(x) - E(y)) / (x - y) -- E = incomplete elliptic integral of 2nd kind
165  real DE(real x, real y) const;
166  // (mux - muy) / (phix - phiy) using elliptic integrals
167  real DRectifying(real latx, real laty) const;
168  // (psix - psiy) / (phix - phiy)
169  real DIsometric(real latx, real laty) const;
170 
171  // (sum(c[j]*sin(2*j*x),j=1..n) - sum(c[j]*sin(2*j*x),j=1..n)) / (x - y)
172  static real SinCosSeries(bool sinp,
173  real x, real y, const real c[], int n);
174  // (mux - muy) / (chix - chiy) using Krueger's series
175  real DConformalToRectifying(real chix, real chiy) const;
176  // (chix - chiy) / (mux - muy) using Krueger's series
177  real DRectifyingToConformal(real mux, real muy) const;
178 
179  // (mux - muy) / (psix - psiy)
180  real DIsometricToRectifying(real psix, real psiy) const;
181  // (psix - psiy) / (mux - muy)
182  real DRectifyingToIsometric(real mux, real muy) const;
183 
184  real MeanSinXi(real psi1, real psi2) const;
185 
186  // The following two functions (with lots of ignored arguments) mimic the
187  // interface to the corresponding Geodesic function. These are needed by
188  // PolygonAreaT.
189  void GenDirect(real lat1, real lon1, real azi12,
190  bool, real s12, unsigned outmask,
191  real& lat2, real& lon2, real&, real&, real&, real&, real&,
192  real& S12) const {
193  GenDirect(lat1, lon1, azi12, s12, outmask, lat2, lon2, S12);
194  }
195  void GenInverse(real lat1, real lon1, real lat2, real lon2,
196  unsigned outmask, real& s12, real& azi12,
197  real&, real& , real& , real& , real& S12) const {
198  GenInverse(lat1, lon1, lat2, lon2, outmask, s12, azi12, S12);
199  }
200  public:
201 
202  /**
203  * Bit masks for what calculations to do. They specify which results to
204  * return in the general routines Rhumb::GenDirect and Rhumb::GenInverse
205  * routines. RhumbLine::mask is a duplication of this enum.
206  **********************************************************************/
207  enum mask {
208  /**
209  * No output.
210  * @hideinitializer
211  **********************************************************************/
212  NONE = 0U,
213  /**
214  * Calculate latitude \e lat2.
215  * @hideinitializer
216  **********************************************************************/
217  LATITUDE = 1U<<7,
218  /**
219  * Calculate longitude \e lon2.
220  * @hideinitializer
221  **********************************************************************/
222  LONGITUDE = 1U<<8,
223  /**
224  * Calculate azimuth \e azi12.
225  * @hideinitializer
226  **********************************************************************/
227  AZIMUTH = 1U<<9,
228  /**
229  * Calculate distance \e s12.
230  * @hideinitializer
231  **********************************************************************/
232  DISTANCE = 1U<<10,
233  /**
234  * Calculate area \e S12.
235  * @hideinitializer
236  **********************************************************************/
237  AREA = 1U<<14,
238  /**
239  * Do not wrap the \e lon2 in the direct calculation.
240  * @hideinitializer
241  **********************************************************************/
242  LONG_NOWRAP = 1U<<15,
243  /**
244  * Calculate everything. (LONG_NOWRAP is not included in this mask.)
245  * @hideinitializer
246  **********************************************************************/
247  ALL = 0x7F80U,
248  };
249 
250  /**
251  * Constructor for a ellipsoid with
252  *
253  * @param[in] a equatorial radius (meters).
254  * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
255  * Negative \e f gives a prolate ellipsoid. If \e f &gt; 1, set
256  * flattening to 1/\e f.
257  * @param[in] exact if true (the default) use an addition theorem for
258  * elliptic integrals to compute divided differences; otherwise use
259  * series expansion (accurate for |<i>f</i>| < 0.01).
260  * @exception GeographicErr if \e a or (1 &minus; \e f) \e a is not
261  * positive.
262  *
263  * See \ref rhumb, for a detailed description of the \e exact parameter.
264  **********************************************************************/
265  Rhumb(real a, real f, bool exact = true);
266 
267  /**
268  * Solve the direct rhumb problem returning also the area.
269  *
270  * @param[in] lat1 latitude of point 1 (degrees).
271  * @param[in] lon1 longitude of point 1 (degrees).
272  * @param[in] azi12 azimuth of the rhumb line (degrees).
273  * @param[in] s12 distance between point 1 and point 2 (meters); it can be
274  * negative.
275  * @param[out] lat2 latitude of point 2 (degrees).
276  * @param[out] lon2 longitude of point 2 (degrees).
277  * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
278  *
279  * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 and \e
280  * azi12 should be in the range [&minus;540&deg;, 540&deg;). The value of
281  * \e lon2 returned is in the range [&minus;180&deg;, 180&deg;).
282  *
283  * If point 1 is a pole, the cosine of its latitude is taken to be
284  * 1/&epsilon;<sup>2</sup> (where &epsilon; is 2<sup>-52</sup>). This
285  * position, which is extremely close to the actual pole, allows the
286  * calculation to be carried out in finite terms. If \e s12 is large
287  * enough that the rhumb line crosses a pole, the longitude of point 2
288  * is indeterminate (a NaN is returned for \e lon2 and \e S12).
289  **********************************************************************/
290  void Direct(real lat1, real lon1, real azi12, real s12,
291  real& lat2, real& lon2, real& S12) const {
292  GenDirect(lat1, lon1, azi12, s12,
293  LATITUDE | LONGITUDE | AREA, lat2, lon2, S12);
294  }
295 
296  /**
297  * Solve the direct rhumb problem without the area.
298  **********************************************************************/
299  void Direct(real lat1, real lon1, real azi12, real s12,
300  real& lat2, real& lon2) const {
301  real t;
302  GenDirect(lat1, lon1, azi12, s12, LATITUDE | LONGITUDE, lat2, lon2, t);
303  }
304 
305  /**
306  * The general direct rhumb problem. Rhumb::Direct is defined in terms
307  * of this function.
308  *
309  * @param[in] lat1 latitude of point 1 (degrees).
310  * @param[in] lon1 longitude of point 1 (degrees).
311  * @param[in] azi12 azimuth of the rhumb line (degrees).
312  * @param[in] s12 distance between point 1 and point 2 (meters); it can be
313  * negative.
314  * @param[in] outmask a bitor'ed combination of Rhumb::mask values
315  * specifying which of the following parameters should be set.
316  * @param[out] lat2 latitude of point 2 (degrees).
317  * @param[out] lon2 longitude of point 2 (degrees).
318  * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
319  *
320  * The Rhumb::mask values possible for \e outmask are
321  * - \e outmask |= Rhumb::LATITUDE for the latitude \e lat2;
322  * - \e outmask |= Rhumb::LONGITUDE for the latitude \e lon2;
323  * - \e outmask |= Rhumb::AREA for the area \e S12;
324  * - \e outmask |= Rhumb::ALL for all of the above;
325  * - \e outmask |= Rhumb::LONG_NOWRAP stops the returned value of \e
326  * lon2 being wrapped into the range [&minus;180&deg;, 180&deg;).
327  * .
328  * With the LONG_NOWRAP bit set, the quantity \e lon2 &minus; \e lon1
329  * indicates how many times the rhumb line wrapped around the ellipsoid.
330  * Because \e lon2 might be outside the normal allowed range for
331  * longitudes, [&minus;540&deg;, 540&deg;), be sure to normalize it with
332  * Math::AngNormalize2 before using it in other GeographicLib calls.
333  **********************************************************************/
334  void GenDirect(real lat1, real lon1, real azi12, real s12, unsigned outmask,
335  real& lat2, real& lon2, real& S12) const;
336 
337  /**
338  * Solve the inverse rhumb problem returning also the area.
339  *
340  * @param[in] lat1 latitude of point 1 (degrees).
341  * @param[in] lon1 longitude of point 1 (degrees).
342  * @param[in] lat2 latitude of point 2 (degrees).
343  * @param[in] lon2 longitude of point 2 (degrees).
344  * @param[out] s12 rhumb distance between point 1 and point 2 (meters).
345  * @param[out] azi12 azimuth of the rhumb line (degrees).
346  * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
347  *
348  * The shortest rhumb line is found. If the end points are on opposite
349  * meridians, there are two shortest rhumb lines and the east-going one is
350  * chosen. \e lat1 and \e lat2 should be in the range [&minus;90&deg;,
351  * 90&deg;]; \e lon1 and \e lon2 should be in the range [&minus;540&deg;,
352  * 540&deg;). The value of \e azi12 returned is in the range
353  * [&minus;180&deg;, 180&deg;).
354  *
355  * If either point is a pole, the cosine of its latitude is taken to be
356  * 1/&epsilon;<sup>2</sup> (where &epsilon; is 2<sup>-52</sup>). This
357  * position, which is extremely close to the actual pole, allows the
358  * calculation to be carried out in finite terms.
359  **********************************************************************/
360  void Inverse(real lat1, real lon1, real lat2, real lon2,
361  real& s12, real& azi12, real& S12) const {
362  GenInverse(lat1, lon1, lat2, lon2,
363  DISTANCE | AZIMUTH | AREA, s12, azi12, S12);
364  }
365 
366  /**
367  * Solve the inverse rhumb problem without the area.
368  **********************************************************************/
369  void Inverse(real lat1, real lon1, real lat2, real lon2,
370  real& s12, real& azi12) const {
371  real t;
372  GenInverse(lat1, lon1, lat2, lon2, DISTANCE | AZIMUTH, s12, azi12, t);
373  }
374 
375  /**
376  * The general inverse rhumb problem. Rhumb::Inverse is defined in terms
377  * of this function.
378  *
379  * @param[in] lat1 latitude of point 1 (degrees).
380  * @param[in] lon1 longitude of point 1 (degrees).
381  * @param[in] lat2 latitude of point 2 (degrees).
382  * @param[in] lon2 longitude of point 2 (degrees).
383  * @param[in] outmask a bitor'ed combination of Rhumb::mask values
384  * specifying which of the following parameters should be set.
385  * @param[out] s12 rhumb distance between point 1 and point 2 (meters).
386  * @param[out] azi12 azimuth of the rhumb line (degrees).
387  * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
388  *
389  * The Rhumb::mask values possible for \e outmask are
390  * - \e outmask |= Rhumb::DISTANCE for the latitude \e s12;
391  * - \e outmask |= Rhumb::AZIMUTH for the latitude \e azi12;
392  * - \e outmask |= Rhumb::AREA for the area \e S12;
393  * - \e outmask |= Rhumb::ALL for all of the above;
394  **********************************************************************/
395  void GenInverse(real lat1, real lon1, real lat2, real lon2,
396  unsigned outmask,
397  real& s12, real& azi12, real& S12) const;
398 
399  /**
400  * Set up to compute several points on a single rhumb line.
401  *
402  * @param[in] lat1 latitude of point 1 (degrees).
403  * @param[in] lon1 longitude of point 1 (degrees).
404  * @param[in] azi12 azimuth of the rhumb line (degrees).
405  * @return a RhumbLine object.
406  *
407  * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 and \e
408  * azi12 should be in the range [&minus;540&deg;, 540&deg;).
409  *
410  * If point 1 is a pole, the cosine of its latitude is taken to be
411  * 1/&epsilon;<sup>2</sup> (where &epsilon; is 2<sup>-52</sup>). This
412  * position, which is extremely close to the actual pole, allows the
413  * calculation to be carried out in finite terms.
414  **********************************************************************/
415  RhumbLine Line(real lat1, real lon1, real azi12) const;
416 
417  /** \name Inspector functions.
418  **********************************************************************/
419  ///@{
420 
421  /**
422  * @return \e a the equatorial radius of the ellipsoid (meters). This is
423  * the value used in the constructor.
424  **********************************************************************/
425  Math::real MajorRadius() const { return _ell.MajorRadius(); }
426 
427  /**
428  * @return \e f the flattening of the ellipsoid. This is the
429  * value used in the constructor.
430  **********************************************************************/
431  Math::real Flattening() const { return _ell.Flattening(); }
432 
433  Math::real EllipsoidArea() const { return _ell.Area(); }
434 
435  /**
436  * A global instantiation of Rhumb with the parameters for the WGS84
437  * ellipsoid.
438  **********************************************************************/
439  static const Rhumb& WGS84();
440  };
441 
442  /**
443  * \brief Find a sequence of points on a single rhumb line.
444  *
445  * RhumbLine facilitates the determination of a series of points on a single
446  * rhumb line. The starting point (\e lat1, \e lon1) and the azimuth \e
447  * azi12 are specified in the call to Rhumb::Line which returns a RhumbLine
448  * object. RhumbLine.Position returns the location of point 2 (and,
449  * optionally, the corresponding area, \e S12) a distance \e s12 along the
450  * rhumb line.
451  *
452  * There is no public constructor for this class. (Use Rhumb::Line to create
453  * an instance.) The Rhumb object used to create a RhumbLine must stay in
454  * scope as long as the RhumbLine.
455  *
456  * Example of use:
457  * \include example-RhumbLine.cpp
458  **********************************************************************/
459 
461  private:
462  typedef Math::real real;
463  friend class Rhumb;
464  const Rhumb& _rh;
465  bool _exact;
466  real _lat1, _lon1, _azi12, _salp, _calp, _mu1, _psi1, _r1;
467  RhumbLine& operator=(const RhumbLine&); // copy assignment not allowed
468  RhumbLine(const Rhumb& rh, real lat1, real lon1, real azi12,
469  bool exact);
470  public:
471 
472  enum mask {
473  /**
474  * No output.
475  * @hideinitializer
476  **********************************************************************/
477  NONE = Rhumb::NONE,
478  /**
479  * Calculate latitude \e lat2.
480  * @hideinitializer
481  **********************************************************************/
482  LATITUDE = Rhumb::LATITUDE,
483  /**
484  * Calculate longitude \e lon2.
485  * @hideinitializer
486  **********************************************************************/
487  LONGITUDE = Rhumb::LONGITUDE,
488  /**
489  * Calculate azimuth \e azi12.
490  * @hideinitializer
491  **********************************************************************/
492  AZIMUTH = Rhumb::AZIMUTH,
493  /**
494  * Calculate distance \e s12.
495  * @hideinitializer
496  **********************************************************************/
497  DISTANCE = Rhumb::DISTANCE,
498  /**
499  * Calculate area \e S12.
500  * @hideinitializer
501  **********************************************************************/
502  AREA = Rhumb::AREA,
503  /**
504  * Do wrap the \e lon2 in the direct calculation.
505  * @hideinitializer
506  **********************************************************************/
507  LONG_NOWRAP = Rhumb::LONG_NOWRAP,
508  /**
509  * Calculate everything. (LONG_NOWRAP is not included in this mask.)
510  * @hideinitializer
511  **********************************************************************/
512  ALL = Rhumb::ALL,
513  };
514 
515  /**
516  * Compute the position of point 2 which is a distance \e s12 (meters) from
517  * point 1. The area is also computed.
518  *
519  * @param[in] s12 distance between point 1 and point 2 (meters); it can be
520  * negative.
521  * @param[out] lat2 latitude of point 2 (degrees).
522  * @param[out] lon2 longitude of point 2 (degrees).
523  * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
524  *
525  * The value of \e lon2 returned is in the range [&minus;180&deg;,
526  * 180&deg;).
527  *
528  * If \e s12 is large enough that the rhumb line crosses a pole, the
529  * longitude of point 2 is indeterminate (a NaN is returned for \e lon2 and
530  * \e S12).
531  **********************************************************************/
532  void Position(real s12, real& lat2, real& lon2, real& S12) const {
533  GenPosition(s12, LATITUDE | LONGITUDE | AREA, lat2, lon2, S12);
534  }
535 
536  /**
537  * Compute the position of point 2 which is a distance \e s12 (meters) from
538  * point 1. The area is not computed.
539  **********************************************************************/
540  void Position(real s12, real& lat2, real& lon2) const {
541  real t;
542  GenPosition(s12, LATITUDE | LONGITUDE, lat2, lon2, t);
543  }
544 
545  /**
546  * The general position routine. RhumbLine::Position is defined in term so
547  * this function.
548  *
549  * @param[in] s12 distance between point 1 and point 2 (meters); it can be
550  * negative.
551  * @param[in] outmask a bitor'ed combination of Rhumb::mask values
552  * specifying which of the following parameters should be set.
553  * @param[out] lat2 latitude of point 2 (degrees).
554  * @param[out] lon2 longitude of point 2 (degrees).
555  * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
556  *
557  * The Rhumb::mask values possible for \e outmask are
558  * - \e outmask |= Rhumb::LATITUDE for the latitude \e lat2;
559  * - \e outmask |= Rhumb::LONGITUDE for the latitude \e lon2;
560  * - \e outmask |= Rhumb::AREA for the area \e S12;
561  * - \e outmask |= Rhumb::ALL for all of the above;
562  * - \e outmask |= Rhumb::LONG_NOWRAP stops the returned value of \e
563  * lon2 being wrapped into the range [&minus;180&deg;, 180&deg;).
564  * .
565  * With the LONG_NOWRAP bit set, the quantity \e lon2 &minus; \e lon1
566  * indicates how many times the rhumb line wrapped around the ellipsoid.
567  * Because \e lon2 might be outside the normal allowed range for
568  * longitudes, [&minus;540&deg;, 540&deg;), be sure to normalize it with
569  * Math::AngNormalize2 before using it in other GeographicLib calls.
570  *
571  * If \e s12 is large enough that the rhumb line crosses a pole, the
572  * longitude of point 2 is indeterminate (a NaN is returned for \e lon2 and
573  * \e S12).
574  **********************************************************************/
575  void GenPosition(real s12, unsigned outmask,
576  real& lat2, real& lon2, real& S12) const;
577 
578  /** \name Inspector functions
579  **********************************************************************/
580  ///@{
581 
582  /**
583  * @return \e lat1 the latitude of point 1 (degrees).
584  **********************************************************************/
585  Math::real Latitude() const { return _lat1; }
586 
587  /**
588  * @return \e lon1 the longitude of point 1 (degrees).
589  **********************************************************************/
590  Math::real Longitude() const { return _lon1; }
591 
592  /**
593  * @return \e azi12 the azimuth of the rhumb line (degrees).
594  **********************************************************************/
595  Math::real Azimuth() const { return _azi12; }
596 
597  /**
598  * @return \e a the equatorial radius of the ellipsoid (meters). This is
599  * the value inherited from the Rhumb object used in the constructor.
600  **********************************************************************/
601  Math::real MajorRadius() const { return _rh.MajorRadius(); }
602 
603  /**
604  * @return \e f the flattening of the ellipsoid. This is the value
605  * inherited from the Rhumb object used in the constructor.
606  **********************************************************************/
607  Math::real Flattening() const { return _rh.Flattening(); }
608  };
609 
610 } // namespace GeographicLib
611 
612 #endif // GEOGRAPHICLIB_RHUMB_HPP
void Inverse(real lat1, real lon1, real lat2, real lon2, real &s12, real &azi12, real &S12) const
Definition: Rhumb.hpp:360
static T pi()
Definition: Math.hpp:214
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:71
GeographicLib::Math::real real
Definition: GeodSolve.cpp:32
void Position(real s12, real &lat2, real &lon2) const
Definition: Rhumb.hpp:540
#define GEOGRAPHICLIB_RHUMBAREA_ORDER
Definition: Rhumb.hpp:21
static T atanh(T x)
Definition: Math.hpp:340
Math::real Latitude() const
Definition: Rhumb.hpp:585
#define GEOGRAPHICLIB_VOLATILE
Definition: Math.hpp:84
Math::real MajorRadius() const
Definition: Rhumb.hpp:425
static T asinh(T x)
Definition: Math.hpp:323
Math::real EllipsoidArea() const
Definition: Rhumb.hpp:433
static T hypot(T x, T y)
Definition: Math.hpp:255
static T sq(T x)
Definition: Math.hpp:244
Math::real MajorRadius() const
Definition: Ellipsoid.hpp:91
Math::real Azimuth() const
Definition: Rhumb.hpp:595
Math::real Longitude() const
Definition: Rhumb.hpp:590
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
#define GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER
Header for GeographicLib::Ellipsoid class.
Math::real Flattening() const
Definition: Rhumb.hpp:431
Properties of an ellipsoid.
Definition: Ellipsoid.hpp:39
Math::real MajorRadius() const
Definition: Rhumb.hpp:601
Math::real Area() const
Definition: Ellipsoid.cpp:40
Header for GeographicLib::Constants class.
Solve of the direct and inverse rhumb problems.
Definition: Rhumb.hpp:66
void Inverse(real lat1, real lon1, real lat2, real lon2, real &s12, real &azi12) const
Definition: Rhumb.hpp:369
Find a sequence of points on a single rhumb line.
Definition: Rhumb.hpp:460
Math::real Flattening() const
Definition: Rhumb.hpp:607
void Direct(real lat1, real lon1, real azi12, real s12, real &lat2, real &lon2) const
Definition: Rhumb.hpp:299
Math::real Flattening() const
Definition: Ellipsoid.hpp:131
void Direct(real lat1, real lon1, real azi12, real s12, real &lat2, real &lon2, real &S12) const
Definition: Rhumb.hpp:290
void Position(real s12, real &lat2, real &lon2, real &S12) const
Definition: Rhumb.hpp:532