GeographicLib  1.21
GeodesicLine.hpp
Go to the documentation of this file.
00001 /**
00002  * \file GeodesicLine.hpp
00003  * \brief Header for GeographicLib::GeodesicLine class
00004  *
00005  * Copyright (c) Charles Karney (2009-2011) <charles@karney.com> and licensed
00006  * under the MIT/X11 License.  For more information, see
00007  * http://geographiclib.sourceforge.net/
00008  **********************************************************************/
00009 
00010 #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP)
00011 #define GEOGRAPHICLIB_GEODESICLINE_HPP \
00012   "$Id: 4bbc611bc3837d78456bc227e17bea39cb443745 $"
00013 
00014 #include <GeographicLib/Constants.hpp>
00015 #include <GeographicLib/Geodesic.hpp>
00016 
00017 namespace GeographicLib {
00018 
00019   /**
00020    * \brief A geodesic line.
00021    *
00022    * GeodesicLine facilitates the determination of a series of points on a
00023    * single geodesic.  The starting point (\e lat1, \e lon1) and the azimuth \e
00024    * azi1 are specified in the constructor.  GeodesicLine.Position returns the
00025    * location of point 2 a distance \e s12 along the geodesic.  Alternatively
00026    * GeodesicLine.ArcPosition gives the position of point 2 an arc length \e
00027    * a12 along the geodesic.
00028    *
00029    * The default copy constructor and assignment operators work with this
00030    * class.  Similarly, a vector can be used to hold GeodesicLine objects.
00031    *
00032    * The calculations are accurate to better than 15 nm (15 nanometers).  See
00033    * Sec. 9 of
00034    * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for
00035    * details.
00036    *
00037    * The algorithms are described in
00038    * - C. F. F. Karney,
00039    *   <a href="http://arxiv.org/abs/1102.1215v1">Geodesics
00040    *   on an ellipsoid of revolution</a>,
00041    *   Feb. 2011;
00042    *   preprint
00043    *   <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a>.
00044    * - C. F. F. Karney,
00045    *   <a href="http://arxiv.org/abs/1109.4448">Algorithms for geodesics</a>,
00046    *   Sept. 2011;
00047    *   preprint
00048    *   <a href="http://arxiv.org/abs/1109.4448">arxiv:1109.4448</a>.
00049    * .
00050    * For more information on geodesics see \ref geodesic.
00051    *
00052    * Example of use:
00053    * \include example-GeodesicLine.cpp
00054    *
00055    * <a href="Geod.1.html">Geod</a> is a command-line utility providing access
00056    * to the functionality of Geodesic and GeodesicLine.
00057    **********************************************************************/
00058 
00059   class GEOGRAPHIC_EXPORT GeodesicLine {
00060   private:
00061     typedef Math::real real;
00062     friend class Geodesic;
00063     static const int nC1_ = Geodesic::nC1_;
00064     static const int nC1p_ = Geodesic::nC1p_;
00065     static const int nC2_ = Geodesic::nC2_;
00066     static const int nC3_ = Geodesic::nC3_;
00067     static const int nC4_ = Geodesic::nC4_;
00068 
00069     real _lat1, _lon1, _azi1;
00070     real _a, _f, _b, _c2, _f1, _salp0, _calp0, _k2,
00071       _salp1, _calp1, _ssig1, _csig1, _stau1, _ctau1, _somg1, _comg1,
00072       _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41;
00073     // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused
00074     real _C1a[nC1_ + 1], _C1pa[nC1p_ + 1], _C2a[nC2_ + 1], _C3a[nC3_],
00075       _C4a[nC4_];    // all the elements of _C4a are used
00076     unsigned _caps;
00077 
00078     enum captype {
00079       CAP_NONE = Geodesic::CAP_NONE,
00080       CAP_C1   = Geodesic::CAP_C1,
00081       CAP_C1p  = Geodesic::CAP_C1p,
00082       CAP_C2   = Geodesic::CAP_C2,
00083       CAP_C3   = Geodesic::CAP_C3,
00084       CAP_C4   = Geodesic::CAP_C4,
00085       CAP_ALL  = Geodesic::CAP_ALL,
00086       OUT_ALL  = Geodesic::OUT_ALL,
00087     };
00088   public:
00089 
00090     /**
00091      * Bit masks for what calculations to do.  They signify to the
00092      * GeodesicLine::GeodesicLine constructor and to Geodesic::Line what
00093      * capabilities should be included in the GeodesicLine object.  This is
00094      * merely a duplication of Geodesic::mask.
00095      **********************************************************************/
00096     enum mask {
00097       /**
00098        * No capabilities, no output.
00099        * @hideinitializer
00100        **********************************************************************/
00101       NONE          = Geodesic::NONE,
00102       /**
00103        * Calculate latitude \e lat2.  (It's not necessary to include this as a
00104        * capability to GeodesicLine because this is included by default.)
00105        * @hideinitializer
00106        **********************************************************************/
00107       LATITUDE      = Geodesic::LATITUDE,
00108       /**
00109        * Calculate longitude \e lon2.
00110        * @hideinitializer
00111        **********************************************************************/
00112       LONGITUDE     = Geodesic::LONGITUDE,
00113       /**
00114        * Calculate azimuths \e azi1 and \e azi2.  (It's not necessary to
00115        * include this as a capability to GeodesicLine because this is included
00116        * by default.)
00117        * @hideinitializer
00118        **********************************************************************/
00119       AZIMUTH       = Geodesic::AZIMUTH,
00120       /**
00121        * Calculate distance \e s12.
00122        * @hideinitializer
00123        **********************************************************************/
00124       DISTANCE      = Geodesic::DISTANCE,
00125       /**
00126        * Allow distance \e s12 to be used as input in the direct geodesic
00127        * problem.
00128        * @hideinitializer
00129        **********************************************************************/
00130       DISTANCE_IN   = Geodesic::DISTANCE_IN,
00131       /**
00132        * Calculate reduced length \e m12.
00133        * @hideinitializer
00134        **********************************************************************/
00135       REDUCEDLENGTH = Geodesic::REDUCEDLENGTH,
00136       /**
00137        * Calculate geodesic scales \e M12 and \e M21.
00138        * @hideinitializer
00139        **********************************************************************/
00140       GEODESICSCALE = Geodesic::GEODESICSCALE,
00141       /**
00142        * Calculate area \e S12.
00143        * @hideinitializer
00144        **********************************************************************/
00145       AREA          = Geodesic::AREA,
00146       /**
00147        * All capabilities.  Calculate everything.
00148        * @hideinitializer
00149        **********************************************************************/
00150       ALL           = Geodesic::ALL,
00151     };
00152 
00153     /** \name Constructors
00154      **********************************************************************/
00155     ///@{
00156 
00157     /**
00158      * Constructor for a geodesic line staring at latitude \e lat1, longitude
00159      * \e lon1, and azimuth \e azi1 (all in degrees).
00160      *
00161      * @param[in] g A Geodesic object used to compute the necessary information
00162      *   about the GeodesicLine.
00163      *
00164      * @param[in] lat1 latitude of point 1 (degrees).
00165      * @param[in] lon1 longitude of point 1 (degrees).
00166      * @param[in] azi1 azimuth at point 1 (degrees).
00167      * @param[in] caps bitor'ed combination of GeodesicLine::mask values
00168      *   specifying the capabilities the GeodesicLine object should possess,
00169      *   i.e., which quantities can be returned in calls to
00170      *   GeodesicLib::Position.
00171      *
00172      * \e lat1 should be in the range [-90, 90]; \e lon1 and \e azi1 should be
00173      * in the range [-180, 360].
00174      *
00175      * The GeodesicLine::mask values are
00176      * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this is
00177      *   added automatically
00178      * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2
00179      * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is
00180      *   added automatically
00181      * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12
00182      * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m12
00183      * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12
00184      *   and \e M21
00185      * - \e caps |= GeodesicLine::AREA for the area \e S12
00186      * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the
00187      *   geodesic to be given in terms of \e s12; without this capability the
00188      *   length can only be specified in terms of arc length.
00189      * .
00190      * The default value of \e caps is GeodesicLine::ALL which turns on all the
00191      * capabilities.
00192      *
00193      * If the point is at a pole, the azimuth is defined by keeping the \e lon1
00194      * fixed and writing \e lat1 = 90 - \e eps or -90 + \e eps and taking the
00195      * limit \e eps -> 0 from above.
00196      **********************************************************************/
00197     GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1,
00198                  unsigned caps = ALL)
00199       throw();
00200 
00201     /**
00202      * A default constructor.  If GeodesicLine::Position is called on the
00203      * resulting object, it returns immediately (without doing any
00204      * calculations).  The object can be set with a call to Geodesic::Line.
00205      * Use Init() to test whether object is still in this uninitialized state.
00206      **********************************************************************/
00207     GeodesicLine() throw() : _caps(0U) {}
00208     ///@}
00209 
00210     /** \name Position in terms of distance
00211      **********************************************************************/
00212     ///@{
00213 
00214     /**
00215      * Compute the position of point 2 which is a distance \e s12 (meters)
00216      * from point 1.
00217      *
00218      * @param[in] s12 distance between point 1 and point 2 (meters); it can be
00219      *   signed.
00220      * @param[out] lat2 latitude of point 2 (degrees).
00221      * @param[out] lon2 longitude of point 2 (degrees); requires that the
00222      *   GeodesicLine object was constructed with \e caps |=
00223      *   GeodesicLine::LONGITUDE.
00224      * @param[out] azi2 (forward) azimuth at point 2 (degrees).
00225      * @param[out] m12 reduced length of geodesic (meters); requires that the
00226      *   GeodesicLine object was constructed with \e caps |=
00227      *   GeodesicLine::REDUCEDLENGTH.
00228      * @param[out] M12 geodesic scale of point 2 relative to point 1
00229      *   (dimensionless); requires that the GeodesicLine object was constructed
00230      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00231      * @param[out] M21 geodesic scale of point 1 relative to point 2
00232      *   (dimensionless); requires that the GeodesicLine object was constructed
00233      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00234      * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
00235      *   that the GeodesicLine object was constructed with \e caps |=
00236      *   GeodesicLine::AREA.
00237      * @return \e a12 arc length of between point 1 and point 2 (degrees).
00238      *
00239      * The values of \e lon2 and \e azi2 returned are in the range [-180, 180).
00240      *
00241      * The GeodesicLine object \e must have been constructed with \e caps |=
00242      * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no
00243      * parameters are set.  Requesting a value which the GeodesicLine object is
00244      * not capable of computing is not an error; the corresponding argument
00245      * will not be altered.
00246      *
00247      * The following functions are overloaded versions of
00248      * GeodesicLine::Position which omit some of the output parameters.  Note,
00249      * however, that the arc length is always computed and returned as the
00250      * function value.
00251      **********************************************************************/
00252     Math::real Position(real s12,
00253                         real& lat2, real& lon2, real& azi2,
00254                         real& m12, real& M12, real& M21,
00255                         real& S12) const throw() {
00256       real t;
00257       return GenPosition(false, s12,
00258                          LATITUDE | LONGITUDE | AZIMUTH |
00259                          REDUCEDLENGTH | GEODESICSCALE | AREA,
00260                          lat2, lon2, azi2, t, m12, M12, M21, S12);
00261     }
00262 
00263     /**
00264      * See the documentation for GeodesicLine::Position.
00265      **********************************************************************/
00266     Math::real Position(real s12, real& lat2, real& lon2) const throw() {
00267       real t;
00268       return GenPosition(false, s12,
00269                          LATITUDE | LONGITUDE,
00270                          lat2, lon2, t, t, t, t, t, t);
00271     }
00272 
00273     /**
00274      * See the documentation for GeodesicLine::Position.
00275      **********************************************************************/
00276     Math::real Position(real s12, real& lat2, real& lon2,
00277                         real& azi2) const throw() {
00278       real t;
00279       return GenPosition(false, s12,
00280                          LATITUDE | LONGITUDE | AZIMUTH,
00281                          lat2, lon2, azi2, t, t, t, t, t);
00282     }
00283 
00284     /**
00285      * See the documentation for GeodesicLine::Position.
00286      **********************************************************************/
00287     Math::real Position(real s12, real& lat2, real& lon2,
00288                         real& azi2, real& m12) const throw() {
00289       real t;
00290       return GenPosition(false, s12,
00291                          LATITUDE | LONGITUDE |
00292                          AZIMUTH | REDUCEDLENGTH,
00293                          lat2, lon2, azi2, t, m12, t, t, t);
00294     }
00295 
00296     /**
00297      * See the documentation for GeodesicLine::Position.
00298      **********************************************************************/
00299     Math::real Position(real s12, real& lat2, real& lon2,
00300                         real& azi2, real& M12, real& M21)
00301       const throw() {
00302       real t;
00303       return GenPosition(false, s12,
00304                          LATITUDE | LONGITUDE |
00305                          AZIMUTH | GEODESICSCALE,
00306                          lat2, lon2, azi2, t, t, M12, M21, t);
00307     }
00308 
00309     /**
00310      * See the documentation for GeodesicLine::Position.
00311      **********************************************************************/
00312     Math::real Position(real s12,
00313                         real& lat2, real& lon2, real& azi2,
00314                         real& m12, real& M12, real& M21)
00315       const throw() {
00316       real t;
00317       return GenPosition(false, s12,
00318                          LATITUDE | LONGITUDE | AZIMUTH |
00319                          REDUCEDLENGTH | GEODESICSCALE,
00320                          lat2, lon2, azi2, t, m12, M12, M21, t);
00321     }
00322 
00323     ///@}
00324 
00325     /** \name Position in terms of arc length
00326      **********************************************************************/
00327     ///@{
00328 
00329     /**
00330      * Compute the position of point 2 which is an arc length \e a12 (degrees)
00331      * from point 1.
00332      *
00333      * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
00334      *   be signed.
00335      * @param[out] lat2 latitude of point 2 (degrees).
00336      * @param[out] lon2 longitude of point 2 (degrees); requires that the
00337      *   GeodesicLine object was constructed with \e caps |=
00338      *   GeodesicLine::LONGITUDE.
00339      * @param[out] azi2 (forward) azimuth at point 2 (degrees).
00340      * @param[out] s12 distance between point 1 and point 2 (meters); requires
00341      *   that the GeodesicLine object was constructed with \e caps |=
00342      *   GeodesicLine::DISTANCE.
00343      * @param[out] m12 reduced length of geodesic (meters); requires that the
00344      *   GeodesicLine object was constructed with \e caps |=
00345      *   GeodesicLine::REDUCEDLENGTH.
00346      * @param[out] M12 geodesic scale of point 2 relative to point 1
00347      *   (dimensionless); requires that the GeodesicLine object was constructed
00348      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00349      * @param[out] M21 geodesic scale of point 1 relative to point 2
00350      *   (dimensionless); requires that the GeodesicLine object was constructed
00351      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00352      * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
00353      *   that the GeodesicLine object was constructed with \e caps |=
00354      *   GeodesicLine::AREA.
00355      *
00356      * The values of \e lon2 and \e azi2 returned are in the range [-180, 180).
00357      *
00358      * Requesting a value which the GeodesicLine object is not capable of
00359      * computing is not an error; the corresponding argument will not be
00360      * altered.
00361      *
00362      * The following functions are overloaded versions of
00363      * GeodesicLine::ArcPosition which omit some of the output parameters.
00364      **********************************************************************/
00365     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00366                      real& s12, real& m12, real& M12, real& M21,
00367                      real& S12) const throw() {
00368       GenPosition(true, a12,
00369                   LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
00370                   REDUCEDLENGTH | GEODESICSCALE | AREA,
00371                   lat2, lon2, azi2, s12, m12, M12, M21, S12);
00372     }
00373 
00374     /**
00375      * See the documentation for GeodesicLine::ArcPosition.
00376      **********************************************************************/
00377     void ArcPosition(real a12, real& lat2, real& lon2)
00378       const throw() {
00379       real t;
00380       GenPosition(true, a12,
00381                   LATITUDE | LONGITUDE,
00382                   lat2, lon2, t, t, t, t, t, t);
00383     }
00384 
00385     /**
00386      * See the documentation for GeodesicLine::ArcPosition.
00387      **********************************************************************/
00388     void ArcPosition(real a12,
00389                      real& lat2, real& lon2, real& azi2)
00390       const throw() {
00391       real t;
00392       GenPosition(true, a12,
00393                   LATITUDE | LONGITUDE | AZIMUTH,
00394                   lat2, lon2, azi2, t, t, t, t, t);
00395     }
00396 
00397     /**
00398      * See the documentation for GeodesicLine::ArcPosition.
00399      **********************************************************************/
00400     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00401                      real& s12) const throw() {
00402       real t;
00403       GenPosition(true, a12,
00404                   LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
00405                   lat2, lon2, azi2, s12, t, t, t, t);
00406     }
00407 
00408     /**
00409      * See the documentation for GeodesicLine::ArcPosition.
00410      **********************************************************************/
00411     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00412                      real& s12, real& m12) const throw() {
00413       real t;
00414       GenPosition(true, a12,
00415                   LATITUDE | LONGITUDE | AZIMUTH |
00416                   DISTANCE | REDUCEDLENGTH,
00417                   lat2, lon2, azi2, s12, m12, t, t, t);
00418     }
00419 
00420     /**
00421      * See the documentation for GeodesicLine::ArcPosition.
00422      **********************************************************************/
00423     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00424                      real& s12, real& M12, real& M21)
00425       const throw() {
00426       real t;
00427       GenPosition(true, a12,
00428                   LATITUDE | LONGITUDE | AZIMUTH |
00429                   DISTANCE | GEODESICSCALE,
00430                   lat2, lon2, azi2, s12, t, M12, M21, t);
00431     }
00432 
00433     /**
00434      * See the documentation for GeodesicLine::ArcPosition.
00435      **********************************************************************/
00436     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00437                      real& s12, real& m12, real& M12, real& M21)
00438       const throw() {
00439       real t;
00440       GenPosition(true, a12,
00441                   LATITUDE | LONGITUDE | AZIMUTH |
00442                   DISTANCE | REDUCEDLENGTH | GEODESICSCALE,
00443                   lat2, lon2, azi2, s12, m12, M12, M21, t);
00444     }
00445     ///@}
00446 
00447     /** \name The general position function.
00448      **********************************************************************/
00449     ///@{
00450 
00451     /**
00452      * The general position function.  GeodesicLine::Position and
00453      * GeodesicLine::ArcPosition are defined in terms of this function.
00454      *
00455      * @param[in] arcmode boolean flag determining the meaning of the second
00456      *   parameter; if arcmode is false, then the GeodesicLine object must have
00457      *   been constructed with \e caps |= GeodesicLine::DISTANCE_IN.
00458      * @param[in] s12_a12 if \e arcmode is false, this is the distance between
00459      *   point 1 and point 2 (meters); otherwise it is the arc length between
00460      *   point 1 and point 2 (degrees); it can be signed.
00461      * @param[in] outmask a bitor'ed combination of GeodesicLine::mask values
00462      *   specifying which of the following parameters should be set.
00463      * @param[out] lat2 latitude of point 2 (degrees).
00464      * @param[out] lon2 longitude of point 2 (degrees); requires that the
00465      *   GeodesicLine object was constructed with \e caps |=
00466      *   GeodesicLine::LONGITUDE.
00467      * @param[out] azi2 (forward) azimuth at point 2 (degrees).
00468      * @param[out] s12 distance between point 1 and point 2 (meters); requires
00469      *   that the GeodesicLine object was constructed with \e caps |=
00470      *   GeodesicLine::DISTANCE.
00471      * @param[out] m12 reduced length of geodesic (meters); requires that the
00472      *   GeodesicLine object was constructed with \e caps |=
00473      *   GeodesicLine::REDUCEDLENGTH.
00474      * @param[out] M12 geodesic scale of point 2 relative to point 1
00475      *   (dimensionless); requires that the GeodesicLine object was constructed
00476      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00477      * @param[out] M21 geodesic scale of point 1 relative to point 2
00478      *   (dimensionless); requires that the GeodesicLine object was constructed
00479      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00480      * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
00481      *   that the GeodesicLine object was constructed with \e caps |=
00482      *   GeodesicLine::AREA.
00483      * @return \e a12 arc length of between point 1 and point 2 (degrees).
00484      *
00485      * The GeodesicLine::mask values possible for \e outmask are
00486      * - \e outmask |= GeodesicLine::LATITUDE for the latitude \e lat2.
00487      * - \e outmask |= GeodesicLine::LONGITUDE for the latitude \e lon2.
00488      * - \e outmask |= GeodesicLine::AZIMUTH for the latitude \e azi2.
00489      * - \e outmask |= GeodesicLine::DISTANCE for the distance \e s12.
00490      * - \e outmask |= GeodesicLine::REDUCEDLENGTH for the reduced length \e
00491      *   m12.
00492      * - \e outmask |= GeodesicLine::GEODESICSCALE for the geodesic scales \e
00493      *   M12 and \e M21.
00494      * - \e outmask |= GeodesicLine::AREA for the area \e S12.
00495      * .
00496      * Requesting a value which the GeodesicLine object is not capable of
00497      * computing is not an error; the corresponding argument will not be
00498      * altered.  Note, however, that the arc length is always computed and
00499      * returned as the function value.
00500      **********************************************************************/
00501     Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask,
00502                            real& lat2, real& lon2, real& azi2,
00503                            real& s12, real& m12, real& M12, real& M21,
00504                            real& S12) const throw();
00505 
00506     ///@}
00507 
00508     /** \name Inspector functions
00509      **********************************************************************/
00510     ///@{
00511 
00512     /**
00513      * @return true if the object has been initialized.
00514      **********************************************************************/
00515     bool Init() const throw() { return _caps != 0U; }
00516 
00517     /**
00518      * @return \e lat1 the latitude of point 1 (degrees).
00519      **********************************************************************/
00520     Math::real Latitude() const throw()
00521     { return Init() ? _lat1 : Math::NaN<real>(); }
00522 
00523     /**
00524      * @return \e lon1 the longitude of point 1 (degrees).
00525      **********************************************************************/
00526     Math::real Longitude() const throw()
00527     { return Init() ? _lon1 : Math::NaN<real>(); }
00528 
00529     /**
00530      * @return \e azi1 the azimuth (degrees) of the geodesic line at point 1.
00531      **********************************************************************/
00532     Math::real Azimuth() const throw()
00533     { return Init() ? _azi1 : Math::NaN<real>(); }
00534 
00535     /**
00536      * @return \e azi0 the azimuth (degrees) of the geodesic line as it crosses
00537      * the equator in a northward direction.
00538      **********************************************************************/
00539     Math::real EquatorialAzimuth() const throw() {
00540       return Init() ?
00541         atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>();
00542     }
00543 
00544     /**
00545      * @return \e a1 the arc length (degrees) between the northward equatorial
00546      * crossing and point 1.
00547      **********************************************************************/
00548     Math::real EquatorialArc() const throw() {
00549       return Init() ?
00550         atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>();
00551     }
00552 
00553     /**
00554      * @return \e a the equatorial radius of the ellipsoid (meters).  This is
00555      *   the value inherited from the Geodesic object used in the constructor.
00556      **********************************************************************/
00557     Math::real MajorRadius() const throw()
00558     { return Init() ? _a : Math::NaN<real>(); }
00559 
00560     /**
00561      * @return \e f the flattening of the ellipsoid.  This is the value
00562      *   inherited from the Geodesic object used in the constructor.
00563      **********************************************************************/
00564     Math::real Flattening() const throw()
00565     { return Init() ? _f : Math::NaN<real>(); }
00566 
00567     /// \cond SKIP
00568     /**
00569      * <b>DEPRECATED</b>
00570      * @return \e r the inverse flattening of the ellipsoid.
00571      **********************************************************************/
00572     Math::real InverseFlattening() const throw()
00573     { return Init() ? 1/_f : Math::NaN<real>(); }
00574     /// \endcond
00575 
00576     /**
00577      * @return \e caps the computational capabilities that this object was
00578      *   constructed with.  LATITUDE and AZIMUTH are always included.
00579      **********************************************************************/
00580     unsigned Capabilities() const throw() { return _caps; }
00581 
00582     /**
00583      * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
00584      * @return true if the GeodesicLine object has all these capabilities.
00585      **********************************************************************/
00586     bool Capabilities(unsigned testcaps) const throw() {
00587       testcaps &= OUT_ALL;
00588       return (_caps & testcaps) == testcaps;
00589     }
00590     ///@}
00591 
00592   };
00593 
00594 } // namespace GeographicLib
00595 
00596 #endif  // GEOGRAPHICLIB_GEODESICLINE_HPP