| Geodesic.hpp | | Geodesic.hpp | |
| | | | |
| skipping to change at line 91 | | skipping to change at line 91 | |
| * equator to point 1. The area of this quadrilateral is represented b
y \e | | * equator to point 1. The area of this quadrilateral is represented b
y \e | |
| * S12 with a clockwise traversal of the perimeter counting as a positi
ve | | * S12 with a clockwise traversal of the perimeter counting as a positi
ve | |
| * area and it can be used to compute the area of any simple geodesic | | * area and it can be used to compute the area of any simple geodesic | |
| * polygon. | | * polygon. | |
| * | | * | |
| * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and | | * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and | |
| * Geodesic::Inverse allow these quantities to be returned. In addition | | * Geodesic::Inverse allow these quantities to be returned. In addition | |
| * there are general functions Geodesic::GenDirect, and Geodesic::GenInve
rse | | * there are general functions Geodesic::GenDirect, and Geodesic::GenInve
rse | |
| * which allow an arbitrary set of results to be computed. The quantitie
s \e | | * which allow an arbitrary set of results to be computed. The quantitie
s \e | |
| * m12, \e M12, \e M21 which all specify the behavior of nearby geodesics | | * m12, \e M12, \e M21 which all specify the behavior of nearby geodesics | |
|
| * obey addition rules. Let points 1, 2, and 3 all lie on a single geode | | * obey addition rules. If points 1, 2, and 3 all lie on a single geodes | |
| sic, | | ic, | |
| * then | | * then the following rules hold: | |
| | | * - \e s13 = \e s12 + \e s23 | |
| | | * - \e a13 = \e a12 + \e a23 | |
| | | * - \e S13 = \e S12 + \e S23 | |
| * - \e m13 = \e m12 \e M23 + \e m23 \e M21 | | * - \e m13 = \e m12 \e M23 + \e m23 \e M21 | |
| * - \e M13 = \e M12 \e M23 − (1 − \e M12 \e M21) \e m23 / \e
m12 | | * - \e M13 = \e M12 \e M23 − (1 − \e M12 \e M21) \e m23 / \e
m12 | |
| * - \e M31 = \e M32 \e M21 − (1 − \e M23 \e M32) \e m12 / \e
m23 | | * - \e M31 = \e M32 \e M21 − (1 − \e M23 \e M32) \e m12 / \e
m23 | |
| * | | * | |
| * Additional functionality is provided by the GeodesicLine class, which | | * Additional functionality is provided by the GeodesicLine class, which | |
| * allows a sequence of points along a geodesic to be computed. | | * allows a sequence of points along a geodesic to be computed. | |
| * | | * | |
|
| | | * The shortest distance returned by the solution of the inverse problem | |
| | | is | |
| | | * (obviously) uniquely defined. However, in a few special cases there a | |
| | | re | |
| | | * multiple azimuths which yield the same shortest distance. Here is a | |
| | | * catalog of those cases: | |
| | | * - \e lat1 = −\e lat2 (with neither at a pole). If \e azi1 = \e | |
| | | * azi2, the geodesic is unique. Otherwise there are two geodesics and | |
| | | the | |
| | | * second one is obtained by setting [\e azi1, \e azi2] = [\e azi2, \e | |
| | | * azi1], [\e M12, \e M21] = [\e M21, \e M12], \e S12 = −\e S12. | |
| | | * (This occurs when the longitude difference is near ±180° | |
| | | for | |
| | | * oblate ellipsoids.) | |
| | | * - \e lon2 = \e lon1 ± 180° (with neither at a pole). If \e | |
| | | * azi1 = 0° or ±180°, the geodesic is unique. Otherwis | |
| | | e | |
| | | * there are two geodesics and the second one is obtained by setting [\ | |
| | | e | |
| | | * azi1, \e azi2] = [−\e azi1, −\e azi2], \e S12 = −\ | |
| | | e | |
| | | * S12. (This occurs when the \e lat2 is near −\e lat1 for prola | |
| | | te | |
| | | * ellipsoids.) | |
| | | * - Points 1 and 2 at opposite poles. There are infinitely many geodesi | |
| | | cs | |
| | | * which can be generated by setting [\e azi1, \e azi2] = [\e azi1, \e | |
| | | * azi2] + [\e d, −\e d], for arbitrary \e d. (For spheres, this | |
| | | * prescription applies when points 1 and 2 are antipodal.) | |
| | | * - s12 = 0 (coincident points). There are infinitely many geodesics wh | |
| | | ich | |
| | | * can be generated by setting [\e azi1, \e azi2] = [\e azi1, \e azi2] | |
| | | + | |
| | | * [\e d, \e d], for arbitrary \e d. | |
| | | * | |
| * The calculations are accurate to better than 15 nm (15 nanometers) for
the | | * The calculations are accurate to better than 15 nm (15 nanometers) for
the | |
| * WGS84 ellipsoid. See Sec. 9 of | | * WGS84 ellipsoid. See Sec. 9 of | |
| * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | | * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | |
| * details. The algorithms used by this class are based on series expans
ions | | * details. The algorithms used by this class are based on series expans
ions | |
|
| * using the flattening \e f as a small parameter. These only accurate f | | * using the flattening \e f as a small parameter. These are only accura | |
| or | | te | |
| * |\e f| < 0.02; however reasonably accurate results will be obtained | | * for |<i>f</i>| < 0.02; however reasonably accurate results will be | |
| for | | * obtained for |<i>f</i>| < 0.2. Here is a table of the approximate | |
| * |\e f| < 0.2. Here is a table of the approximate maximum error | | * maximum error (expressed as a distance) for an ellipsoid with the same | |
| * (expressed as a distance) for an ellipsoid with the same major radius | | * major radius as the WGS84 ellipsoid and different values of the | |
| as | | * flattening.<pre> | |
| * the WGS84 ellipsoid and different values of the flattening.<pre> | | | |
| * |f| error | | * |f| error | |
| * 0.01 25 nm | | * 0.01 25 nm | |
| * 0.02 30 nm | | * 0.02 30 nm | |
| * 0.05 10 um | | * 0.05 10 um | |
| * 0.1 1.5 mm | | * 0.1 1.5 mm | |
| * 0.2 300 mm | | * 0.2 300 mm | |
| * </pre>For very eccentric ellipsoids, use GeodesicExact instead. | | * </pre>For very eccentric ellipsoids, use GeodesicExact instead. | |
| * | | * | |
| * The algorithms are described in | | * The algorithms are described in | |
| * - C. F. F. Karney, | | * - C. F. F. Karney, | |
| * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * Algorithms for geodesics</a>, | | * Algorithms for geodesics</a>, | |
|
| * J. Geodesy, 2012; | | * J. Geodesy <b>87</b>, 43--55 (2013); | |
| * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * 10.1007/s00190-012-0578-z</a>; | | * 10.1007/s00190-012-0578-z</a>; | |
| * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> | | * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> | |
| * geod-addenda.html</a>. | | * geod-addenda.html</a>. | |
| * . | | * . | |
| * For more information on geodesics see \ref geodesic. | | * For more information on geodesics see \ref geodesic. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-Geodesic.cpp | | * \include example-Geodesic.cpp | |
| * | | * | |
| | | | |
| skipping to change at line 182 | | skipping to change at line 210 | |
| | | | |
| static real SinCosSeries(bool sinp, | | static real SinCosSeries(bool sinp, | |
| real sinx, real cosx, const real c[], int n) | | real sinx, real cosx, const real c[], int n) | |
| throw(); | | throw(); | |
| static inline real AngRound(real x) throw() { | | static inline real AngRound(real x) throw() { | |
| // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^
57 | | // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^
57 | |
| // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi
s | | // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi
s | |
| // is about 1000 times more resolution than we get with angles around
90 | | // is about 1000 times more resolution than we get with angles around
90 | |
| // degrees.) We use this to avoid having to deal with near singular | | // degrees.) We use this to avoid having to deal with near singular | |
| // cases when x is non-zero but tiny (e.g., 1.0e-200). | | // cases when x is non-zero but tiny (e.g., 1.0e-200). | |
|
| const real z = real(0.0625); // 1/16 | | const real z = 1/real(16); | |
| volatile real y = std::abs(x); | | volatile real y = std::abs(x); | |
| // The compiler mustn't "simplify" z - (z - y) to y | | // The compiler mustn't "simplify" z - (z - y) to y | |
| y = y < z ? z - (z - y) : y; | | y = y < z ? z - (z - y) : y; | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
| } | | } | |
| static inline void SinCosNorm(real& sinx, real& cosx) throw() { | | static inline void SinCosNorm(real& sinx, real& cosx) throw() { | |
| real r = Math::hypot(sinx, cosx); | | real r = Math::hypot(sinx, cosx); | |
| sinx /= r; | | sinx /= r; | |
| cosx /= r; | | cosx /= r; | |
| } | | } | |
| | | | |
| skipping to change at line 322 | | skipping to change at line 350 | |
| * @exception GeographicErr if \e a or (1 − \e f ) \e a is not | | * @exception GeographicErr if \e a or (1 − \e f ) \e a is not | |
| * positive. | | * positive. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Geodesic(real a, real f); | | Geodesic(real a, real f); | |
| ///@} | | ///@} | |
| | | | |
| /** \name Direct geodesic problem specified in terms of distance. | | /** \name Direct geodesic problem specified in terms of distance. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
|
| * Perform the direct geodesic calculation where the length of the geod
esic | | * Solve the direct geodesic problem where the length of the geodesic | |
| * is specify in terms of distance. | | * is specify in terms of distance. | |
| * | | * | |
| * @param[in] lat1 latitude of point 1 (degrees). | | * @param[in] lat1 latitude of point 1 (degrees). | |
| * @param[in] lon1 longitude of point 1 (degrees). | | * @param[in] lon1 longitude of point 1 (degrees). | |
| * @param[in] azi1 azimuth at point 1 (degrees). | | * @param[in] azi1 azimuth at point 1 (degrees). | |
| * @param[in] s12 distance between point 1 and point 2 (meters); it can
be | | * @param[in] s12 distance between point 1 and point 2 (meters); it can
be | |
|
| * signed. | | * negative. | |
| * @param[out] lat2 latitude of point 2 (degrees). | | * @param[out] lat2 latitude of point 2 (degrees). | |
| * @param[out] lon2 longitude of point 2 (degrees). | | * @param[out] lon2 longitude of point 2 (degrees). | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] m12 reduced length of geodesic (meters). | | * @param[out] m12 reduced length of geodesic (meters). | |
| * @param[out] M12 geodesic scale of point 2 relative to point 1 | | * @param[out] M12 geodesic scale of point 2 relative to point 1 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] M21 geodesic scale of point 1 relative to point 2 | | * @param[out] M21 geodesic scale of point 1 relative to point 2 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | | * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | |
| * @return \e a12 arc length of between point 1 and point 2 (degrees). | | * @return \e a12 arc length of between point 1 and point 2 (degrees). | |
| * | | * | |
| * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | | * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | |
| * azi1 should be in the range [−540°, 540°). The values
of | | * azi1 should be in the range [−540°, 540°). The values
of | |
| * \e lon2 and \e azi2 returned are in the range [−180°, | | * \e lon2 and \e azi2 returned are in the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
|
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = ±(90° − &epsil | |
| * −90° + ε and taking the limit ε → 0 f | | on;) | |
| rom | | * and taking the limit ε → 0+. An arc length greater tha | |
| * above. An arc length greater that 180° signifies a geodesic whi | | t | |
| ch | | * 180° signifies a geodesic which is not a shortest path. (For a | |
| * is not a shortest path. (For a prolate ellipsoid, an additional | | * prolate ellipsoid, an additional condition is necessary for a shorte | |
| * condition is necessary for a shortest path: the longitudinal extent | | st | |
| must | | * path: the longitudinal extent must not exceed of 180°.) | |
| * not exceed of 180°.) | | | |
| * | | * | |
| * The following functions are overloaded versions of Geodesic::Direct | | * The following functions are overloaded versions of Geodesic::Direct | |
| * which omit some of the output parameters. Note, however, that the a
rc | | * which omit some of the output parameters. Note, however, that the a
rc | |
| * length is always computed and returned as the function value. | | * length is always computed and returned as the function value. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Direct(real lat1, real lon1, real azi1, real s12, | | Math::real Direct(real lat1, real lon1, real azi1, real s12, | |
| real& lat2, real& lon2, real& azi2, | | real& lat2, real& lon2, real& azi2, | |
| real& m12, real& M12, real& M21, real& S12) | | real& m12, real& M12, real& M21, real& S12) | |
| const throw() { | | const throw() { | |
| real t; | | real t; | |
| | | | |
| skipping to change at line 437 | | skipping to change at line 464 | |
| LATITUDE | LONGITUDE | AZIMUTH | | | LATITUDE | LONGITUDE | AZIMUTH | | |
| REDUCEDLENGTH | GEODESICSCALE, | | REDUCEDLENGTH | GEODESICSCALE, | |
| lat2, lon2, azi2, t, m12, M12, M21, t); | | lat2, lon2, azi2, t, m12, M12, M21, t); | |
| } | | } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Direct geodesic problem specified in terms of arc length. | | /** \name Direct geodesic problem specified in terms of arc length. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
|
| * Perform the direct geodesic calculation where the length of the geod
esic | | * Solve the direct geodesic problem where the length of the geodesic | |
| * is specify in terms of arc length. | | * is specify in terms of arc length. | |
| * | | * | |
| * @param[in] lat1 latitude of point 1 (degrees). | | * @param[in] lat1 latitude of point 1 (degrees). | |
| * @param[in] lon1 longitude of point 1 (degrees). | | * @param[in] lon1 longitude of point 1 (degrees). | |
| * @param[in] azi1 azimuth at point 1 (degrees). | | * @param[in] azi1 azimuth at point 1 (degrees). | |
| * @param[in] a12 arc length between point 1 and point 2 (degrees); it
can | | * @param[in] a12 arc length between point 1 and point 2 (degrees); it
can | |
|
| * be signed. | | * be negative. | |
| * @param[out] lat2 latitude of point 2 (degrees). | | * @param[out] lat2 latitude of point 2 (degrees). | |
| * @param[out] lon2 longitude of point 2 (degrees). | | * @param[out] lon2 longitude of point 2 (degrees). | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] s12 distance between point 1 and point 2 (meters). | | * @param[out] s12 distance between point 1 and point 2 (meters). | |
| * @param[out] m12 reduced length of geodesic (meters). | | * @param[out] m12 reduced length of geodesic (meters). | |
| * @param[out] M12 geodesic scale of point 2 relative to point 1 | | * @param[out] M12 geodesic scale of point 2 relative to point 1 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] M21 geodesic scale of point 1 relative to point 2 | | * @param[out] M21 geodesic scale of point 1 relative to point 2 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | | * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | |
| * | | * | |
| * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | | * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | |
| * azi1 should be in the range [−540°, 540°). The values
of | | * azi1 should be in the range [−540°, 540°). The values
of | |
| * \e lon2 and \e azi2 returned are in the range [−180°, | | * \e lon2 and \e azi2 returned are in the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
|
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = ±(90° − &epsil | |
| * −90° + ε and taking the limit ε → 0 f | | on;) | |
| rom | | * and taking the limit ε → 0+. An arc length greater tha | |
| * above. An arc length greater that 180° signifies a geodesic whi | | t | |
| ch | | * 180° signifies a geodesic which is not a shortest path. (For a | |
| * is not a shortest path. (For a prolate ellipsoid, an additional | | * prolate ellipsoid, an additional condition is necessary for a shorte | |
| * condition is necessary for a shortest path: the longitudinal extent | | st | |
| must | | * path: the longitudinal extent must not exceed of 180°.) | |
| * not exceed of 180°.) | | | |
| * | | * | |
| * The following functions are overloaded versions of Geodesic::Direct | | * The following functions are overloaded versions of Geodesic::Direct | |
| * which omit some of the output parameters. | | * which omit some of the output parameters. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void ArcDirect(real lat1, real lon1, real azi1, real a12, | | void ArcDirect(real lat1, real lon1, real azi1, real a12, | |
| real& lat2, real& lon2, real& azi2, real& s12, | | real& lat2, real& lon2, real& azi2, real& s12, | |
| real& m12, real& M12, real& M21, real& S12) | | real& m12, real& M12, real& M21, real& S12) | |
| const throw() { | | const throw() { | |
| GenDirect(lat1, lon1, azi1, true, a12, | | GenDirect(lat1, lon1, azi1, true, a12, | |
| LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | | | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | | |
| | | | |
| skipping to change at line 561 | | skipping to change at line 587 | |
| REDUCEDLENGTH | GEODESICSCALE, | | REDUCEDLENGTH | GEODESICSCALE, | |
| lat2, lon2, azi2, s12, m12, M12, M21, t); | | lat2, lon2, azi2, s12, m12, M12, M21, t); | |
| } | | } | |
| ///@} | | ///@} | |
| | | | |
| /** \name General version of the direct geodesic solution. | | /** \name General version of the direct geodesic solution. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
|
| * The general direct geodesic calculation. Geodesic::Direct and | | * The general direct geodesic problem. Geodesic::Direct and | |
| * Geodesic::ArcDirect are defined in terms of this function. | | * Geodesic::ArcDirect are defined in terms of this function. | |
| * | | * | |
| * @param[in] lat1 latitude of point 1 (degrees). | | * @param[in] lat1 latitude of point 1 (degrees). | |
| * @param[in] lon1 longitude of point 1 (degrees). | | * @param[in] lon1 longitude of point 1 (degrees). | |
| * @param[in] azi1 azimuth at point 1 (degrees). | | * @param[in] azi1 azimuth at point 1 (degrees). | |
|
| * @param[in] arcmode boolean flag determining the meaning of the secon | | * @param[in] arcmode boolean flag determining the meaning of the \e | |
| d | | * s12_a12. | |
| * parameter. | | | |
| * @param[in] s12_a12 if \e arcmode is false, this is the distance betw
een | | * @param[in] s12_a12 if \e arcmode is false, this is the distance betw
een | |
| * point 1 and point 2 (meters); otherwise it is the arc length betwe
en | | * point 1 and point 2 (meters); otherwise it is the arc length betwe
en | |
|
| * point 1 and point 2 (degrees); it can be signed. | | * point 1 and point 2 (degrees); it can be negative. | |
| * @param[in] outmask a bitor'ed combination of Geodesic::mask values | | * @param[in] outmask a bitor'ed combination of Geodesic::mask values | |
| * specifying which of the following parameters should be set. | | * specifying which of the following parameters should be set. | |
| * @param[out] lat2 latitude of point 2 (degrees). | | * @param[out] lat2 latitude of point 2 (degrees). | |
| * @param[out] lon2 longitude of point 2 (degrees). | | * @param[out] lon2 longitude of point 2 (degrees). | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] s12 distance between point 1 and point 2 (meters). | | * @param[out] s12 distance between point 1 and point 2 (meters). | |
| * @param[out] m12 reduced length of geodesic (meters). | | * @param[out] m12 reduced length of geodesic (meters). | |
| * @param[out] M12 geodesic scale of point 2 relative to point 1 | | * @param[out] M12 geodesic scale of point 2 relative to point 1 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] M21 geodesic scale of point 1 relative to point 2 | | * @param[out] M21 geodesic scale of point 1 relative to point 2 | |
| | | | |
| skipping to change at line 614 | | skipping to change at line 640 | |
| bool arcmode, real s12_a12, unsigned outmask, | | bool arcmode, real s12_a12, unsigned outmask, | |
| real& lat2, real& lon2, real& azi2, | | real& lat2, real& lon2, real& azi2, | |
| real& s12, real& m12, real& M12, real& M21, | | real& s12, real& m12, real& M12, real& M21, | |
| real& S12) const throw(); | | real& S12) const throw(); | |
| ///@} | | ///@} | |
| | | | |
| /** \name Inverse geodesic problem. | | /** \name Inverse geodesic problem. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
|
| * Perform the inverse geodesic calculation. | | * Solve the inverse geodesic problem. | |
| * | | * | |
| * @param[in] lat1 latitude of point 1 (degrees). | | * @param[in] lat1 latitude of point 1 (degrees). | |
| * @param[in] lon1 longitude of point 1 (degrees). | | * @param[in] lon1 longitude of point 1 (degrees). | |
| * @param[in] lat2 latitude of point 2 (degrees). | | * @param[in] lat2 latitude of point 2 (degrees). | |
| * @param[in] lon2 longitude of point 2 (degrees). | | * @param[in] lon2 longitude of point 2 (degrees). | |
| * @param[out] s12 distance between point 1 and point 2 (meters). | | * @param[out] s12 distance between point 1 and point 2 (meters). | |
| * @param[out] azi1 azimuth at point 1 (degrees). | | * @param[out] azi1 azimuth at point 1 (degrees). | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] m12 reduced length of geodesic (meters). | | * @param[out] m12 reduced length of geodesic (meters). | |
| * @param[out] M12 geodesic scale of point 2 relative to point 1 | | * @param[out] M12 geodesic scale of point 2 relative to point 1 | |
| | | | |
| skipping to change at line 637 | | skipping to change at line 663 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | | * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | |
| * @return \e a12 arc length of between point 1 and point 2 (degrees). | | * @return \e a12 arc length of between point 1 and point 2 (degrees). | |
| * | | * | |
| * \e lat1 and \e lat2 should be in the range [−90°, 90°]
; \e | | * \e lat1 and \e lat2 should be in the range [−90°, 90°]
; \e | |
| * lon1 and \e lon2 should be in the range [−540°, 540°). | | * lon1 and \e lon2 should be in the range [−540°, 540°). | |
| * The values of \e azi1 and \e azi2 returned are in the range | | * The values of \e azi1 and \e azi2 returned are in the range | |
| * [−180°, 180°). | | * [−180°, 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
|
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = ±(90° − &epsil | |
| * −90° + ε and taking the limit ε → 0 f | | on;) | |
| rom | | * and taking the limit ε → 0+. | |
| * above. | | | |
| * | | * | |
| * The solution to the inverse problem is found using Newton's method.
If | | * The solution to the inverse problem is found using Newton's method.
If | |
| * this fails to converge (this is very unlikely in geodetic applicatio
ns | | * this fails to converge (this is very unlikely in geodetic applicatio
ns | |
| * but does occur for very eccentric ellipsoids), then the bisection me
thod | | * but does occur for very eccentric ellipsoids), then the bisection me
thod | |
| * is used to refine the solution. | | * is used to refine the solution. | |
| * | | * | |
| * The following functions are overloaded versions of Geodesic::Inverse | | * The following functions are overloaded versions of Geodesic::Inverse | |
| * which omit some of the output parameters. Note, however, that the a
rc | | * which omit some of the output parameters. Note, however, that the a
rc | |
| * length is always computed and returned as the function value. | | * length is always computed and returned as the function value. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
| skipping to change at line 810 | | skipping to change at line 835 | |
| * and \e M21 | | * and \e M21 | |
| * - \e caps |= Geodesic::AREA for the area \e S12 | | * - \e caps |= Geodesic::AREA for the area \e S12 | |
| * - \e caps |= Geodesic::DISTANCE_IN permits the length of the | | * - \e caps |= Geodesic::DISTANCE_IN permits the length of the | |
| * geodesic to be given in terms of \e s12; without this capability t
he | | * geodesic to be given in terms of \e s12; without this capability t
he | |
| * length can only be specified in terms of arc length. | | * length can only be specified in terms of arc length. | |
| * . | | * . | |
| * The default value of \e caps is Geodesic::ALL which turns on all the | | * The default value of \e caps is Geodesic::ALL which turns on all the | |
| * capabilities. | | * capabilities. | |
| * | | * | |
| * If the point is at a pole, the azimuth is defined by keeping the \e
lon1 | | * If the point is at a pole, the azimuth is defined by keeping the \e
lon1 | |
|
| * fixed and writing \e lat1 = 90 − ε or −90 + | | * fixed and writing \e lat1 = ±&(90 − ε) and taki | |
| * ε and taking the limit ε → 0 from above. | | ng | |
| | | * the limit ε → 0+. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps = ALL) | | GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps = ALL) | |
| const throw(); | | const throw(); | |
| | | | |
| ///@} | | ///@} | |
| | | | |
| /** \name Inspector functions. | | /** \name Inspector functions. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| | | | |
End of changes. 17 change blocks. |
| 47 lines changed or deleted | | 81 lines changed or added | |
|
| GeodesicExact.hpp | | GeodesicExact.hpp | |
| | | | |
| skipping to change at line 116 | | skipping to change at line 116 | |
| }; | | }; | |
| | | | |
| static real CosSeries(real sinx, real cosx, const real c[], int n) | | static real CosSeries(real sinx, real cosx, const real c[], int n) | |
| throw(); | | throw(); | |
| static inline real AngRound(real x) throw() { | | static inline real AngRound(real x) throw() { | |
| // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^
57 | | // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^
57 | |
| // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi
s | | // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi
s | |
| // is about 1000 times more resolution than we get with angles around
90 | | // is about 1000 times more resolution than we get with angles around
90 | |
| // degrees.) We use this to avoid having to deal with near singular | | // degrees.) We use this to avoid having to deal with near singular | |
| // cases when x is non-zero but tiny (e.g., 1.0e-200). | | // cases when x is non-zero but tiny (e.g., 1.0e-200). | |
|
| const real z = real(0.0625); // 1/16 | | const real z = 1/real(16); | |
| volatile real y = std::abs(x); | | volatile real y = std::abs(x); | |
| // The compiler mustn't "simplify" z - (z - y) to y | | // The compiler mustn't "simplify" z - (z - y) to y | |
| y = y < z ? z - (z - y) : y; | | y = y < z ? z - (z - y) : y; | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
| } | | } | |
| static inline void SinCosNorm(real& sinx, real& cosx) throw() { | | static inline void SinCosNorm(real& sinx, real& cosx) throw() { | |
| real r = Math::hypot(sinx, cosx); | | real r = Math::hypot(sinx, cosx); | |
| sinx /= r; | | sinx /= r; | |
| cosx /= r; | | cosx /= r; | |
| } | | } | |
| | | | |
| skipping to change at line 272 | | skipping to change at line 272 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | | * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | |
| * @return \e a12 arc length of between point 1 and point 2 (degrees). | | * @return \e a12 arc length of between point 1 and point 2 (degrees). | |
| * | | * | |
| * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | | * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | |
| * azi1 should be in the range [−540°, 540°). The values
of | | * azi1 should be in the range [−540°, 540°). The values
of | |
| * \e lon2 and \e azi2 returned are in the range [−180°, | | * \e lon2 and \e azi2 returned are in the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
|
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = ±(90° − &epsil | |
| * −90° + ε and taking the limit ε → 0 f | | on;) | |
| rom | | * and taking the limit ε → 0+.. An arc length greater th | |
| * above. An arc length greater that 180° signifies a geodesic whi | | at | |
| ch | | * 180° signifies a geodesic which is not a shortest path. (For a | |
| * is not a shortest path. (For a prolate ellipsoid, an additional | | * prolate ellipsoid, an additional condition is necessary for a shorte | |
| * condition is necessary for a shortest path: the longitudinal extent | | st | |
| must | | * path: the longitudinal extent must not exceed of 180°.) | |
| * not exceed of 180°.) | | | |
| * | | * | |
| * The following functions are overloaded versions of GeodesicExact::Di
rect | | * The following functions are overloaded versions of GeodesicExact::Di
rect | |
| * which omit some of the output parameters. Note, however, that the a
rc | | * which omit some of the output parameters. Note, however, that the a
rc | |
| * length is always computed and returned as the function value. | | * length is always computed and returned as the function value. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Direct(real lat1, real lon1, real azi1, real s12, | | Math::real Direct(real lat1, real lon1, real azi1, real s12, | |
| real& lat2, real& lon2, real& azi2, | | real& lat2, real& lon2, real& azi2, | |
| real& m12, real& M12, real& M21, real& S12) | | real& m12, real& M12, real& M21, real& S12) | |
| const throw() { | | const throw() { | |
| real t; | | real t; | |
| | | | |
| skipping to change at line 387 | | skipping to change at line 386 | |
| * @param[out] M21 geodesic scale of point 1 relative to point 2 | | * @param[out] M21 geodesic scale of point 1 relative to point 2 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | | * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | |
| * | | * | |
| * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | | * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | |
| * azi1 should be in the range [−540°, 540°). The values
of | | * azi1 should be in the range [−540°, 540°). The values
of | |
| * \e lon2 and \e azi2 returned are in the range [−180°, | | * \e lon2 and \e azi2 returned are in the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
|
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = ±(90° − &epsil | |
| * −90° + ε and taking the limit ε → 0 f | | on;) | |
| rom | | * and taking the limit ε → 0+. An arc length greater tha | |
| * above. An arc length greater that 180° signifies a geodesic whi | | t | |
| ch | | * 180° signifies a geodesic which is not a shortest path. (For a | |
| * is not a shortest path. (For a prolate ellipsoid, an additional | | * prolate ellipsoid, an additional condition is necessary for a shorte | |
| * condition is necessary for a shortest path: the longitudinal extent | | st | |
| must | | * path: the longitudinal extent must not exceed of 180°.) | |
| * not exceed of 180°.) | | | |
| * | | * | |
| * The following functions are overloaded versions of GeodesicExact::Di
rect | | * The following functions are overloaded versions of GeodesicExact::Di
rect | |
| * which omit some of the output parameters. | | * which omit some of the output parameters. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void ArcDirect(real lat1, real lon1, real azi1, real a12, | | void ArcDirect(real lat1, real lon1, real azi1, real a12, | |
| real& lat2, real& lon2, real& azi2, real& s12, | | real& lat2, real& lon2, real& azi2, real& s12, | |
| real& m12, real& M12, real& M21, real& S12) | | real& m12, real& M12, real& M21, real& S12) | |
| const throw() { | | const throw() { | |
| GenDirect(lat1, lon1, azi1, true, a12, | | GenDirect(lat1, lon1, azi1, true, a12, | |
| LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | | | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | | |
| | | | |
| skipping to change at line 562 | | skipping to change at line 560 | |
| * (dimensionless). | | * (dimensionless). | |
| * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | | * @param[out] S12 area under the geodesic (meters<sup>2</sup>). | |
| * @return \e a12 arc length of between point 1 and point 2 (degrees). | | * @return \e a12 arc length of between point 1 and point 2 (degrees). | |
| * | | * | |
| * \e lat1 and \e lat2 should be in the range [−90°, 90°]
; \e | | * \e lat1 and \e lat2 should be in the range [−90°, 90°]
; \e | |
| * lon1 and \e lon2 should be in the range [−540°, 540°). | | * lon1 and \e lon2 should be in the range [−540°, 540°). | |
| * The values of \e azi1 and \e azi2 returned are in the range | | * The values of \e azi1 and \e azi2 returned are in the range | |
| * [−180°, 180°). | | * [−180°, 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
|
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = ±(90° − &epsil | |
| * −90° + ε and taking the limit ε → 0 f | | on;) | |
| rom | | * and taking the limit ε → 0+. | |
| * above. | | | |
| * | | * | |
| * The following functions are overloaded versions of GeodesicExact::In
verse | | * The following functions are overloaded versions of GeodesicExact::In
verse | |
| * which omit some of the output parameters. Note, however, that the a
rc | | * which omit some of the output parameters. Note, however, that the a
rc | |
| * length is always computed and returned as the function value. | | * length is always computed and returned as the function value. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Inverse(real lat1, real lon1, real lat2, real lon2, | | Math::real Inverse(real lat1, real lon1, real lat2, real lon2, | |
| real& s12, real& azi1, real& azi2, real& m12, | | real& s12, real& azi1, real& azi2, real& m12, | |
| real& M12, real& M21, real& S12) const throw() { | | real& M12, real& M21, real& S12) const throw() { | |
| return GenInverse(lat1, lon1, lat2, lon2, | | return GenInverse(lat1, lon1, lat2, lon2, | |
| DISTANCE | AZIMUTH | | | DISTANCE | AZIMUTH | | |
| | | | |
End of changes. 4 change blocks. |
| 23 lines changed or deleted | | 20 lines changed or added | |
|
| GeodesicLine.hpp | | GeodesicLine.hpp | |
| | | | |
| skipping to change at line 35 | | skipping to change at line 35 | |
| * GeodesicLine.ArcPosition gives the position of point 2 an arc length \
e | | * GeodesicLine.ArcPosition gives the position of point 2 an arc length \
e | |
| * a12 along the geodesic. | | * a12 along the geodesic. | |
| * | | * | |
| * The default copy constructor and assignment operators work with this | | * The default copy constructor and assignment operators work with this | |
| * class. Similarly, a vector can be used to hold GeodesicLine objects. | | * class. Similarly, a vector can be used to hold GeodesicLine objects. | |
| * | | * | |
| * The calculations are accurate to better than 15 nm (15 nanometers). S
ee | | * The calculations are accurate to better than 15 nm (15 nanometers). S
ee | |
| * Sec. 9 of | | * Sec. 9 of | |
| * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | | * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | |
| * details. The algorithms used by this class are based on series expans
ions | | * details. The algorithms used by this class are based on series expans
ions | |
|
| * using the flattening \e f as a small parameter. These only accurate f | | * using the flattening \e f as a small parameter. These are only accura | |
| or | | te | |
| * |\e f| < 0.02; however reasonably accurate results will be obtained | | * for |<i>f</i>| < 0.02; however reasonably accurate results will be | |
| for | | * obtained for |<i>f</i>| < 0.2. For very eccentric ellipsoids, use | |
| * |\e f| < 0.2. For very eccentric ellipsoids, use GeodesicLineExact | | * GeodesicLineExact instead. | |
| * instead. | | | |
| * | | * | |
| * The algorithms are described in | | * The algorithms are described in | |
| * - C. F. F. Karney, | | * - C. F. F. Karney, | |
| * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * Algorithms for geodesics</a>, | | * Algorithms for geodesics</a>, | |
|
| * J. Geodesy, 2012; | | * J. Geodesy <b>87</b>, 43--55 (2013); | |
| * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * 10.1007/s00190-012-0578-z</a>; | | * 10.1007/s00190-012-0578-z</a>; | |
| * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> | | * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> | |
| * geod-addenda.html</a>. | | * geod-addenda.html</a>. | |
| * . | | * . | |
| * For more information on geodesics see \ref geodesic. | | * For more information on geodesics see \ref geodesic. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-GeodesicLine.cpp | | * \include example-GeodesicLine.cpp | |
| * | | * | |
| | | | |
| skipping to change at line 193 | | skipping to change at line 193 | |
| * and \e M21 | | * and \e M21 | |
| * - \e caps |= GeodesicLine::AREA for the area \e S12 | | * - \e caps |= GeodesicLine::AREA for the area \e S12 | |
| * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the | | * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the | |
| * geodesic to be given in terms of \e s12; without this capability t
he | | * geodesic to be given in terms of \e s12; without this capability t
he | |
| * length can only be specified in terms of arc length. | | * length can only be specified in terms of arc length. | |
| * . | | * . | |
| * The default value of \e caps is GeodesicLine::ALL which turns on all
the | | * The default value of \e caps is GeodesicLine::ALL which turns on all
the | |
| * capabilities. | | * capabilities. | |
| * | | * | |
| * If the point is at a pole, the azimuth is defined by keeping the \e
lon1 | | * If the point is at a pole, the azimuth is defined by keeping the \e
lon1 | |
|
| * fixed and writing \e lat1 = 90° − ε or | | * fixed and writing \e lat1 = ±(90° − ε) and | |
| * −90° + ε and taking the limit ε → 0 f | | * taking the limit ε → 0+. | |
| rom | | | |
| * above. | | | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1, | | GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1, | |
| unsigned caps = ALL) | | unsigned caps = ALL) | |
| throw(); | | throw(); | |
| | | | |
| /** | | /** | |
| * A default constructor. If GeodesicLine::Position is called on the | | * A default constructor. If GeodesicLine::Position is called on the | |
| * resulting object, it returns immediately (without doing any | | * resulting object, it returns immediately (without doing any | |
| * calculations). The object can be set with a call to Geodesic::Line. | | * calculations). The object can be set with a call to Geodesic::Line. | |
| * Use Init() to test whether object is still in this uninitialized sta
te. | | * Use Init() to test whether object is still in this uninitialized sta
te. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| GeodesicLine() throw() : _caps(0U) {} | | GeodesicLine() throw() : _caps(0U) {} | |
| ///@} | | ///@} | |
| | | | |
| /** \name Position in terms of distance | | /** \name Position in terms of distance | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
|
| * Compute the position of point 2 which is a distance \e s12 (meters) | | * Compute the position of point 2 which is a distance \e s12 (meters) | |
| * from point 1. | | from | |
| | | * point 1. | |
| * | | * | |
| * @param[in] s12 distance between point 1 and point 2 (meters); it can
be | | * @param[in] s12 distance between point 1 and point 2 (meters); it can
be | |
|
| * signed. | | * negative. | |
| * @param[out] lat2 latitude of point 2 (degrees). | | * @param[out] lat2 latitude of point 2 (degrees). | |
| * @param[out] lon2 longitude of point 2 (degrees); requires that the | | * @param[out] lon2 longitude of point 2 (degrees); requires that the | |
| * GeodesicLine object was constructed with \e caps |= | | * GeodesicLine object was constructed with \e caps |= | |
| * GeodesicLine::LONGITUDE. | | * GeodesicLine::LONGITUDE. | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] m12 reduced length of geodesic (meters); requires that t
he | | * @param[out] m12 reduced length of geodesic (meters); requires that t
he | |
| * GeodesicLine object was constructed with \e caps |= | | * GeodesicLine object was constructed with \e caps |= | |
| * GeodesicLine::REDUCEDLENGTH. | | * GeodesicLine::REDUCEDLENGTH. | |
| * @param[out] M12 geodesic scale of point 2 relative to point 1 | | * @param[out] M12 geodesic scale of point 2 relative to point 1 | |
| * (dimensionless); requires that the GeodesicLine object was constru
cted | | * (dimensionless); requires that the GeodesicLine object was constru
cted | |
| | | | |
| skipping to change at line 335 | | skipping to change at line 334 | |
| | | | |
| /** \name Position in terms of arc length | | /** \name Position in terms of arc length | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
| * Compute the position of point 2 which is an arc length \e a12 (degre
es) | | * Compute the position of point 2 which is an arc length \e a12 (degre
es) | |
| * from point 1. | | * from point 1. | |
| * | | * | |
| * @param[in] a12 arc length between point 1 and point 2 (degrees); it
can | | * @param[in] a12 arc length between point 1 and point 2 (degrees); it
can | |
|
| * be signed. | | * be negative. | |
| * @param[out] lat2 latitude of point 2 (degrees). | | * @param[out] lat2 latitude of point 2 (degrees). | |
| * @param[out] lon2 longitude of point 2 (degrees); requires that the | | * @param[out] lon2 longitude of point 2 (degrees); requires that the | |
| * GeodesicLine object was constructed with \e caps |= | | * GeodesicLine object was constructed with \e caps |= | |
| * GeodesicLine::LONGITUDE. | | * GeodesicLine::LONGITUDE. | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] s12 distance between point 1 and point 2 (meters); requi
res | | * @param[out] s12 distance between point 1 and point 2 (meters); requi
res | |
| * that the GeodesicLine object was constructed with \e caps |= | | * that the GeodesicLine object was constructed with \e caps |= | |
| * GeodesicLine::DISTANCE. | | * GeodesicLine::DISTANCE. | |
| * @param[out] m12 reduced length of geodesic (meters); requires that t
he | | * @param[out] m12 reduced length of geodesic (meters); requires that t
he | |
| * GeodesicLine object was constructed with \e caps |= | | * GeodesicLine object was constructed with \e caps |= | |
| | | | |
| skipping to change at line 462 | | skipping to change at line 461 | |
| | | | |
| /** | | /** | |
| * The general position function. GeodesicLine::Position and | | * The general position function. GeodesicLine::Position and | |
| * GeodesicLine::ArcPosition are defined in terms of this function. | | * GeodesicLine::ArcPosition are defined in terms of this function. | |
| * | | * | |
| * @param[in] arcmode boolean flag determining the meaning of the secon
d | | * @param[in] arcmode boolean flag determining the meaning of the secon
d | |
| * parameter; if arcmode is false, then the GeodesicLine object must
have | | * parameter; if arcmode is false, then the GeodesicLine object must
have | |
| * been constructed with \e caps |= GeodesicLine::DISTANCE_IN. | | * been constructed with \e caps |= GeodesicLine::DISTANCE_IN. | |
| * @param[in] s12_a12 if \e arcmode is false, this is the distance betw
een | | * @param[in] s12_a12 if \e arcmode is false, this is the distance betw
een | |
| * point 1 and point 2 (meters); otherwise it is the arc length betwe
en | | * point 1 and point 2 (meters); otherwise it is the arc length betwe
en | |
|
| * point 1 and point 2 (degrees); it can be signed. | | * point 1 and point 2 (degrees); it can be negative. | |
| * @param[in] outmask a bitor'ed combination of GeodesicLine::mask valu
es | | * @param[in] outmask a bitor'ed combination of GeodesicLine::mask valu
es | |
| * specifying which of the following parameters should be set. | | * specifying which of the following parameters should be set. | |
| * @param[out] lat2 latitude of point 2 (degrees). | | * @param[out] lat2 latitude of point 2 (degrees). | |
| * @param[out] lon2 longitude of point 2 (degrees); requires that the | | * @param[out] lon2 longitude of point 2 (degrees); requires that the | |
| * GeodesicLine object was constructed with \e caps |= | | * GeodesicLine object was constructed with \e caps |= | |
| * GeodesicLine::LONGITUDE. | | * GeodesicLine::LONGITUDE. | |
| * @param[out] azi2 (forward) azimuth at point 2 (degrees). | | * @param[out] azi2 (forward) azimuth at point 2 (degrees). | |
| * @param[out] s12 distance between point 1 and point 2 (meters); requi
res | | * @param[out] s12 distance between point 1 and point 2 (meters); requi
res | |
| * that the GeodesicLine object was constructed with \e caps |= | | * that the GeodesicLine object was constructed with \e caps |= | |
| * GeodesicLine::DISTANCE. | | * GeodesicLine::DISTANCE. | |
| | | | |
End of changes. 7 change blocks. |
| 16 lines changed or deleted | | 14 lines changed or added | |
|
| Math.hpp | | Math.hpp | |
| | | | |
| skipping to change at line 49 | | skipping to change at line 49 | |
| * float (single precision); 2 (the default) means double; 3 means long dou
ble; | | * float (single precision); 2 (the default) means double; 3 means long dou
ble; | |
| * 4 is reserved for quadruple precision. Nearly all the testing has been | | * 4 is reserved for quadruple precision. Nearly all the testing has been | |
| * carried out with doubles and that's the recommended configuration. In o
rder | | * carried out with doubles and that's the recommended configuration. In o
rder | |
| * for long double to be used, HAVE_LONG_DOUBLE needs to be defined. Note
that | | * for long double to be used, HAVE_LONG_DOUBLE needs to be defined. Note
that | |
| * with Microsoft Visual Studio, long double is the same as double. | | * with Microsoft Visual Studio, long double is the same as double. | |
| **********************************************************************/ | | **********************************************************************/ | |
| # define GEOGRAPHICLIB_PRECISION 2 | | # define GEOGRAPHICLIB_PRECISION 2 | |
| #endif | | #endif | |
| | | | |
| #include <cmath> | | #include <cmath> | |
|
| #include <limits> | | | |
| #include <algorithm> | | #include <algorithm> | |
|
| #include <vector> | | #include <limits> | |
| | | #if defined(_LIBCPP_VERSION) | |
| | | #include <type_traits> | |
| | | #endif | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Mathematical functions needed by %GeographicLib | | * \brief Mathematical functions needed by %GeographicLib | |
| * | | * | |
| * Define mathematical functions in order to localize system dependencies
and | | * Define mathematical functions in order to localize system dependencies
and | |
| * to provide generic versions of the functions. In addition define a re
al | | * to provide generic versions of the functions. In addition define a re
al | |
| * type to be used by %GeographicLib. | | * type to be used by %GeographicLib. | |
| * | | * | |
| | | | |
| skipping to change at line 329 | | skipping to change at line 331 | |
| { return std::cbrt(x); } | | { return std::cbrt(x); } | |
| #else | | #else | |
| static inline double cbrt(double x) throw() { return ::cbrt(x); } | | static inline double cbrt(double x) throw() { return ::cbrt(x); } | |
| static inline float cbrt(float x) throw() { return ::cbrtf(x); } | | static inline float cbrt(float x) throw() { return ::cbrtf(x); } | |
| # if HAVE_LONG_DOUBLE | | # if HAVE_LONG_DOUBLE | |
| static inline long double cbrt(long double x) throw() { return ::cbrtl(
x); } | | static inline long double cbrt(long double x) throw() { return ::cbrtl(
x); } | |
| # endif | | # endif | |
| #endif | | #endif | |
| | | | |
| /** | | /** | |
|
| | | * The error-free sum of two numbers. | |
| | | * | |
| | | * @tparam T the type of the argument and the returned value. | |
| | | * @param[in] u | |
| | | * @param[in] v | |
| | | * @param[out] t the exact error given by (\e u + \e v) - \e s. | |
| | | * @return \e s = round(\e u + \e v). | |
| | | * | |
| | | * See D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B. (Note that \e t ca | |
| | | n be | |
| | | * the same as one of the first two arguments.) | |
| | | ********************************************************************** | |
| | | / | |
| | | template<typename T> static inline T sum(T u, T v, T& t) throw() { | |
| | | volatile T s = u + v; | |
| | | volatile T up = s - v; | |
| | | volatile T vpp = s - up; | |
| | | up -= u; | |
| | | vpp -= v; | |
| | | t = -(up + vpp); | |
| | | // u + v = s + t | |
| | | // = round(u + v) + t | |
| | | return s; | |
| | | } | |
| | | | |
| | | /** | |
| * Normalize an angle (restricted input range). | | * Normalize an angle (restricted input range). | |
| * | | * | |
| * @tparam T the type of the argument and returned value. | | * @tparam T the type of the argument and returned value. | |
| * @param[in] x the angle in degrees. | | * @param[in] x the angle in degrees. | |
| * @return the angle reduced to the range [−180°, | | * @return the angle reduced to the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * \e x must lie in [−540°, 540°). | | * \e x must lie in [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T AngNormalize(T x) throw() | | template<typename T> static inline T AngNormalize(T x) throw() | |
| | | | |
| skipping to change at line 355 | | skipping to change at line 381 | |
| * @param[in] x the angle in degrees. | | * @param[in] x the angle in degrees. | |
| * @return the angle reduced to the range [−180°, | | * @return the angle reduced to the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * The range of \e x is unrestricted. | | * The range of \e x is unrestricted. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T AngNormalize2(T x) throw() | | template<typename T> static inline T AngNormalize2(T x) throw() | |
| { return AngNormalize<T>(std::fmod(x, T(360))); } | | { return AngNormalize<T>(std::fmod(x, T(360))); } | |
| | | | |
| /** | | /** | |
|
| | | * Difference of two angles reduced to [−180°, 180°] | |
| | | * | |
| | | * @tparam T the type of the arguments and returned value. | |
| | | * @param[in] x the first angle in degrees. | |
| | | * @param[in] y the second angle in degrees. | |
| | | * @return \e y − \e x, reduced to the range [−180°, | |
| | | * 180°]. | |
| | | * | |
| | | * \e x and \e y must both lie in [−180°, 180°]. The res | |
| | | ult | |
| | | * is equivalent to computing the difference exactly, reducing it to | |
| | | * (−180°, 180°] and rounding the result. Note that this | |
| | | * prescription allows −180° to be returned (e.g., if \e x is | |
| | | * tiny and negative and \e y = 180°). | |
| | | ********************************************************************** | |
| | | / | |
| | | template<typename T> static inline T AngDiff(T x, T y) throw() { | |
| | | T t, d = sum(-x, y, t); | |
| | | if ((d - T(180)) + t > T(0)) // y - x > 180 | |
| | | d -= T(360); // exact | |
| | | else if ((d + T(180)) + t <= T(0)) // y - x <= -180 | |
| | | d += T(360); // exact | |
| | | return d + t; | |
| | | } | |
| | | | |
| | | #if defined(DOXYGEN) | |
| | | /** | |
| * Test for finiteness. | | * Test for finiteness. | |
| * | | * | |
| * @tparam T the type of the argument. | | * @tparam T the type of the argument. | |
| * @param[in] x | | * @param[in] x | |
| * @return true if number is finite, false if NaN or infinite. | | * @return true if number is finite, false if NaN or infinite. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline bool isfinite(T x) throw() { | | template<typename T> static inline bool isfinite(T x) throw() { | |
|
| #if defined(DOXYGEN) | | | |
| return std::abs(x) <= (std::numeric_limits<T>::max)(); | | return std::abs(x) <= (std::numeric_limits<T>::max)(); | |
|
| | | } | |
| #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH) | | #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH) | |
|
| | | template<typename T> static inline bool isfinite(T x) throw() { | |
| return _finite(double(x)) != 0; | | return _finite(double(x)) != 0; | |
|
| | | } | |
| | | #elif defined(_LIBCPP_VERSION) | |
| | | // libc++ implements std::isfinite() as a template that only allows | |
| | | // floating-point types. isfinite is invoked by Utility::str to format | |
| | | // numbers conveniently and this allows integer arguments, so we need t | |
| | | o | |
| | | // allow Math::isfinite to work on integers. | |
| | | template<typename T> static inline | |
| | | typename std::enable_if<std::is_floating_point<T>::value, bool>::type | |
| | | isfinite(T x) throw() { | |
| | | return std::isfinite(x); | |
| | | } | |
| | | template<typename T> static inline | |
| | | typename std::enable_if<!std::is_floating_point<T>::value, bool>::type | |
| | | isfinite(T /*x*/) throw() { | |
| | | return true; | |
| | | } | |
| #else | | #else | |
|
| | | template<typename T> static inline bool isfinite(T x) throw() { | |
| return std::isfinite(x); | | return std::isfinite(x); | |
|
| #endif | | | |
| } | | } | |
|
| | | #endif | |
| | | | |
| /** | | /** | |
| * The NaN (not a number) | | * The NaN (not a number) | |
| * | | * | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return NaN if available, otherwise return the max real of type T. | | * @return NaN if available, otherwise return the max real of type T. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T NaN() throw() { | | template<typename T> static inline T NaN() throw() { | |
| return std::numeric_limits<T>::has_quiet_NaN ? | | return std::numeric_limits<T>::has_quiet_NaN ? | |
| std::numeric_limits<T>::quiet_NaN() : | | std::numeric_limits<T>::quiet_NaN() : | |
| | | | |
End of changes. 11 change blocks. |
| 4 lines changed or deleted | | 78 lines changed or added | |
|