GeographicLib  2.6
GeodesicLine.hpp
Go to the documentation of this file.
1 /**
2  * \file GeodesicLine.hpp
3  * \brief Header for GeographicLib::GeodesicLine class
4  *
5  * Copyright (c) Charles Karney (2009-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_GEODESICLINE_HPP)
11 #define GEOGRAPHICLIB_GEODESICLINE_HPP 1
12 
16 
17 namespace GeographicLib {
18 
19  /**
20  * \brief A geodesic line
21  *
22  * GeodesicLine facilitates the determination of a series of points on a
23  * single geodesic. The starting point (\e lat1, \e lon1) and the azimuth \e
24  * azi1 are specified in the constructor; alternatively, the Geodesic::Line
25  * method can be used to create a GeodesicLine. GeodesicLine.Position
26  * returns the location of point 2 a distance \e s12 along the geodesic. In
27  * addition, GeodesicLine.ArcPosition gives the position of point 2 an arc
28  * length \e a12 along the geodesic.
29  *
30  * You can register the position of a reference point 3 a distance (arc
31  * length), \e s13 (\e a13) along the geodesic with the
32  * GeodesicLine.SetDistance (GeodesicLine.SetArc) functions. Points a
33  * fractional distance along the line can be found by providing, for example,
34  * 0.5 * Distance() as an argument to GeodesicLine.Position. The
35  * Geodesic::InverseLine or Geodesic::DirectLine methods return GeodesicLine
36  * objects with point 3 set to the point 2 of the corresponding geodesic
37  * problem. GeodesicLine objects created with the public constructor or with
38  * Geodesic::Line have \e s13 and \e a13 set to NaNs.
39  *
40  * The default copy constructor and assignment operators work with this
41  * class. Similarly, a vector can be used to hold GeodesicLine objects.
42  *
43  * The calculations are accurate to better than 15 nm (15 nanometers). See
44  * Sec. 9 of
45  * <a href="https://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for
46  * details. With \e exact = false (the default) in the constructor for the
47  * Geodesic object, the algorithms used by this class are based on series
48  * expansions using the flattening \e f as a small parameter. These are only
49  * accurate for |<i>f</i>| &lt; 0.02; however reasonably accurate results
50  * will be obtained for |<i>f</i>| &lt; 0.2. For very eccentric ellipsoids,
51  * set \e exact = true in the constructor for the Geodesic object; this will
52  * delegate the calculations to GeodesicLineExact.
53  *
54  * The algorithms are described in
55  * - C. F. F. Karney,
56  * <a href="https://doi.org/10.1007/s00190-012-0578-z">
57  * Algorithms for geodesics</a>,
58  * J. Geodesy <b>87</b>, 43--55 (2013);
59  * DOI: <a href="https://doi.org/10.1007/s00190-012-0578-z">
60  * 10.1007/s00190-012-0578-z</a>;
61  * addenda:
62  * <a href="https://geographiclib.sourceforge.io/geod-addenda.html">
63  * geod-addenda.html</a>.
64  * .
65  * For more information on geodesics see \ref geodesic.
66  *
67  * Example of use:
68  * \include example-GeodesicLine.cpp
69  *
70  * <a href="GeodSolve.1.html">GeodSolve</a> is a command-line utility
71  * providing access to the functionality of Geodesic and GeodesicLine.
72  **********************************************************************/
73 
75  private:
76  typedef Math::real real;
77  friend class Geodesic;
78  static const int nC1_ = Geodesic::nC1_;
79  static const int nC1p_ = Geodesic::nC1p_;
80  static const int nC2_ = Geodesic::nC2_;
81  static const int nC3_ = Geodesic::nC3_;
82  static const int nC4_ = Geodesic::nC4_;
83 
84  real tiny_;
85  real _lat1, _lon1, _azi1;
86  real _a, _f;
87  bool _exact;
88  real _b, _c2, _f1, _salp0, _calp0, _k2,
89  _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, _somg1, _comg1,
90  _aA1m1, _aA2m1, _aA3c, _bB11, _bB21, _bB31, _aA4, _bB41;
91  real _a13, _s13;
92  // index zero elements of _cC1a, _cC1pa, _cC2a, _cC3a are unused
93  real _cC1a[nC1_ + 1], _cC1pa[nC1p_ + 1], _cC2a[nC2_ + 1], _cC3a[nC3_],
94  _cC4a[nC4_]; // all the elements of _cC4a are used
95  unsigned _caps;
96  GeodesicLineExact _lineexact;
97 
98  void LineInit(const Geodesic& g,
99  real lat1, real lon1,
100  real azi1, real salp1, real calp1,
101  unsigned caps);
102  GeodesicLine(const Geodesic& g,
103  real lat1, real lon1,
104  real azi1, real salp1, real calp1,
105  unsigned caps, bool arcmode, real s13_a13);
106 
107  static constexpr unsigned CAP_NONE = Geodesic::CAP_NONE;
108  static constexpr unsigned CAP_C1 = Geodesic::CAP_C1;
109  static constexpr unsigned CAP_C1p = Geodesic::CAP_C1p;
110  static constexpr unsigned CAP_C2 = Geodesic::CAP_C2;
111  static constexpr unsigned CAP_C3 = Geodesic::CAP_C3;
112  static constexpr unsigned CAP_C4 = Geodesic::CAP_C4;
113  static constexpr unsigned CAP_ALL = Geodesic::CAP_ALL;
114  static constexpr unsigned CAP_MASK = Geodesic::CAP_MASK;
115  static constexpr unsigned OUT_ALL = Geodesic::OUT_ALL;
116  static constexpr unsigned OUT_MASK = Geodesic::OUT_MASK;
117 
118  public:
119 
120  /**
121  * Bit masks for what calculations to do. They signify to the
122  * GeodesicLine::GeodesicLine constructor and to Geodesic::Line what
123  * capabilities should be included in the GeodesicLine object. This is
124  * merely a duplication of Geodesic::mask.
125  **********************************************************************/
126  enum mask {
127  /**
128  * No capabilities, no output.
129  * @hideinitializer
130  **********************************************************************/
132  /**
133  * Calculate latitude \e lat2. (It's not necessary to include this as a
134  * capability to GeodesicLine because this is included by default.)
135  * @hideinitializer
136  **********************************************************************/
137  LATITUDE = Geodesic::LATITUDE,
138  /**
139  * Calculate longitude \e lon2.
140  * @hideinitializer
141  **********************************************************************/
142  LONGITUDE = Geodesic::LONGITUDE,
143  /**
144  * Calculate azimuths \e azi1 and \e azi2. (It's not necessary to
145  * include this as a capability to GeodesicLine because this is included
146  * by default.)
147  * @hideinitializer
148  **********************************************************************/
149  AZIMUTH = Geodesic::AZIMUTH,
150  /**
151  * Calculate distance \e s12.
152  * @hideinitializer
153  **********************************************************************/
154  DISTANCE = Geodesic::DISTANCE,
155  /**
156  * A combination of the common capabilities: GeodesicLine::LATITUDE,
157  * GeodesicLine::LONGITUDE, GeodesicLine::AZIMUTH, GeodesicLine::DISTANCE.
158  * @hideinitializer
159  **********************************************************************/
160  STANDARD = Geodesic::STANDARD,
161  /**
162  * Allow distance \e s12 to be used as input in the direct geodesic
163  * problem.
164  * @hideinitializer
165  **********************************************************************/
166  DISTANCE_IN = Geodesic::DISTANCE_IN,
167  /**
168  * Calculate reduced length \e m12.
169  * @hideinitializer
170  **********************************************************************/
171  REDUCEDLENGTH = Geodesic::REDUCEDLENGTH,
172  /**
173  * Calculate geodesic scales \e M12 and \e M21.
174  * @hideinitializer
175  **********************************************************************/
176  GEODESICSCALE = Geodesic::GEODESICSCALE,
177  /**
178  * Calculate area \e S12.
179  * @hideinitializer
180  **********************************************************************/
182  /**
183  * Unroll \e lon2 in the direct calculation.
184  * @hideinitializer
185  **********************************************************************/
186  LONG_UNROLL = Geodesic::LONG_UNROLL,
187  /**
188  * All capabilities, calculate everything. (GeodesicLine::LONG_UNROLL is
189  * not included in this mask.)
190  * @hideinitializer
191  **********************************************************************/
193  };
194 
195  /**
196  * Typedef for the base class implementing geodesics.
197  **********************************************************************/
199 
200  /** \name Constructors
201  **********************************************************************/
202  ///@{
203 
204  /**
205  * Constructor for a geodesic line staring at latitude \e lat1, longitude
206  * \e lon1, and azimuth \e azi1 (all in degrees).
207  *
208  * @param[in] g A Geodesic object used to compute the necessary information
209  * about the GeodesicLine.
210  * @param[in] lat1 latitude of point 1 (degrees).
211  * @param[in] lon1 longitude of point 1 (degrees).
212  * @param[in] azi1 azimuth at point 1 (degrees).
213  * @param[in] caps bitor'ed combination of GeodesicLine::mask values
214  * specifying the capabilities the GeodesicLine object should possess,
215  * i.e., which quantities can be returned in calls to
216  * GeodesicLine::Position.
217  *
218  * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
219  *
220  * The GeodesicLine::mask values are
221  * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this is
222  * added automatically;
223  * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2;
224  * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is
225  * added automatically;
226  * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12;
227  * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m12;
228  * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12
229  * and \e M21;
230  * - \e caps |= GeodesicLine::AREA for the area \e S12;
231  * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the
232  * geodesic to be given in terms of \e s12; without this capability the
233  * length can only be specified in terms of arc length;
234  * - \e caps |= GeodesicLine::ALL for all of the above.
235  * .
236  * The default value of \e caps is GeodesicLine::ALL.
237  *
238  * If the point is at a pole, the azimuth is defined by keeping \e lon1
239  * fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and taking
240  * the limit &epsilon; &rarr; 0+.
241  **********************************************************************/
242  GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1,
243  unsigned caps = ALL);
244 
245  /**
246  * A default constructor. If GeodesicLine::Position is called on the
247  * resulting object, it returns immediately (without doing any
248  * calculations). The object can be set with a call to Geodesic::Line.
249  * Use Init() to test whether object is still in this uninitialized state.
250  **********************************************************************/
251  GeodesicLine() : _caps(0U) {}
252  ///@}
253 
254  /** \name Position in terms of distance
255  **********************************************************************/
256  ///@{
257 
258  /**
259  * Compute the position of point 2 which is a distance \e s12 (meters) from
260  * point 1.
261  *
262  * @param[in] s12 distance from point 1 to point 2 (meters); it can be
263  * negative.
264  * @param[out] lat2 latitude of point 2 (degrees).
265  * @param[out] lon2 longitude of point 2 (degrees); requires that the
266  * GeodesicLine object was constructed with \e caps |=
267  * GeodesicLine::LONGITUDE.
268  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
269  * @param[out] m12 reduced length of geodesic (meters); requires that the
270  * GeodesicLine object was constructed with \e caps |=
271  * GeodesicLine::REDUCEDLENGTH.
272  * @param[out] M12 geodesic scale of point 2 relative to point 1
273  * (dimensionless); requires that the GeodesicLine object was constructed
274  * with \e caps |= GeodesicLine::GEODESICSCALE.
275  * @param[out] M21 geodesic scale of point 1 relative to point 2
276  * (dimensionless); requires that the GeodesicLine object was constructed
277  * with \e caps |= GeodesicLine::GEODESICSCALE.
278  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
279  * that the GeodesicLine object was constructed with \e caps |=
280  * GeodesicLine::AREA.
281  * @return \e a12 arc length from point 1 to point 2 (degrees).
282  *
283  * The values of \e lon2 and \e azi2 returned are in the range
284  * [&minus;180&deg;, 180&deg;].
285  *
286  * The GeodesicLine object \e must have been constructed with \e caps |=
287  * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no
288  * parameters are set. Requesting a value which the GeodesicLine object is
289  * not capable of computing is not an error; the corresponding argument
290  * will not be altered.
291  *
292  * The following functions are overloaded versions of
293  * GeodesicLine::Position which omit some of the output parameters. Note,
294  * however, that the arc length is always computed and returned as the
295  * function value.
296  **********************************************************************/
298  real& lat2, real& lon2, real& azi2,
299  real& m12, real& M12, real& M21,
300  real& S12) const {
301  real t;
302  return GenPosition(false, s12,
303  LATITUDE | LONGITUDE | AZIMUTH |
304  REDUCEDLENGTH | GEODESICSCALE | AREA,
305  lat2, lon2, azi2, t, m12, M12, M21, S12);
306  }
307 
308  /**
309  * See the documentation for GeodesicLine::Position.
310  **********************************************************************/
311  Math::real Position(real s12, real& lat2, real& lon2) const {
312  real t;
313  return GenPosition(false, s12,
314  LATITUDE | LONGITUDE,
315  lat2, lon2, t, t, t, t, t, t);
316  }
317 
318  /**
319  * See the documentation for GeodesicLine::Position.
320  **********************************************************************/
321  Math::real Position(real s12, real& lat2, real& lon2,
322  real& azi2) const {
323  real t;
324  return GenPosition(false, s12,
325  LATITUDE | LONGITUDE | AZIMUTH,
326  lat2, lon2, azi2, t, t, t, t, t);
327  }
328 
329  /**
330  * See the documentation for GeodesicLine::Position.
331  **********************************************************************/
332  Math::real Position(real s12, real& lat2, real& lon2,
333  real& azi2, real& m12) const {
334  real t;
335  return GenPosition(false, s12,
336  LATITUDE | LONGITUDE |
337  AZIMUTH | REDUCEDLENGTH,
338  lat2, lon2, azi2, t, m12, t, t, t);
339  }
340 
341  /**
342  * See the documentation for GeodesicLine::Position.
343  **********************************************************************/
344  Math::real Position(real s12, real& lat2, real& lon2,
345  real& azi2, real& M12, real& M21)
346  const {
347  real t;
348  return GenPosition(false, s12,
349  LATITUDE | LONGITUDE |
350  AZIMUTH | GEODESICSCALE,
351  lat2, lon2, azi2, t, t, M12, M21, t);
352  }
353 
354  /**
355  * See the documentation for GeodesicLine::Position.
356  **********************************************************************/
358  real& lat2, real& lon2, real& azi2,
359  real& m12, real& M12, real& M21)
360  const {
361  real t;
362  return GenPosition(false, s12,
363  LATITUDE | LONGITUDE | AZIMUTH |
364  REDUCEDLENGTH | GEODESICSCALE,
365  lat2, lon2, azi2, t, m12, M12, M21, t);
366  }
367  ///@}
368 
369  /** \name Position in terms of arc length
370  **********************************************************************/
371  ///@{
372 
373  /**
374  * Compute the position of point 2 which is an arc length \e a12 (degrees)
375  * from point 1.
376  *
377  * @param[in] a12 arc length from point 1 to point 2 (degrees); it can
378  * be negative.
379  * @param[out] lat2 latitude of point 2 (degrees).
380  * @param[out] lon2 longitude of point 2 (degrees); requires that the
381  * GeodesicLine object was constructed with \e caps |=
382  * GeodesicLine::LONGITUDE.
383  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
384  * @param[out] s12 distance from point 1 to point 2 (meters); requires
385  * that the GeodesicLine object was constructed with \e caps |=
386  * GeodesicLine::DISTANCE.
387  * @param[out] m12 reduced length of geodesic (meters); requires that the
388  * GeodesicLine object was constructed with \e caps |=
389  * GeodesicLine::REDUCEDLENGTH.
390  * @param[out] M12 geodesic scale of point 2 relative to point 1
391  * (dimensionless); requires that the GeodesicLine object was constructed
392  * with \e caps |= GeodesicLine::GEODESICSCALE.
393  * @param[out] M21 geodesic scale of point 1 relative to point 2
394  * (dimensionless); requires that the GeodesicLine object was constructed
395  * with \e caps |= GeodesicLine::GEODESICSCALE.
396  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
397  * that the GeodesicLine object was constructed with \e caps |=
398  * GeodesicLine::AREA.
399  *
400  * The values of \e lon2 and \e azi2 returned are in the range
401  * [&minus;180&deg;, 180&deg;].
402  *
403  * Requesting a value which the GeodesicLine object is not capable of
404  * computing is not an error; the corresponding argument will not be
405  * altered.
406  *
407  * The following functions are overloaded versions of
408  * GeodesicLine::ArcPosition which omit some of the output parameters.
409  **********************************************************************/
410  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
411  real& s12, real& m12, real& M12, real& M21,
412  real& S12) const {
413  GenPosition(true, a12,
414  LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
415  REDUCEDLENGTH | GEODESICSCALE | AREA,
416  lat2, lon2, azi2, s12, m12, M12, M21, S12);
417  }
418 
419  /**
420  * See the documentation for GeodesicLine::ArcPosition.
421  **********************************************************************/
422  void ArcPosition(real a12, real& lat2, real& lon2)
423  const {
424  real t;
425  GenPosition(true, a12,
426  LATITUDE | LONGITUDE,
427  lat2, lon2, t, t, t, t, t, t);
428  }
429 
430  /**
431  * See the documentation for GeodesicLine::ArcPosition.
432  **********************************************************************/
433  void ArcPosition(real a12,
434  real& lat2, real& lon2, real& azi2)
435  const {
436  real t;
437  GenPosition(true, a12,
438  LATITUDE | LONGITUDE | AZIMUTH,
439  lat2, lon2, azi2, t, t, t, t, t);
440  }
441 
442  /**
443  * See the documentation for GeodesicLine::ArcPosition.
444  **********************************************************************/
445  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
446  real& s12) const {
447  real t;
448  GenPosition(true, a12,
449  LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
450  lat2, lon2, azi2, s12, t, t, t, t);
451  }
452 
453  /**
454  * See the documentation for GeodesicLine::ArcPosition.
455  **********************************************************************/
456  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
457  real& s12, real& m12) const {
458  real t;
459  GenPosition(true, a12,
460  LATITUDE | LONGITUDE | AZIMUTH |
461  DISTANCE | REDUCEDLENGTH,
462  lat2, lon2, azi2, s12, m12, t, t, t);
463  }
464 
465  /**
466  * See the documentation for GeodesicLine::ArcPosition.
467  **********************************************************************/
468  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
469  real& s12, real& M12, real& M21)
470  const {
471  real t;
472  GenPosition(true, a12,
473  LATITUDE | LONGITUDE | AZIMUTH |
474  DISTANCE | GEODESICSCALE,
475  lat2, lon2, azi2, s12, t, M12, M21, t);
476  }
477 
478  /**
479  * See the documentation for GeodesicLine::ArcPosition.
480  **********************************************************************/
481  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
482  real& s12, real& m12, real& M12, real& M21)
483  const {
484  real t;
485  GenPosition(true, a12,
486  LATITUDE | LONGITUDE | AZIMUTH |
487  DISTANCE | REDUCEDLENGTH | GEODESICSCALE,
488  lat2, lon2, azi2, s12, m12, M12, M21, t);
489  }
490  ///@}
491 
492  /** \name The general position function.
493  **********************************************************************/
494  ///@{
495 
496  /**
497  * The general position function. GeodesicLine::Position and
498  * GeodesicLine::ArcPosition are defined in terms of this function.
499  *
500  * @param[in] arcmode boolean flag determining the meaning of the second
501  * parameter; if \e arcmode is false, then the GeodesicLine object must
502  * have been constructed with \e caps |= GeodesicLine::DISTANCE_IN.
503  * @param[in] s12_a12 if \e arcmode is false, this is the distance between
504  * point 1 and point 2 (meters); otherwise it is the arc length between
505  * point 1 and point 2 (degrees); it can be negative.
506  * @param[in] outmask a bitor'ed combination of GeodesicLine::mask values
507  * specifying which of the following parameters should be set.
508  * @param[out] lat2 latitude of point 2 (degrees).
509  * @param[out] lon2 longitude of point 2 (degrees); requires that the
510  * GeodesicLine object was constructed with \e caps |=
511  * GeodesicLine::LONGITUDE.
512  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
513  * @param[out] s12 distance from point 1 to point 2 (meters); requires
514  * that the GeodesicLine object was constructed with \e caps |=
515  * GeodesicLine::DISTANCE.
516  * @param[out] m12 reduced length of geodesic (meters); requires that the
517  * GeodesicLine object was constructed with \e caps |=
518  * GeodesicLine::REDUCEDLENGTH.
519  * @param[out] M12 geodesic scale of point 2 relative to point 1
520  * (dimensionless); requires that the GeodesicLine object was constructed
521  * with \e caps |= GeodesicLine::GEODESICSCALE.
522  * @param[out] M21 geodesic scale of point 1 relative to point 2
523  * (dimensionless); requires that the GeodesicLine object was constructed
524  * with \e caps |= GeodesicLine::GEODESICSCALE.
525  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
526  * that the GeodesicLine object was constructed with \e caps |=
527  * GeodesicLine::AREA.
528  * @return \e a12 arc length from point 1 to point 2 (degrees).
529  *
530  * The GeodesicLine::mask values possible for \e outmask are
531  * - \e outmask |= GeodesicLine::LATITUDE for the latitude \e lat2;
532  * - \e outmask |= GeodesicLine::LONGITUDE for the latitude \e lon2;
533  * - \e outmask |= GeodesicLine::AZIMUTH for the latitude \e azi2;
534  * - \e outmask |= GeodesicLine::DISTANCE for the distance \e s12;
535  * - \e outmask |= GeodesicLine::REDUCEDLENGTH for the reduced length \e
536  * m12;
537  * - \e outmask |= GeodesicLine::GEODESICSCALE for the geodesic scales \e
538  * M12 and \e M21;
539  * - \e outmask |= GeodesicLine::AREA for the area \e S12;
540  * - \e outmask |= GeodesicLine::ALL for all of the above;
541  * - \e outmask |= GeodesicLine::LONG_UNROLL to unroll \e lon2 instead of
542  * reducing it into the range [&minus;180&deg;, 180&deg;].
543  * .
544  * Requesting a value which the GeodesicLine object is not capable of
545  * computing is not an error; the corresponding argument will not be
546  * altered. Note, however, that the arc length is always computed and
547  * returned as the function value.
548  *
549  * With the GeodesicLine::LONG_UNROLL bit set, the quantity \e lon2 &minus;
550  * \e lon1 indicates how many times and in what sense the geodesic
551  * encircles the ellipsoid.
552  **********************************************************************/
553  Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask,
554  real& lat2, real& lon2, real& azi2,
555  real& s12, real& m12, real& M12, real& M21,
556  real& S12) const;
557  ///@}
558 
559  /** \name Setting point 3
560  **********************************************************************/
561  ///@{
562 
563  /**
564  * Specify position of point 3 in terms of distance.
565  *
566  * @param[in] s13 the distance from point 1 to point 3 (meters); it
567  * can be negative.
568  *
569  * This is only useful if the GeodesicLine object has been constructed
570  * with \e caps |= GeodesicLine::DISTANCE_IN.
571  **********************************************************************/
572  void SetDistance(real s13);
573 
574  /**
575  * Specify position of point 3 in terms of arc length.
576  *
577  * @param[in] a13 the arc length from point 1 to point 3 (degrees); it
578  * can be negative.
579  *
580  * The distance \e s13 is only set if the GeodesicLine object has been
581  * constructed with \e caps |= GeodesicLine::DISTANCE.
582  **********************************************************************/
583  void SetArc(real a13);
584 
585  /**
586  * Specify position of point 3 in terms of either distance or arc length.
587  *
588  * @param[in] arcmode boolean flag determining the meaning of the second
589  * parameter; if \e arcmode is false, then the GeodesicLine object must
590  * have been constructed with \e caps |= GeodesicLine::DISTANCE_IN.
591  * @param[in] s13_a13 if \e arcmode is false, this is the distance from
592  * point 1 to point 3 (meters); otherwise it is the arc length from
593  * point 1 to point 3 (degrees); it can be negative.
594  **********************************************************************/
595  void GenSetDistance(bool arcmode, real s13_a13);
596  ///@}
597 
598  /** \name Inspector functions
599  **********************************************************************/
600  ///@{
601 
602  /**
603  * @return true if the object has been initialized.
604  **********************************************************************/
605  bool Init() const { return _caps != 0U; }
606 
607  /**
608  * @return \e lat1 the latitude of point 1 (degrees).
609  **********************************************************************/
611  { return Init() ? _lat1 : Math::NaN(); }
612 
613  /**
614  * @return \e lon1 the longitude of point 1 (degrees).
615  **********************************************************************/
617  { return Init() ? _lon1 : Math::NaN(); }
618 
619  /**
620  * @return \e azi1 the azimuth (degrees) of the geodesic line at point 1.
621  **********************************************************************/
623  { return Init() ? _azi1 : Math::NaN(); }
624 
625  /**
626  * The sine and cosine of \e azi1.
627  *
628  * @param[out] sazi1 the sine of \e azi1.
629  * @param[out] cazi1 the cosine of \e azi1.
630  **********************************************************************/
631  void Azimuth(real& sazi1, real& cazi1) const
632  { if (Init()) { sazi1 = _salp1; cazi1 = _calp1; } }
633 
634  /**
635  * @return \e azi0 the azimuth (degrees) of the geodesic line as it crosses
636  * the equator in a northward direction.
637  *
638  * The result lies in [&minus;90&deg;, 90&deg;].
639  **********************************************************************/
641  { return Init() ? Math::atan2d(_salp0, _calp0) : Math::NaN(); }
642 
643  /**
644  * The sine and cosine of \e azi0.
645  *
646  * @param[out] sazi0 the sine of \e azi0.
647  * @param[out] cazi0 the cosine of \e azi0.
648  **********************************************************************/
649  void EquatorialAzimuth(real& sazi0, real& cazi0) const
650  { if (Init()) { sazi0 = _salp0; cazi0 = _calp0; } }
651 
652  /**
653  * @return \e a1 the arc length (degrees) between the northward equatorial
654  * crossing and point 1.
655  *
656  * The result lies in [&minus;180&deg;, 180&deg;].
657  **********************************************************************/
659  return Init() ? Math::atan2d(_ssig1, _csig1) : Math::NaN();
660  }
661 
662  /**
663  * @return \e a the equatorial radius of the ellipsoid (meters). This is
664  * the value inherited from the Geodesic object used in the constructor.
665  **********************************************************************/
667  { return Init() ? _a : Math::NaN(); }
668 
669  /**
670  * @return \e f the flattening of the ellipsoid. This is the value
671  * inherited from the Geodesic object used in the constructor.
672  **********************************************************************/
674  { return Init() ? _f : Math::NaN(); }
675 
676  /**
677  * @return \e exact whether the exact formulation is used. This is the
678  * value returned by the Geodesic object used in the constructor.
679  **********************************************************************/
680  bool Exact() const { return _exact; }
681 
682  /**
683  * @return \e caps the computational capabilities that this object was
684  * constructed with. LATITUDE and AZIMUTH are always included.
685  **********************************************************************/
686  unsigned Capabilities() const { return _caps; }
687 
688  /**
689  * Test what capabilities are available.
690  *
691  * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
692  * @return true if the GeodesicLine object has all these capabilities.
693  **********************************************************************/
694  bool Capabilities(unsigned testcaps) const {
695  testcaps &= OUT_ALL;
696  return (_caps & testcaps) == testcaps;
697  }
698 
699  /**
700  * The distance or arc length to point 3.
701  *
702  * @param[in] arcmode boolean flag determining the meaning of returned
703  * value.
704  * @return \e s13 if \e arcmode is false; \e a13 if \e arcmode is true.
705  **********************************************************************/
706  Math::real GenDistance(bool arcmode) const
707  { return Init() ? (arcmode ? _a13 : _s13) : Math::NaN(); }
708 
709  /**
710  * @return \e s13, the distance to point 3 (meters).
711  **********************************************************************/
712  Math::real Distance() const { return GenDistance(false); }
713 
714  /**
715  * @return \e a13, the arc length to point 3 (degrees).
716  **********************************************************************/
717  Math::real Arc() const { return GenDistance(true); }
718  ///@}
719 
720  };
721 
722 } // namespace GeographicLib
723 
724 #endif // GEOGRAPHICLIB_GEODESICLINE_HPP
Math::real Position(real s12, real &lat2, real &lon2) const
void ArcPosition(real a12, real &lat2, real &lon2, real &azi2) const
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:59
void EquatorialAzimuth(real &sazi0, real &cazi0) const
Math::real Flattening() const
void ArcPosition(real a12, real &lat2, real &lon2, real &azi2, real &s12, real &m12, real &M12, real &M21) const
void Azimuth(real &sazi1, real &cazi1) const
Math::real Position(real s12, real &lat2, real &lon2, real &azi2, real &m12, real &M12, real &M21, real &S12) const
Math::real GenDistance(bool arcmode) const
Math::real EquatorialRadius() const
void ArcPosition(real a12, real &lat2, real &lon2, real &azi2, real &s12) const
Math::real EquatorialArc() const
Math::real Position(real s12, real &lat2, real &lon2, real &azi2, real &m12, real &M12, real &M21) const
unsigned Capabilities() const
Math::real Azimuth() const
static T atan2d(T y, T x)
Definition: Math.cpp:212
Math::real Distance() const
Header for GeographicLib::Geodesic class.
Math::real EquatorialAzimuth() const
void ArcPosition(real a12, real &lat2, real &lon2) const
Header for GeographicLib::GeodesicLineExact class.
bool Capabilities(unsigned testcaps) const
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
static T NaN()
Definition: Math.cpp:301
GeographicLib::Math::real real
Definition: Geod3Solve.cpp:25
Math::real Position(real s12, real &lat2, real &lon2, real &azi2, real &m12) const
Math::real Latitude() const
Header for GeographicLib::Constants class.
void ArcPosition(real a12, real &lat2, real &lon2, real &azi2, real &s12, real &m12, real &M12, real &M21, real &S12) const
void ArcPosition(real a12, real &lat2, real &lon2, real &azi2, real &s12, real &M12, real &M21) const
void ArcPosition(real a12, real &lat2, real &lon2, real &azi2, real &s12, real &m12) const
Math::real Position(real s12, real &lat2, real &lon2, real &azi2) const
Math::real Position(real s12, real &lat2, real &lon2, real &azi2, real &M12, real &M21) const
Geodesic calculations
Definition: Geodesic.hpp:175
Math::real Longitude() const