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