| AlbersEqualArea.hpp | | AlbersEqualArea.hpp | |
| | | | |
| skipping to change at line 63 | | skipping to change at line 63 | |
| * Example of use: | | * Example of use: | |
| * \include example-AlbersEqualArea.cpp | | * \include example-AlbersEqualArea.cpp | |
| * | | * | |
| * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility | | * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility | |
| * providing access to the functionality of LambertConformalConic and | | * providing access to the functionality of LambertConformalConic and | |
| * AlbersEqualArea. | | * AlbersEqualArea. | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT AlbersEqualArea { | | class GEOGRAPHICLIB_EXPORT AlbersEqualArea { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| | | real eps_, epsx_, epsx2_, tol_, tol0_; | |
| real _a, _f, _fm, _e2, _e, _e2m, _qZ, _qx; | | real _a, _f, _fm, _e2, _e, _e2m, _qZ, _qx; | |
| real _sign, _lat0, _k0; | | real _sign, _lat0, _k0; | |
| real _n0, _m02, _nrho0, _k2, _txi0, _scxi0, _sxi0; | | real _n0, _m02, _nrho0, _k2, _txi0, _scxi0, _sxi0; | |
|
| static const real eps_; | | | |
| static const real epsx_; | | | |
| static const real epsx2_; | | | |
| static const real tol_; | | | |
| static const real tol0_; | | | |
| static const real ahypover_; | | | |
| static const int numit_ = 5; // Newton iterations in Reverse | | static const int numit_ = 5; // Newton iterations in Reverse | |
| static const int numit0_ = 20; // Newton iterations in Init | | static const int numit0_ = 20; // Newton iterations in Init | |
| static inline real hyp(real x) { return Math::hypot(real(1), x); } | | static inline real hyp(real x) { return Math::hypot(real(1), x); } | |
| // atanh( e * x)/ e if f > 0 | | // atanh( e * x)/ e if f > 0 | |
| // atan (sqrt(-e2) * x)/sqrt(-e2) if f < 0 | | // atan (sqrt(-e2) * x)/sqrt(-e2) if f < 0 | |
| // x if f = 0 | | // x if f = 0 | |
| inline real atanhee(real x) const { | | inline real atanhee(real x) const { | |
|
| | | using std::atan2; using std::abs; | |
| return _f > 0 ? Math::atanh(_e * x)/_e : | | return _f > 0 ? Math::atanh(_e * x)/_e : | |
| // We only invoke atanhee in txif for positive latitude. Then x is | | // We only invoke atanhee in txif for positive latitude. Then x is | |
| // only negative for very prolate ellipsoids (_b/_a >= sqrt(2)) and
we | | // only negative for very prolate ellipsoids (_b/_a >= sqrt(2)) and
we | |
| // still need to return a positive result in this case; hence the n
eed | | // still need to return a positive result in this case; hence the n
eed | |
| // for the call to atan2. | | // for the call to atan2. | |
|
| (_f < 0 ? (std::atan2(_e * std::abs(x), x < 0 ? -1 : 1)/_e) : x); | | (_f < 0 ? (atan2(_e * abs(x), x < 0 ? -1 : 1)/_e) : x); | |
| } | | } | |
| // return atanh(sqrt(x))/sqrt(x) - 1, accurate for small x | | // return atanh(sqrt(x))/sqrt(x) - 1, accurate for small x | |
| static real atanhxm1(real x); | | static real atanhxm1(real x); | |
| | | | |
| // Divided differences | | // Divided differences | |
| // Definition: Df(x,y) = (f(x)-f(y))/(x-y) | | // Definition: Df(x,y) = (f(x)-f(y))/(x-y) | |
| // See: | | // See: | |
| // W. M. Kahan and R. J. Fateman, | | // W. M. Kahan and R. J. Fateman, | |
| // Symbolic computation of divided differences, | | // Symbolic computation of divided differences, | |
| // SIGSAM Bull. 33(3), 7-28 (1999) | | // SIGSAM Bull. 33(3), 7-28 (1999) | |
| | | | |
| skipping to change at line 115 | | skipping to change at line 111 | |
| // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^
2)) | | // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^
2)) | |
| static inline real Dsn(real x, real y, real sx, real sy) { | | static inline real Dsn(real x, real y, real sx, real sy) { | |
| // sx = x/hyp(x) | | // sx = x/hyp(x) | |
| real t = x * y; | | real t = x * y; | |
| return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) : | | return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) : | |
| (x - y != 0 ? (sx - sy) / (x - y) : 1); | | (x - y != 0 ? (sx - sy) / (x - y) : 1); | |
| } | | } | |
| // Datanhee(x,y) = atanhee((x-y)/(1-e^2*x*y))/(x-y) | | // Datanhee(x,y) = atanhee((x-y)/(1-e^2*x*y))/(x-y) | |
| inline real Datanhee(real x, real y) const { | | inline real Datanhee(real x, real y) const { | |
| real t = x - y, d = 1 - _e2 * x * y; | | real t = x - y, d = 1 - _e2 * x * y; | |
|
| return t != 0 ? atanhee(t / d) / t : 1 / d; | | return t ? atanhee(t / d) / t : 1 / d; | |
| } | | } | |
| // DDatanhee(x,y) = (Datanhee(1,y) - Datanhee(1,x))/(y-x) | | // DDatanhee(x,y) = (Datanhee(1,y) - Datanhee(1,x))/(y-x) | |
| real DDatanhee(real x, real y) const; | | real DDatanhee(real x, real y) const; | |
| void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1); | | void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1); | |
| real txif(real tphi) const; | | real txif(real tphi) const; | |
| real tphif(real txi) const; | | real tphif(real txi) const; | |
| | | | |
| friend class Ellipsoid; // For access to txif, tphif, etc. | | friend class Ellipsoid; // For access to txif, tphif, etc. | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor with a single standard parallel. | | * Constructor with a single standard parallel. | |
| * | | * | |
| * @param[in] a equatorial radius of ellipsoid (meters). | | * @param[in] a equatorial radius of ellipsoid (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] stdlat standard parallel (degrees), the circle of tangenc
y. | | * @param[in] stdlat standard parallel (degrees), the circle of tangenc
y. | |
| * @param[in] k0 azimuthal scale on the standard parallel. | | * @param[in] k0 azimuthal scale on the standard parallel. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k0 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k0 is | |
| * not positive. | | * not positive. | |
| * @exception GeographicErr if \e stdlat is not in [−90°, | | * @exception GeographicErr if \e stdlat is not in [−90°, | |
| * 90°]. | | * 90°]. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| AlbersEqualArea(real a, real f, real stdlat, real k0); | | AlbersEqualArea(real a, real f, real stdlat, real k0); | |
| | | | |
| /** | | /** | |
| * Constructor with two standard parallels. | | * Constructor with two standard parallels. | |
| * | | * | |
| * @param[in] a equatorial radius of ellipsoid (meters). | | * @param[in] a equatorial radius of ellipsoid (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] stdlat1 first standard parallel (degrees). | | * @param[in] stdlat1 first standard parallel (degrees). | |
| * @param[in] stdlat2 second standard parallel (degrees). | | * @param[in] stdlat2 second standard parallel (degrees). | |
| * @param[in] k1 azimuthal scale on the standard parallels. | | * @param[in] k1 azimuthal scale on the standard parallels. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k1 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k1 is | |
| * not positive. | | * not positive. | |
| * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | | * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | |
| * [−90°, 90°], or if \e stdlat1 and \e stdlat2 are | | * [−90°, 90°], or if \e stdlat1 and \e stdlat2 are | |
| * opposite poles. | | * opposite poles. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| AlbersEqualArea(real a, real f, real stdlat1, real stdlat2, real k1); | | AlbersEqualArea(real a, real f, real stdlat1, real stdlat2, real k1); | |
| | | | |
| /** | | /** | |
| * Constructor with two standard parallels specified by sines and cosin
es. | | * Constructor with two standard parallels specified by sines and cosin
es. | |
| * | | * | |
| * @param[in] a equatorial radius of ellipsoid (meters). | | * @param[in] a equatorial radius of ellipsoid (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] sinlat1 sine of first standard parallel. | | * @param[in] sinlat1 sine of first standard parallel. | |
| * @param[in] coslat1 cosine of first standard parallel. | | * @param[in] coslat1 cosine of first standard parallel. | |
| * @param[in] sinlat2 sine of second standard parallel. | | * @param[in] sinlat2 sine of second standard parallel. | |
| * @param[in] coslat2 cosine of second standard parallel. | | * @param[in] coslat2 cosine of second standard parallel. | |
| * @param[in] k1 azimuthal scale on the standard parallels. | | * @param[in] k1 azimuthal scale on the standard parallels. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k1 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k1 is | |
| * not positive. | | * not positive. | |
| * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | | * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | |
| * [−90°, 90°], or if \e stdlat1 and \e stdlat2 are | | * [−90°, 90°], or if \e stdlat1 and \e stdlat2 are | |
| * opposite poles. | | * opposite poles. | |
| * | | * | |
| * This allows parallels close to the poles to be specified accurately. | | * This allows parallels close to the poles to be specified accurately. | |
| * This routine computes the latitude of origin and the azimuthal scale
at | | * This routine computes the latitude of origin and the azimuthal scale
at | |
| * this latitude. If \e dlat = abs(\e lat2 − \e lat1) ≤ 160&d
eg;, | | * this latitude. If \e dlat = abs(\e lat2 − \e lat1) ≤ 160&d
eg;, | |
| * then the error in the latitude of origin is less than 4.5 × | | * then the error in the latitude of origin is less than 4.5 × | |
| * 10<sup>−14</sup>d;. | | * 10<sup>−14</sup>d;. | |
| | | | |
| skipping to change at line 311 | | skipping to change at line 307 | |
| * on the latitude of origin. | | * on the latitude of origin. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real CentralScale() const { return _k0; } | | Math::real CentralScale() const { return _k0; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid,
\e | | * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid,
\e | |
| * stdlat = 0, and \e k0 = 1. This degenerates to the cylindrical equa
l | | * stdlat = 0, and \e k0 = 1. This degenerates to the cylindrical equa
l | |
| * area projection. | | * area projection. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const AlbersEqualArea CylindricalEqualArea; | | static const AlbersEqualArea& CylindricalEqualArea(); | |
| | | | |
| /** | | /** | |
| * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid,
\e | | * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid,
\e | |
| * stdlat = 90°, and \e k0 = 1. This degenerates to the | | * stdlat = 90°, and \e k0 = 1. This degenerates to the | |
| * Lambert azimuthal equal area projection. | | * Lambert azimuthal equal area projection. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const AlbersEqualArea AzimuthalEqualAreaNorth; | | static const AlbersEqualArea& AzimuthalEqualAreaNorth(); | |
| | | | |
| /** | | /** | |
| * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid,
\e | | * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid,
\e | |
| * stdlat = −90°, and \e k0 = 1. This degenerates to the | | * stdlat = −90°, and \e k0 = 1. This degenerates to the | |
| * Lambert azimuthal equal area projection. | | * Lambert azimuthal equal area projection. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const AlbersEqualArea AzimuthalEqualAreaSouth; | | static const AlbersEqualArea& AzimuthalEqualAreaSouth(); | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_ALBERSEQUALAREA_HPP | | #endif // GEOGRAPHICLIB_ALBERSEQUALAREA_HPP | |
| | | | |
End of changes. 14 change blocks. |
| 23 lines changed or deleted | | 16 lines changed or added | |
|
| CassiniSoldner.hpp | | CassiniSoldner.hpp | |
| | | | |
| skipping to change at line 52 | | skipping to change at line 52 | |
| * path. | | * path. | |
| * | | * | |
| * Because of the properties of geodesics, the (\e x, \e y) grid is | | * Because of the properties of geodesics, the (\e x, \e y) grid is | |
| * orthogonal. The scale in the easting direction is unity. The scale,
\e | | * orthogonal. The scale in the easting direction is unity. The scale,
\e | |
| * k, in the northing direction is unity on the central meridian and | | * k, in the northing direction is unity on the central meridian and | |
| * increases away from the central meridian. The projection routines ret
urn | | * increases away from the central meridian. The projection routines ret
urn | |
| * \e azi, the true bearing of the easting direction, and \e rk = 1/\e k,
the | | * \e azi, the true bearing of the easting direction, and \e rk = 1/\e k,
the | |
| * reciprocal of the scale in the northing direction. | | * reciprocal of the scale in the northing direction. | |
| * | | * | |
| * The conversions all take place using a Geodesic object (by default | | * The conversions all take place using a Geodesic object (by default | |
|
| * Geodesic::WGS84). For more information on geodesics see \ref geodesic
. | | * Geodesic::WGS84()). For more information on geodesics see \ref geodes
ic. | |
| * The determination of (\e lat1, \e lon1) in the forward projection is b
y | | * The determination of (\e lat1, \e lon1) in the forward projection is b
y | |
| * solving the inverse geodesic problem for (\e lat, \e lon) and its twin | | * solving the inverse geodesic problem for (\e lat, \e lon) and its twin | |
| * obtained by reflection in the meridional plane. The scale is found by | | * obtained by reflection in the meridional plane. The scale is found by | |
| * determining where two neighboring geodesics intersecting the central | | * determining where two neighboring geodesics intersecting the central | |
| * meridian at \e lat1 and \e lat1 + \e dlat1 intersect and taking the ra
tio | | * meridian at \e lat1 and \e lat1 + \e dlat1 intersect and taking the ra
tio | |
| * of the reduced lengths for the two geodesics between that point and, | | * of the reduced lengths for the two geodesics between that point and, | |
| * respectively, (\e lat1, \e lon1) and (\e lat, \e lon). | | * respectively, (\e lat1, \e lon1) and (\e lat, \e lon). | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-CassiniSoldner.cpp | | * \include example-CassiniSoldner.cpp | |
| * | | * | |
| * <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utili
ty | | * <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utili
ty | |
| * providing access to the functionality of AzimuthalEquidistant, Gnomoni
c, | | * providing access to the functionality of AzimuthalEquidistant, Gnomoni
c, | |
| * and CassiniSoldner. | | * and CassiniSoldner. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT CassiniSoldner { | | class GEOGRAPHICLIB_EXPORT CassiniSoldner { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| | | real eps1_, tiny_; | |
| Geodesic _earth; | | Geodesic _earth; | |
| GeodesicLine _meridian; | | GeodesicLine _meridian; | |
| real _sbet0, _cbet0; | | real _sbet0, _cbet0; | |
|
| static const real eps1_; | | | |
| static const real tiny_; | | | |
| static const unsigned maxit_ = 10; | | static const unsigned maxit_ = 10; | |
| | | | |
| // The following private helper functions are copied from Geodesic. | | // The following private helper functions are copied from Geodesic. | |
| static inline real AngRound(real x) { | | static inline real AngRound(real x) { | |
| // 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). | |
|
| | | using std::abs; | |
| const real z = 1/real(16); | | const real z = 1/real(16); | |
|
| volatile real y = std::abs(x); | | GEOGRAPHICLIB_VOLATILE real y = 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) { | | static inline void SinCosNorm(real& sinx, real& cosx) { | |
| real r = Math::hypot(sinx, cosx); | | real r = Math::hypot(sinx, cosx); | |
| sinx /= r; | | sinx /= r; | |
| cosx /= r; | | cosx /= r; | |
| } | | } | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor for CassiniSoldner. | | * Constructor for CassiniSoldner. | |
| * | | * | |
| * @param[in] earth the Geodesic object to use for geodesic calculation
s. | | * @param[in] earth the Geodesic object to use for geodesic calculation
s. | |
| * By default this uses the WGS84 ellipsoid. | | * By default this uses the WGS84 ellipsoid. | |
| * | | * | |
| * This constructor makes an "uninitialized" object. Call Reset to set
the | | * This constructor makes an "uninitialized" object. Call Reset to set
the | |
| * central latitude and longitude, prior to calling Forward and Reverse
. | | * central latitude and longitude, prior to calling Forward and Reverse
. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| explicit CassiniSoldner(const Geodesic& earth = Geodesic::WGS84) | | explicit CassiniSoldner(const Geodesic& earth = Geodesic::WGS84()); | |
| : _earth(earth) {} | | | |
| | | | |
| /** | | /** | |
| * Constructor for CassiniSoldner specifying a center point. | | * Constructor for CassiniSoldner specifying a center point. | |
| * | | * | |
| * @param[in] lat0 latitude of center point of projection (degrees). | | * @param[in] lat0 latitude of center point of projection (degrees). | |
| * @param[in] lon0 longitude of center point of projection (degrees). | | * @param[in] lon0 longitude of center point of projection (degrees). | |
| * @param[in] earth the Geodesic object to use for geodesic calculation
s. | | * @param[in] earth the Geodesic object to use for geodesic calculation
s. | |
| * By default this uses the WGS84 ellipsoid. | | * By default this uses the WGS84 ellipsoid. | |
| * | | * | |
| * \e lat0 should be in the range [−90°, 90°] and \e | | * \e lat0 should be in the range [−90°, 90°] and \e | |
| * lon0 should be in the range [−540°, 540°). | | * lon0 should be in the range [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| CassiniSoldner(real lat0, real lon0, | | CassiniSoldner(real lat0, real lon0, | |
|
| const Geodesic& earth = Geodesic::WGS84) | | const Geodesic& earth = Geodesic::WGS84()); | |
| : _earth(earth) { | | | |
| Reset(lat0, lon0); | | | |
| } | | | |
| | | | |
| /** | | /** | |
| * Set the central point of the projection | | * Set the central point of the projection | |
| * | | * | |
| * @param[in] lat0 latitude of center point of projection (degrees). | | * @param[in] lat0 latitude of center point of projection (degrees). | |
| * @param[in] lon0 longitude of center point of projection (degrees). | | * @param[in] lon0 longitude of center point of projection (degrees). | |
| * | | * | |
| * \e lat0 should be in the range [−90°, 90°] and \e | | * \e lat0 should be in the range [−90°, 90°] and \e | |
| * lon0 should be in the range [−540°, 540°). | | * lon0 should be in the range [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
End of changes. 7 change blocks. |
| 10 lines changed or deleted | | 6 lines changed or added | |
|
| Constants.hpp | | Constants.hpp | |
| | | | |
| skipping to change at line 16 | | skipping to change at line 16 | |
| * under the MIT/X11 License. For more information, see | | * under the MIT/X11 License. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP) | | #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP) | |
| #define GEOGRAPHICLIB_CONSTANTS_HPP 1 | | #define GEOGRAPHICLIB_CONSTANTS_HPP 1 | |
| | | | |
| #include <GeographicLib/Config.h> | | #include <GeographicLib/Config.h> | |
| | | | |
| /** | | /** | |
|
| | | * @relates GeographicLib::Constants | |
| | | * Pack the version components into a single integer. | |
| | | **********************************************************************/ | |
| | | #define GEOGRAPHICLIB_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c) | |
| | | ) | |
| | | | |
| | | /** | |
| | | * @relates GeographicLib::Constants | |
| | | * The version of GeographicLib as a single integer, packed as MMmmmmpp whe | |
| | | re | |
| | | * MM is the major version, mmmm is the minor version, and pp is the patch | |
| | | * level. | |
| | | **********************************************************************/ | |
| | | #define GEOGRAPHICLIB_VERSION \ | |
| | | GEOGRAPHICLIB_VERSION_NUM(GEOGRAPHICLIB_VERSION_MAJOR, \ | |
| | | GEOGRAPHICLIB_VERSION_MINOR, \ | |
| | | GEOGRAPHICLIB_VERSION_PATCH) | |
| | | | |
| | | /** | |
| | | * @relates GeographicLib::Constants | |
| * A compile-time assert. Use C++11 static_assert, if available. | | * A compile-time assert. Use C++11 static_assert, if available. | |
| **********************************************************************/ | | **********************************************************************/ | |
|
| #if !defined(STATIC_ASSERT) | | #if !defined(GEOGRAPHICLIB_STATIC_ASSERT) | |
| # if __cplusplus >= 201103 | | # if __cplusplus >= 201103 | |
|
| # define STATIC_ASSERT static_assert | | # define GEOGRAPHICLIB_STATIC_ASSERT static_assert | |
| # elif defined(__GXX_EXPERIMENTAL_CXX0X__) | | # elif defined(__GXX_EXPERIMENTAL_CXX0X__) | |
|
| # define STATIC_ASSERT static_assert | | # define GEOGRAPHICLIB_STATIC_ASSERT static_assert | |
| # elif defined(_MSC_VER) && _MSC_VER >= 1600 | | # elif defined(_MSC_VER) && _MSC_VER >= 1600 | |
| // For reference, here is a table of Visual Studio and _MSC_VER | | // For reference, here is a table of Visual Studio and _MSC_VER | |
| // correspondences: | | // correspondences: | |
| // | | // | |
| // _MSC_VER Visual Studio | | // _MSC_VER Visual Studio | |
| // 1300 vc7 | | // 1300 vc7 | |
| // 1311 vc7.1 (2003) | | // 1311 vc7.1 (2003) | |
| // 1400 vc8 (2005) | | // 1400 vc8 (2005) | |
| // 1500 vc9 (2008) | | // 1500 vc9 (2008) | |
| // 1600 vc10 (2010) | | // 1600 vc10 (2010) | |
| // 1700 vc11 (2012) | | // 1700 vc11 (2012) | |
| // 1800 vc12 (2013) | | // 1800 vc12 (2013) | |
|
| # define STATIC_ASSERT static_assert | | # define GEOGRAPHICLIB_STATIC_ASSERT static_assert | |
| # else | | # else | |
|
| # define STATIC_ASSERT(cond,reason) \ | | # define GEOGRAPHICLIB_STATIC_ASSERT(cond,reason) \ | |
| { enum{ STATIC_ASSERT_ENUM = 1/int(cond) }; } | | { enum{ GEOGRAPHICLIB_STATIC_ASSERT_ENUM = 1/int(cond) }; } | |
| # endif | | # endif | |
| #endif | | #endif | |
| | | | |
| #if defined(_MSC_VER) && defined(GEOGRAPHICLIB_SHARED_LIB) && \ | | #if defined(_MSC_VER) && defined(GEOGRAPHICLIB_SHARED_LIB) && \ | |
| GEOGRAPHICLIB_SHARED_LIB | | GEOGRAPHICLIB_SHARED_LIB | |
| # if GEOGRAPHICLIB_SHARED_LIB > 1 | | # if GEOGRAPHICLIB_SHARED_LIB > 1 | |
| # error GEOGRAPHICLIB_SHARED_LIB must be 0 or 1 | | # error GEOGRAPHICLIB_SHARED_LIB must be 0 or 1 | |
| # elif defined(GeographicLib_EXPORTS) | | # elif defined(GeographicLib_EXPORTS) | |
| # define GEOGRAPHICLIB_EXPORT __declspec(dllexport) | | # define GEOGRAPHICLIB_EXPORT __declspec(dllexport) | |
| # else | | # else | |
| | | | |
| skipping to change at line 86 | | skipping to change at line 104 | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT Constants { | | class GEOGRAPHICLIB_EXPORT Constants { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| Constants(); // Disable constructor | | Constants(); // Disable constructor | |
| | | | |
| public: | | public: | |
| /** | | /** | |
| * A synonym for Math::degree<real>(). | | * A synonym for Math::degree<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real degree() { return Math::degree<real>(); } | | static inline Math::real degree() { return Math::degree(); } | |
| /** | | /** | |
| * @return the number of radians in an arcminute. | | * @return the number of radians in an arcminute. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real arcminute() | | static inline Math::real arcminute() | |
|
| { return Math::degree<real>() / 60; } | | { return Math::degree() / 60; } | |
| /** | | /** | |
| * @return the number of radians in an arcsecond. | | * @return the number of radians in an arcsecond. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real arcsecond() | | static inline Math::real arcsecond() | |
|
| { return Math::degree<real>() / 3600; } | | { return Math::degree() / 3600; } | |
| | | | |
| /** \name Ellipsoid parameters | | /** \name Ellipsoid parameters | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the equatorial radius of WGS84 ellipsoid (6378137 m). | | * @return the equatorial radius of WGS84 ellipsoid (6378137 m). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T WGS84_a() | | template<typename T> static inline T WGS84_a() | |
|
| { return T(6378137) * meter<T>(); } | | { return 6378137 * meter<T>(); } | |
| /** | | /** | |
| * A synonym for WGS84_a<real>(). | | * A synonym for WGS84_a<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real WGS84_a() { return WGS84_a<real>(); } | | static inline Math::real WGS84_a() { return WGS84_a<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the flattening of WGS84 ellipsoid (1/298.257223563). | | * @return the flattening of WGS84 ellipsoid (1/298.257223563). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T WGS84_f() | | template<typename T> static inline T WGS84_f() | |
|
| { return T(1) / ( T(298) + T(257223563) / T(1000000000) ); } | | { return 1 / ( T(298257223563LL) / 1000000000 ); } | |
| /** | | /** | |
| * A synonym for WGS84_f<real>(). | | * A synonym for WGS84_f<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real WGS84_f() { return WGS84_f<real>(); } | | static inline Math::real WGS84_f() { return WGS84_f<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the gravitational constant of the WGS84 ellipsoid, \e GM, in | | * @return the gravitational constant of the WGS84 ellipsoid, \e GM, in | |
| * m<sup>3</sup> s<sup>−2</sup>. | | * m<sup>3</sup> s<sup>−2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T WGS84_GM() | | template<typename T> static inline T WGS84_GM() | |
|
| { return T(3986004) * T(100000000) + T(41800000); } | | { return T(3986004) * 100000000 + 41800000; } | |
| | | /** | |
| | | * A synonym for WGS84_GM<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real WGS84_GM() { return WGS84_GM<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the angular velocity of the WGS84 ellipsoid, ω, in rad | | * @return the angular velocity of the WGS84 ellipsoid, ω, in rad | |
| * s<sup>−1</sup>. | | * s<sup>−1</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T WGS84_omega() | | template<typename T> static inline T WGS84_omega() | |
|
| { return T(7292115) / (T(1000000) * T(100000)); } | | { return 7292115 / (T(1000000) * 100000); } | |
| | | /** | |
| | | * A synonym for WGS84_omega<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real WGS84_omega() { return WGS84_omega<real>(); } | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return the reciprocal flattening of WGS84 ellipsoid. | | * @return the reciprocal flattening of WGS84 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T WGS84_r() | | template<typename T> static inline T WGS84_r() | |
| { return 1/WGS84_f<T>(); } | | { return 1/WGS84_f<T>(); } | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * A synonym for WGS84_r<real>(). | | * A synonym for WGS84_r<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real WGS84_r() { return WGS84_r<real>(); } | | static inline Math::real WGS84_r() { return WGS84_r<real>(); } | |
| /// \endcond | | /// \endcond | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the equatorial radius of GRS80 ellipsoid, \e a, in m. | | * @return the equatorial radius of GRS80 ellipsoid, \e a, in m. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T GRS80_a() | | template<typename T> static inline T GRS80_a() | |
|
| { return T(6378137); } | | { return 6378137 * meter<T>(); } | |
| | | /** | |
| | | * A synonym for GRS80_a<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real GRS80_a() { return GRS80_a<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the gravitational constant of the GRS80 ellipsoid, \e GM, in | | * @return the gravitational constant of the GRS80 ellipsoid, \e GM, in | |
| * m<sup>3</sup> s<sup>−2</sup>. | | * m<sup>3</sup> s<sup>−2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T GRS80_GM() | | template<typename T> static inline T GRS80_GM() | |
|
| { return T(3986005) * T(100000000); } | | { return T(3986005) * 100000000; } | |
| | | /** | |
| | | * A synonym for GRS80_GM<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real GRS80_GM() { return GRS80_GM<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the angular velocity of the GRS80 ellipsoid, ω, in rad | | * @return the angular velocity of the GRS80 ellipsoid, ω, in rad | |
| * s<sup>−1</sup>. | | * s<sup>−1</sup>. | |
| * | | * | |
| * This is about 2 π 366.25 / (365.25 × 24 × 3600) rad | | * This is about 2 π 366.25 / (365.25 × 24 × 3600) rad | |
| * s<sup>−1</sup>. 365.25 is the number of days in a Julian year
and | | * s<sup>−1</sup>. 365.25 is the number of days in a Julian year
and | |
| * 365.35/366.25 converts from solar days to sidereal days. Using the | | * 365.35/366.25 converts from solar days to sidereal days. Using the | |
| * number of days in a Gregorian year (365.2425) results in a worse | | * number of days in a Gregorian year (365.2425) results in a worse | |
| * approximation (because the Gregorian year includes the precession of
the | | * approximation (because the Gregorian year includes the precession of
the | |
| * earth's axis). | | * earth's axis). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T GRS80_omega() | | template<typename T> static inline T GRS80_omega() | |
|
| { return T(7292115) / (T(1000000) * T(100000)); } | | { return 7292115 / (T(1000000) * 100000); } | |
| | | /** | |
| | | * A synonym for GRS80_omega<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real GRS80_omega() { return GRS80_omega<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the dynamical form factor of the GRS80 ellipsoid, | | * @return the dynamical form factor of the GRS80 ellipsoid, | |
| * <i>J</i><sub>2</sub>. | | * <i>J</i><sub>2</sub>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T GRS80_J2() | | template<typename T> static inline T GRS80_J2() | |
|
| { return T(108263) / T(100000000); } | | { return T(108263) / 100000000; } | |
| | | /** | |
| | | * A synonym for GRS80_J2<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real GRS80_J2() { return GRS80_J2<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the central scale factor for UTM (0.9996). | | * @return the central scale factor for UTM (0.9996). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T UTM_k0() | | template<typename T> static inline T UTM_k0() | |
|
| {return T(9996) / T(10000); } | | {return T(9996) / 10000; } | |
| /** | | /** | |
| * A synonym for UTM_k0<real>(). | | * A synonym for UTM_k0<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real UTM_k0() { return UTM_k0<real>(); } | | static inline Math::real UTM_k0() { return UTM_k0<real>(); } | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the central scale factor for UPS (0.994). | | * @return the central scale factor for UPS (0.994). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T UPS_k0() | | template<typename T> static inline T UPS_k0() | |
|
| { return T(994) / T(1000); } | | { return T(994) / 1000; } | |
| /** | | /** | |
| * A synonym for UPS_k0<real>(). | | * A synonym for UPS_k0<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real UPS_k0() { return UPS_k0<real>(); } | | static inline Math::real UPS_k0() { return UPS_k0<real>(); } | |
| ///@} | | ///@} | |
| | | | |
| /** \name SI units | | /** \name SI units | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| | | | |
| skipping to change at line 269 | | skipping to change at line 311 | |
| { return nauticalmile() * nauticalmile(); } | | { return nauticalmile() * nauticalmile(); } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Anachronistic British units | | /** \name Anachronistic British units | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return the number of meters in an international foot. | | * @return the number of meters in an international foot. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real foot() | | static inline Math::real foot() | |
|
| { return real(0.0254L) * 12 * meter<real>(); } | | { return real(254 * 12) / 10000 * meter<real>(); } | |
| /** | | /** | |
| * @return the number of meters in a yard. | | * @return the number of meters in a yard. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real yard() { return 3 * foot(); } | | static inline Math::real yard() { return 3 * foot(); } | |
| /** | | /** | |
| * @return the number of meters in a fathom. | | * @return the number of meters in a fathom. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real fathom() { return 2 * yard(); } | | static inline Math::real fathom() { return 2 * yard(); } | |
| /** | | /** | |
| * @return the number of meters in a chain. | | * @return the number of meters in a chain. | |
| | | | |
| skipping to change at line 307 | | skipping to change at line 349 | |
| static inline Math::real square_mile() { return mile() * mile(); } | | static inline Math::real square_mile() { return mile() * mile(); } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Anachronistic US units | | /** \name Anachronistic US units | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return the number of meters in a US survey foot. | | * @return the number of meters in a US survey foot. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real surveyfoot() | | static inline Math::real surveyfoot() | |
|
| { return real(1200) / real(3937) * meter<real>(); } | | { return real(1200) / 3937 * meter<real>(); } | |
| ///@} | | ///@} | |
| }; | | }; | |
| | | | |
| /** | | /** | |
| * \brief Exception handling for %GeographicLib | | * \brief Exception handling for %GeographicLib | |
| * | | * | |
| * A class to handle exceptions. It's derived from std::runtime_error so
it | | * A class to handle exceptions. It's derived from std::runtime_error so
it | |
| * can be caught by the usual catch clauses. | | * can be caught by the usual catch clauses. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| | | | |
End of changes. 21 change blocks. |
| 21 lines changed or deleted | | 71 lines changed or added | |
|
| Ellipsoid.hpp | | Ellipsoid.hpp | |
| | | | |
| skipping to change at line 43 | | skipping to change at line 43 | |
| * should be limited to −3 < \e f < 3/4 (i.e., 1/4 < b/a < 4). | | * should be limited to −3 < \e f < 3/4 (i.e., 1/4 < b/a < 4). | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-Ellipsoid.cpp | | * \include example-Ellipsoid.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT Ellipsoid { | | class GEOGRAPHICLIB_EXPORT Ellipsoid { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| static const int numit_ = 10; | | static const int numit_ = 10; | |
|
| static const real stol_; | | real stol_; | |
| real _a, _f, _f1, _f12, _e2, _e12, _n, _b; | | real _a, _f, _f1, _f12, _e2, _e, _e12, _n, _b; | |
| TransverseMercator _tm; | | TransverseMercator _tm; | |
| EllipticFunction _ell; | | EllipticFunction _ell; | |
| AlbersEqualArea _au; | | AlbersEqualArea _au; | |
|
| static real tand(real x) { | | static inline real tand(real x) { | |
| | | using std::abs; using std::tan; | |
| return | | return | |
|
| std::abs(x) == real(90) ? (x < 0 ? | | abs(x) == real(90) ? (x < 0 ? | |
| - TransverseMercator::overflow_ | | - TransverseMercator::overflow() | |
| : TransverseMercator::overflow_) : | | : TransverseMercator::overflow()) : | |
| std::tan(x * Math::degree<real>()); | | tan(x * Math::degree()); | |
| } | | } | |
|
| static real atand(real x) | | static inline real atand(real x) | |
| { return std::atan(x) / Math::degree<real>(); } | | { using std::atan; return atan(x) / Math::degree(); } | |
| | | | |
|
| | | // These are the alpha and beta coefficients in the Krueger series from | |
| | | // TransverseMercator. Thy are used by RhumbSolve to compute | |
| | | // (psi2-psi1)/(mu2-mu1). | |
| | | const Math::real* ConformalToRectifyingCoeffs() const { return _tm._alp | |
| | | ; } | |
| | | const Math::real* RectifyingToConformalCoeffs() const { return _tm._bet | |
| | | ; } | |
| | | friend class Rhumb; friend class RhumbLine; | |
| public: | | public: | |
| /** \name Constructor | | /** \name Constructor | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | * @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. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Ellipsoid(real a, real f); | | Ellipsoid(real a, real f); | |
| ///@} | | ///@} | |
| | | | |
| /** \name %Ellipsoid dimensions. | | /** \name %Ellipsoid dimensions. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
| | | | |
| skipping to change at line 111 | | skipping to change at line 118 | |
| * with the same area is sqrt(\e A / (4π)). | | * with the same area is sqrt(\e A / (4π)). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Area() const; | | Math::real Area() const; | |
| | | | |
| /** | | /** | |
| * @return \e V the total volume of the ellipsoid (meters<sup>3</sup>). | | * @return \e V the total volume of the ellipsoid (meters<sup>3</sup>). | |
| * For a sphere \e V = (4π / 3) <i>a</i><sup>3</sup>. The radius
of | | * For a sphere \e V = (4π / 3) <i>a</i><sup>3</sup>. The radius
of | |
| * a sphere with the same volume is cbrt(\e V / (4π/3)). | | * a sphere with the same volume is cbrt(\e V / (4π/3)). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Volume() const | | Math::real Volume() const | |
|
| { return (4 * Math::pi<real>()) * Math::sq(_a) * _b / 3; } | | { return (4 * Math::pi()) * Math::sq(_a) * _b / 3; } | |
| ///@} | | ///@} | |
| | | | |
| /** \name %Ellipsoid shape | | /** \name %Ellipsoid shape | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
| * @return \e f = (\e a − \e b) / \e a, the flattening of the | | * @return \e f = (\e a − \e b) / \e a, the flattening of the | |
| * ellipsoid. This is the value used in the constructor. This is ze
ro, | | * ellipsoid. This is the value used in the constructor. This is ze
ro, | |
| * positive, or negative for a sphere, oblate ellipsoid, or prolate | | * positive, or negative for a sphere, oblate ellipsoid, or prolate | |
| | | | |
| skipping to change at line 313 | | skipping to change at line 320 | |
| /** | | /** | |
| * @param[in] phi the geographic latitude (degrees). | | * @param[in] phi the geographic latitude (degrees). | |
| * @return ψ the isometric latitude (degrees). | | * @return ψ the isometric latitude (degrees). | |
| * | | * | |
| * The isometric latitude gives the mapping of the ellipsoid to a plane | | * The isometric latitude gives the mapping of the ellipsoid to a plane | |
| * which which is conformal (angles are preserved) and in which the equ
ator | | * which which is conformal (angles are preserved) and in which the equ
ator | |
| * of the ellipsoid maps to a straight line of constant scale; this map
ping | | * of the ellipsoid maps to a straight line of constant scale; this map
ping | |
| * defines the Mercator projection. For a sphere ψ = | | * defines the Mercator projection. For a sphere ψ = | |
| * sinh<sup>−1</sup> tan φ. | | * sinh<sup>−1</sup> tan φ. | |
| * | | * | |
|
| * φ must lie in the range [−90°, 90°]; the | | * φ must lie in the range [−90°, 90°]; the result is | |
| * result is undefined if this condition does not hold. | | * undefined if this condition does not hold. The value returned for & | |
| | | phi; | |
| | | * = ±90° is some (positive or negative) large but finite va | |
| | | lue, | |
| | | * such that InverseIsometricLatitude returns the original value of &ph | |
| | | i;. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real IsometricLatitude(real phi) const; | | Math::real IsometricLatitude(real phi) const; | |
| | | | |
| /** | | /** | |
| * @param[in] psi the isometric latitude (degrees). | | * @param[in] psi the isometric latitude (degrees). | |
| * @return φ the geographic latitude (degrees). | | * @return φ the geographic latitude (degrees). | |
| * | | * | |
|
| * The returned value φ lies in [−90°, 90°]. | | * The returned value φ lies in [−90°, 90°]. For a | |
| | | * sphere φ = tan<sup>−1</sup> sinh ψ. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real InverseIsometricLatitude(real psi) const; | | Math::real InverseIsometricLatitude(real psi) const; | |
| ///@} | | ///@} | |
| | | | |
| /** \name Other quantities. | | /** \name Other quantities. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
| * @param[in] phi the geographic latitude (degrees). | | * @param[in] phi the geographic latitude (degrees). | |
| | | | |
| skipping to change at line 463 | | skipping to change at line 473 | |
| /** | | /** | |
| * @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − | | * @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − | |
| * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity | | * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity | |
| * squared. | | * squared. | |
| * @return \e f = (\e a − \e b) / \e a, the flattening. | | * @return \e f = (\e a − \e b) / \e a, the flattening. | |
| * | | * | |
| * <i>e</i><sup>2</sup> should lie in (−∞, 1). | | * <i>e</i><sup>2</sup> should lie in (−∞, 1). | |
| * The returned value \e f lies in (−∞, 1). | | * The returned value \e f lies in (−∞, 1). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real EccentricitySqToFlattening(real e2) | | static Math::real EccentricitySqToFlattening(real e2) | |
|
| { return e2 / (std::sqrt(1 - e2) + 1); } | | { using std::sqrt; return e2 / (sqrt(1 - e2) + 1); } | |
| | | | |
| /** | | /** | |
| * @param[in] f = (\e a − \e b) / \e a, the flattening. | | * @param[in] f = (\e a − \e b) / \e a, the flattening. | |
| * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − | | * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − | |
| * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity | | * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity | |
| * squared. | | * squared. | |
| * | | * | |
| * \e f should lie in (−∞, 1). | | * \e f should lie in (−∞, 1). | |
| * The returned value <i>e</i><sup>2</sup> lies in (−∞, 1). | | * The returned value <i>e</i><sup>2</sup> lies in (−∞, 1). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
| skipping to change at line 487 | | skipping to change at line 497 | |
| /** | | /** | |
| * @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &min
us; | | * @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &min
us; | |
| * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric
ity | | * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric
ity | |
| * squared. | | * squared. | |
| * @return \e f = (\e a − \e b) / \e a, the flattening. | | * @return \e f = (\e a − \e b) / \e a, the flattening. | |
| * | | * | |
| * <i>e'</i> <sup>2</sup> should lie in (−1, ∞). | | * <i>e'</i> <sup>2</sup> should lie in (−1, ∞). | |
| * The returned value \e f lies in (−∞, 1). | | * The returned value \e f lies in (−∞, 1). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real SecondEccentricitySqToFlattening(real ep2) | | static Math::real SecondEccentricitySqToFlattening(real ep2) | |
|
| { return ep2 / (std::sqrt(1 + ep2) + 1 + ep2); } | | { using std::sqrt; return ep2 / (sqrt(1 + ep2) + 1 + ep2); } | |
| | | | |
| /** | | /** | |
| * @param[in] f = (\e a − \e b) / \e a, the flattening. | | * @param[in] f = (\e a − \e b) / \e a, the flattening. | |
| * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − | | * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − | |
| * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric
ity | | * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric
ity | |
| * squared. | | * squared. | |
| * | | * | |
| * \e f should lie in (−∞, 1). | | * \e f should lie in (−∞, 1). | |
| * The returned value <i>e'</i> <sup>2</sup> lies in (−1, ∞
). | | * The returned value <i>e'</i> <sup>2</sup> lies in (−1, ∞
). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
| skipping to change at line 531 | | skipping to change at line 541 | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real FlatteningToThirdEccentricitySq(real f) | | static Math::real FlatteningToThirdEccentricitySq(real f) | |
| { return f * (2 - f) / (1 + Math::sq(1 - f)); } | | { return f * (2 - f) / (1 + Math::sq(1 - f)); } | |
| | | | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of Ellipsoid with the parameters for the WGS8
4 | | * A global instantiation of Ellipsoid with the parameters for the WGS8
4 | |
| * ellipsoid. | | * ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const Ellipsoid WGS84; | | static const Ellipsoid& WGS84(); | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_ELLIPSOID_HPP | | #endif // GEOGRAPHICLIB_ELLIPSOID_HPP | |
| | | | |
End of changes. 12 change blocks. |
| 21 lines changed or deleted | | 34 lines changed or added | |
|
| EllipticFunction.hpp | | EllipticFunction.hpp | |
| | | | |
| skipping to change at line 65 | | skipping to change at line 65 | |
| * 78--90 (1965). | | * 78--90 (1965). | |
| * . | | * . | |
| * The notation follows http://dlmf.nist.gov/19 and http://dlmf.nist.gov/
22 | | * The notation follows http://dlmf.nist.gov/19 and http://dlmf.nist.gov/
22 | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-EllipticFunction.cpp | | * \include example-EllipticFunction.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT EllipticFunction { | | class GEOGRAPHICLIB_EXPORT EllipticFunction { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| static const real tol_; | | | |
| static const real tolRF_; | | | |
| static const real tolRD_; | | | |
| static const real tolRG0_; | | | |
| static const real tolJAC_; | | | |
| enum { num_ = 13 }; // Max depth required for sncndn. Probably 5 is en
ough. | | enum { num_ = 13 }; // Max depth required for sncndn. Probably 5 is en
ough. | |
| real _k2, _kp2, _alpha2, _alphap2, _eps; | | real _k2, _kp2, _alpha2, _alphap2, _eps; | |
|
| mutable bool _init; | | real _Kc, _Ec, _Dc, _Pic, _Gc, _Hc; | |
| mutable real _Kc, _Ec, _Dc, _Pic, _Gc, _Hc; | | | |
| bool Init() const; | | | |
| public: | | public: | |
| /** \name Constructor | | /** \name Constructor | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * Constructor specifying the modulus and parameter. | | * Constructor specifying the modulus and parameter. | |
| * | | * | |
| * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | | * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | |
| * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | | * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | |
| * done.) | | * done.) | |
| * @param[in] alpha2 the parameter α<sup>2</sup>. | | * @param[in] alpha2 the parameter α<sup>2</sup>. | |
| * α<sup>2</sup> must lie in (-∞, 1). (No checking is do
ne.) | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do
ne.) | |
| * | | * | |
| * If only elliptic integrals of the first and second kinds are needed, | | * If only elliptic integrals of the first and second kinds are needed, | |
| * then set α<sup>2</sup> = 0 (the default value); in this case,
we | | * then set α<sup>2</sup> = 0 (the default value); in this case,
we | |
| * have Π(φ, 0, \e k) = \e F(φ, \e k), \e G(φ, 0, \e k)
= \e | | * have Π(φ, 0, \e k) = \e F(φ, \e k), \e G(φ, 0, \e k)
= \e | |
| * E(φ, \e k), and \e H(φ, 0, \e k) = \e F(φ, \e k) - \e | | * E(φ, \e k), and \e H(φ, 0, \e k) = \e F(φ, \e k) - \e | |
| * D(φ, \e k). | | * D(φ, \e k). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| EllipticFunction(real k2 = 0, real alpha2 = 0); | | EllipticFunction(real k2 = 0, real alpha2 = 0) | |
| | | { Reset(k2, alpha2); } | |
| | | | |
| /** | | /** | |
| * Constructor specifying the modulus and parameter and their complemen
ts. | | * Constructor specifying the modulus and parameter and their complemen
ts. | |
| * | | * | |
| * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | | * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | |
| * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | | * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | |
| * done.) | | * done.) | |
| * @param[in] alpha2 the parameter α<sup>2</sup>. | | * @param[in] alpha2 the parameter α<sup>2</sup>. | |
| * α<sup>2</sup> must lie in (-∞, 1). (No checking is do
ne.) | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do
ne.) | |
| * @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su
p> = | | * @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su
p> = | |
| * 1 − <i>k</i><sup>2</sup>. | | * 1 − <i>k</i><sup>2</sup>. | |
| * @param[in] alphap2 the complementary parameter α'<sup>2</sup>
= 1 | | * @param[in] alphap2 the complementary parameter α'<sup>2</sup>
= 1 | |
| * − α<sup>2</sup>. | | * − α<sup>2</sup>. | |
| * | | * | |
| * The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp
hap2 | | * The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp
hap2 | |
| * = 1. (No checking is done that these conditions are met.) This | | * = 1. (No checking is done that these conditions are met.) This | |
| * constructor is provided to enable accuracy to be maintained, e.g., w
hen | | * constructor is provided to enable accuracy to be maintained, e.g., w
hen | |
| * \e k is very close to unity. | | * \e k is very close to unity. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| EllipticFunction(real k2, real alpha2, real kp2, real alphap2); | | EllipticFunction(real k2, real alpha2, real kp2, real alphap2) | |
| | | { Reset(k2, alpha2, kp2, alphap2); } | |
| | | | |
| /** | | /** | |
| * Reset the modulus and parameter. | | * Reset the modulus and parameter. | |
| * | | * | |
| * @param[in] k2 the new value of square of the modulus | | * @param[in] k2 the new value of square of the modulus | |
| * <i>k</i><sup>2</sup> which must lie in (-∞, 1). (No checkin
g is | | * <i>k</i><sup>2</sup> which must lie in (-∞, 1). (No checkin
g is | |
| * done.) | | * done.) | |
| * @param[in] alpha2 the new value of parameter α<sup>2</sup>. | | * @param[in] alpha2 the new value of parameter α<sup>2</sup>. | |
| * α<sup>2</sup> must lie in (-∞, 1). (No checking is do
ne.) | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do
ne.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
| skipping to change at line 205 | | skipping to change at line 200 | |
| /** | | /** | |
| * The complete integral of the first kind. | | * The complete integral of the first kind. | |
| * | | * | |
| * @return \e K(\e k). | | * @return \e K(\e k). | |
| * | | * | |
| * \e K(\e k) is defined in http://dlmf.nist.gov/19.2.E4 | | * \e K(\e k) is defined in http://dlmf.nist.gov/19.2.E4 | |
| * \f[ | | * \f[ | |
| * K(k) = \int_0^{\pi/2} \frac1{\sqrt{1-k^2\sin^2\phi}}\,d\phi. | | * K(k) = \int_0^{\pi/2} \frac1{\sqrt{1-k^2\sin^2\phi}}\,d\phi. | |
| * \f] | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real K() const { _init || Init(); return _Kc; } | | Math::real K() const { return _Kc; } | |
| | | | |
| /** | | /** | |
| * The complete integral of the second kind. | | * The complete integral of the second kind. | |
| * | | * | |
| * @return \e E(\e k) | | * @return \e E(\e k) | |
| * | | * | |
| * \e E(\e k) is defined in http://dlmf.nist.gov/19.2.E5 | | * \e E(\e k) is defined in http://dlmf.nist.gov/19.2.E5 | |
| * \f[ | | * \f[ | |
| * E(k) = \int_0^{\pi/2} \sqrt{1-k^2\sin^2\phi}\,d\phi. | | * E(k) = \int_0^{\pi/2} \sqrt{1-k^2\sin^2\phi}\,d\phi. | |
| * \f] | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real E() const { _init || Init(); return _Ec; } | | Math::real E() const { return _Ec; } | |
| | | | |
| /** | | /** | |
| * Jahnke's complete integral. | | * Jahnke's complete integral. | |
| * | | * | |
| * @return \e D(\e k). | | * @return \e D(\e k). | |
| * | | * | |
| * \e D(\e k) is defined in http://dlmf.nist.gov/19.2.E6 | | * \e D(\e k) is defined in http://dlmf.nist.gov/19.2.E6 | |
| * \f[ | | * \f[ | |
| * D(k) = \int_0^{\pi/2} \frac{\sin^2\phi}{\sqrt{1-k^2\sin^2\phi}}\,d
\phi. | | * D(k) = \int_0^{\pi/2} \frac{\sin^2\phi}{\sqrt{1-k^2\sin^2\phi}}\,d
\phi. | |
| * \f] | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real D() const { _init || Init(); return _Dc; } | | Math::real D() const { return _Dc; } | |
| | | | |
| /** | | /** | |
| * The difference between the complete integrals of the first and secon
d | | * The difference between the complete integrals of the first and secon
d | |
| * kinds. | | * kinds. | |
| * | | * | |
| * @return \e K(\e k) − \e E(\e k). | | * @return \e K(\e k) − \e E(\e k). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real KE() const { _init || Init(); return _k2 * _Dc; } | | Math::real KE() const { return _k2 * _Dc; } | |
| | | | |
| /** | | /** | |
| * The complete integral of the third kind. | | * The complete integral of the third kind. | |
| * | | * | |
| * @return Π(α<sup>2</sup>, \e k) | | * @return Π(α<sup>2</sup>, \e k) | |
| * | | * | |
| * Π(α<sup>2</sup>, \e k) is defined in | | * Π(α<sup>2</sup>, \e k) is defined in | |
| * http://dlmf.nist.gov/19.2.E7 | | * http://dlmf.nist.gov/19.2.E7 | |
| * \f[ | | * \f[ | |
| * \Pi(\alpha^2, k) = \int_0^{\pi/2} | | * \Pi(\alpha^2, k) = \int_0^{\pi/2} | |
| * \frac1{\sqrt{1-k^2\sin^2\phi}(1 - \alpha^2\sin^2\phi_)}\,d\phi. | | * \frac1{\sqrt{1-k^2\sin^2\phi}(1 - \alpha^2\sin^2\phi_)}\,d\phi. | |
| * \f] | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real Pi() const { _init || Init(); return _Pic; } | | Math::real Pi() const { return _Pic; } | |
| | | | |
| /** | | /** | |
| * Legendre's complete geodesic longitude integral. | | * Legendre's complete geodesic longitude integral. | |
| * | | * | |
| * @return \e G(α<sup>2</sup>, \e k) | | * @return \e G(α<sup>2</sup>, \e k) | |
| * | | * | |
| * \e G(α<sup>2</sup>, \e k) is given by | | * \e G(α<sup>2</sup>, \e k) is given by | |
| * \f[ | | * \f[ | |
| * G(\alpha^2, k) = \int_0^{\pi/2} | | * G(\alpha^2, k) = \int_0^{\pi/2} | |
| * \frac{\sqrt{1-k^2\sin^2\phi}}{1 - \alpha^2\sin^2\phi}\,d\phi. | | * \frac{\sqrt{1-k^2\sin^2\phi}}{1 - \alpha^2\sin^2\phi}\,d\phi. | |
| * \f] | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real G() const { _init || Init(); return _Gc; } | | Math::real G() const { return _Gc; } | |
| | | | |
| /** | | /** | |
| * Cayley's complete geodesic longitude difference integral. | | * Cayley's complete geodesic longitude difference integral. | |
| * | | * | |
| * @return \e H(α<sup>2</sup>, \e k) | | * @return \e H(α<sup>2</sup>, \e k) | |
| * | | * | |
| * \e H(α<sup>2</sup>, \e k) is given by | | * \e H(α<sup>2</sup>, \e k) is given by | |
| * \f[ | | * \f[ | |
| * H(\alpha^2, k) = \int_0^{\pi/2} | | * H(\alpha^2, k) = \int_0^{\pi/2} | |
| * \frac{\cos^2\phi}{(1-\alpha^2\sin^2\phi)\sqrt{1-k^2\sin^2\phi}} | | * \frac{\cos^2\phi}{(1-\alpha^2\sin^2\phi)\sqrt{1-k^2\sin^2\phi}} | |
| * \,d\phi. | | * \,d\phi. | |
| * \f] | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real H() const { _init || Init(); return _Hc; } | | Math::real H() const { return _Hc; } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Incomplete elliptic integrals. | | /** \name Incomplete elliptic integrals. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * The incomplete integral of the first kind. | | * The incomplete integral of the first kind. | |
| * | | * | |
| * @param[in] phi | | * @param[in] phi | |
| * @return \e F(φ, \e k). | | * @return \e F(φ, \e k). | |
| | | | |
| skipping to change at line 597 | | skipping to change at line 592 | |
| void sncndn(real x, real& sn, real& cn, real& dn) const; | | void sncndn(real x, real& sn, real& cn, real& dn) const; | |
| | | | |
| /** | | /** | |
| * The Δ amplitude function. | | * The Δ amplitude function. | |
| * | | * | |
| * @param[in] sn sinφ | | * @param[in] sn sinφ | |
| * @param[in] cn cosφ | | * @param[in] cn cosφ | |
| * @return Δ = sqrt(1 − <i>k</i><sup>2</sup> | | * @return Δ = sqrt(1 − <i>k</i><sup>2</sup> | |
| * sin<sup>2</sup>φ) | | * sin<sup>2</sup>φ) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real Delta(real sn, real cn) const | | Math::real Delta(real sn, real cn) const { | |
| { return std::sqrt(_k2 < 0 ? 1 - _k2 * sn*sn : _kp2 + _k2 * cn*cn); } | | using std::sqrt; | |
| | | return sqrt(_k2 < 0 ? 1 - _k2 * sn*sn : _kp2 + _k2 * cn*cn); | |
| | | } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Symmetric elliptic integrals. | | /** \name Symmetric elliptic integrals. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
|
| * Symmetric integral of the first kind <i>R<sub>F</sub></i>. | | * Symmetric integral of the first kind <i>R</i><sub><i>F</i></sub>. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
| * @param[in] z | | * @param[in] z | |
|
| * @return <i>R<sub>F</sub></i>(\e x, \e y, \e z) | | * @return <i>R</i><sub><i>F</i></sub>(\e x, \e y, \e z) | |
| * | | * | |
|
| * <i>R<sub>F</sub></i> is defined in http://dlmf.nist.gov/19.16.E1 | | * <i>R</i><sub><i>F</i></sub> is defined in http://dlmf.nist.gov/19.16
.E1 | |
| * \f[ R_F(x, y, z) = \frac12 | | * \f[ R_F(x, y, z) = \frac12 | |
| * \int_0^\infty\frac1{\sqrt{(t + x) (t + y) (t + z)}}\, dt \f] | | * \int_0^\infty\frac1{\sqrt{(t + x) (t + y) (t + z)}}\, dt \f] | |
| * If one of the arguments is zero, it is more efficient to call the | | * If one of the arguments is zero, it is more efficient to call the | |
| * two-argument version of this function with the non-zero arguments. | | * two-argument version of this function with the non-zero arguments. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RF(real x, real y, real z); | | static real RF(real x, real y, real z); | |
| | | | |
| /** | | /** | |
|
| * Complete symmetric integral of the first kind, <i>R<sub>F</sub></i> | | * Complete symmetric integral of the first kind, | |
| with | | * <i>R</i><sub><i>F</i></sub> with one argument zero. | |
| * one argument zero. | | | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
|
| * @return <i>R<sub>F</sub></i>(\e x, \e y, 0) | | * @return <i>R</i><sub><i>F</i></sub>(\e x, \e y, 0) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RF(real x, real y); | | static real RF(real x, real y); | |
| | | | |
| /** | | /** | |
|
| * Degenerate symmetric integral of the first kind <i>R<sub>C</sub></i> | | * Degenerate symmetric integral of the first kind | |
| . | | * <i>R</i><sub><i>C</i></sub>. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
|
| * @return <i>R<sub>C</sub></i>(\e x, \e y) = <i>R<sub>F</sub></i>(\e x | | * @return <i>R</i><sub><i>C</i></sub>(\e x, \e y) = | |
| , \e | | * <i>R</i><sub><i>F</i></sub>(\e x, \e y, \e y) | |
| * y, \e y) | | | |
| * | | * | |
|
| * <i>R<sub>C</sub></i> is defined in http://dlmf.nist.gov/19.2.E17 | | * <i>R</i><sub><i>C</i></sub> is defined in http://dlmf.nist.gov/19.2.
E17 | |
| * \f[ R_C(x, y) = \frac12 | | * \f[ R_C(x, y) = \frac12 | |
| * \int_0^\infty\frac1{\sqrt{t + x}(t + y)}\,dt \f] | | * \int_0^\infty\frac1{\sqrt{t + x}(t + y)}\,dt \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RC(real x, real y); | | static real RC(real x, real y); | |
| | | | |
| /** | | /** | |
|
| * Symmetric integral of the second kind <i>R<sub>G</sub></i>. | | * Symmetric integral of the second kind <i>R</i><sub><i>G</i></sub>. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
| * @param[in] z | | * @param[in] z | |
|
| * @return <i>R<sub>G</sub></i>(\e x, \e y, \e z) | | * @return <i>R</i><sub><i>G</i></sub>(\e x, \e y, \e z) | |
| * | | * | |
|
| * <i>R<sub>G</sub></i> is defined in Carlson, eq 1.5 | | * <i>R</i><sub><i>G</i></sub> is defined in Carlson, eq 1.5 | |
| * \f[ R_G(x, y, z) = \frac14 | | * \f[ R_G(x, y, z) = \frac14 | |
| * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} | | * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} | |
| * \biggl( | | * \biggl( | |
| * \frac x{t + x} + \frac y{t + y} + \frac z{t + z} | | * \frac x{t + x} + \frac y{t + y} + \frac z{t + z} | |
| * \biggr)t\,dt \f] | | * \biggr)t\,dt \f] | |
| * See also http://dlmf.nist.gov/19.16.E3. | | * See also http://dlmf.nist.gov/19.16.E3. | |
| * If one of the arguments is zero, it is more efficient to call the | | * If one of the arguments is zero, it is more efficient to call the | |
| * two-argument version of this function with the non-zero arguments. | | * two-argument version of this function with the non-zero arguments. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RG(real x, real y, real z); | | static real RG(real x, real y, real z); | |
| | | | |
| /** | | /** | |
|
| * Complete symmetric integral of the second kind, <i>R<sub>G</sub></i> | | * Complete symmetric integral of the second kind, | |
| * with one argument zero. | | * <i>R</i><sub><i>G</i></sub> with one argument zero. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
|
| * @return <i>R<sub>G</sub></i>(\e x, \e y, 0) | | * @return <i>R</i><sub><i>G</i></sub>(\e x, \e y, 0) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RG(real x, real y); | | static real RG(real x, real y); | |
| | | | |
| /** | | /** | |
|
| * Symmetric integral of the third kind <i>R<sub>J</sub></i>. | | * Symmetric integral of the third kind <i>R</i><sub><i>J</i></sub>. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
| * @param[in] z | | * @param[in] z | |
| * @param[in] p | | * @param[in] p | |
|
| * @return <i>R<sub>J</sub></i>(\e x, \e y, \e z, \e p) | | * @return <i>R</i><sub><i>J</i></sub>(\e x, \e y, \e z, \e p) | |
| * | | * | |
|
| * <i>R<sub>J</sub></i> is defined in http://dlmf.nist.gov/19.16.E2 | | * <i>R</i><sub><i>J</i></sub> is defined in http://dlmf.nist.gov/19.16
.E2 | |
| * \f[ R_J(x, y, z, p) = \frac32 | | * \f[ R_J(x, y, z, p) = \frac32 | |
| * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} (t + p)^{-1}\, d
t \f] | | * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} (t + p)^{-1}\, d
t \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RJ(real x, real y, real z, real p); | | static real RJ(real x, real y, real z, real p); | |
| | | | |
| /** | | /** | |
|
| * Degenerate symmetric integral of the third kind <i>R<sub>D</sub></i> | | * Degenerate symmetric integral of the third kind | |
| . | | * <i>R</i><sub><i>D</i></sub>. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
| * @param[in] z | | * @param[in] z | |
|
| * @return <i>R<sub>D</sub></i>(\e x, \e y, \e z) = <i>R<sub>J</sub></i | | * @return <i>R</i><sub><i>D</i></sub>(\e x, \e y, \e z) = | |
| >(\e | | * <i>R</i><sub><i>J</i></sub>(\e x, \e y, \e z, \e z) | |
| * x, \e y, \e z, \e z) | | | |
| * | | * | |
|
| * <i>R<sub>D</sub></i> is defined in http://dlmf.nist.gov/19.16.E5 | | * <i>R</i><sub><i>D</i></sub> is defined in http://dlmf.nist.gov/19.16
.E5 | |
| * \f[ R_D(x, y, z) = \frac32 | | * \f[ R_D(x, y, z) = \frac32 | |
| * \int_0^\infty[(t + x) (t + y)]^{-1/2} (t + z)^{-3/2}\, dt \f] | | * \int_0^\infty[(t + x) (t + y)]^{-1/2} (t + z)^{-3/2}\, dt \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static real RD(real x, real y, real z); | | static real RD(real x, real y, real z); | |
| ///@} | | ///@} | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| | | | |
End of changes. 31 change blocks. |
| 47 lines changed or deleted | | 41 lines changed or added | |
|
| Geocentric.hpp | | Geocentric.hpp | |
| | | | |
| skipping to change at line 46 | | skipping to change at line 46 | |
| * Several changes have been made to ensure that the method returns accur
ate | | * Several changes have been made to ensure that the method returns accur
ate | |
| * results for all finite inputs (even if \e h is infinite). The changes
are | | * results for all finite inputs (even if \e h is infinite). The changes
are | |
| * described in Appendix B of | | * described in Appendix B of | |
| * - C. F. F. Karney, | | * - C. F. F. Karney, | |
| * <a href="http://arxiv.org/abs/1102.1215v1">Geodesics | | * <a href="http://arxiv.org/abs/1102.1215v1">Geodesics | |
| * on an ellipsoid of revolution</a>, | | * on an ellipsoid of revolution</a>, | |
| * Feb. 2011; | | * Feb. 2011; | |
| * preprint | | * preprint | |
| * <a href="http://arxiv.org/abs/1102.1215v1">arxiv:1102.1215v1</a>. | | * <a href="http://arxiv.org/abs/1102.1215v1">arxiv:1102.1215v1</a>. | |
| * . | | * . | |
|
| | | * Vermeille similarly updated his method in | |
| | | * - H. Vermeille, | |
| | | * <a href="http://dx.doi.org/10.1007/s00190-010-0419-x"> | |
| | | * An analytical method to transform geocentric into | |
| | | * geodetic coordinates</a>, J. Geodesy 85, 105--117 (2011). | |
| | | * . | |
| * See \ref geocentric for more information. | | * See \ref geocentric for more information. | |
| * | | * | |
| * The errors in these routines are close to round-off. Specifically, fo
r | | * The errors in these routines are close to round-off. Specifically, fo
r | |
| * points within 5000 km of the surface of the ellipsoid (either inside o
r | | * points within 5000 km of the surface of the ellipsoid (either inside o
r | |
| * outside the ellipsoid), the error is bounded by 7 nm (7 nanometers) fo
r | | * outside the ellipsoid), the error is bounded by 7 nm (7 nanometers) fo
r | |
| * the WGS84 ellipsoid. See \ref geocentric for further information on t
he | | * the WGS84 ellipsoid. See \ref geocentric for further information on t
he | |
| * errors. | | * errors. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-Geocentric.cpp | | * \include example-Geocentric.cpp | |
| | | | |
| skipping to change at line 106 | | skipping to change at line 112 | |
| void IntReverse(real X, real Y, real Z, real& lat, real& lon, real& h, | | void IntReverse(real X, real Y, real Z, real& lat, real& lon, real& h, | |
| real M[dim2_]) const; | | real M[dim2_]) const; | |
| | | | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | * @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. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Geocentric(real a, real f); | | Geocentric(real a, real f); | |
| | | | |
| /** | | /** | |
| * A default constructor (for use by NormalGravity). | | * A default constructor (for use by NormalGravity). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Geocentric() : _a(-1) {} | | Geocentric() : _a(-1) {} | |
| | | | |
| /** | | /** | |
| | | | |
| skipping to change at line 219 | | skipping to change at line 225 | |
| * matrix in row-major order. | | * matrix in row-major order. | |
| * | | * | |
| * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can | | * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can | |
| * express \e v as \e column vectors in one of two ways | | * express \e v as \e column vectors in one of two ways | |
| * - in east, north, up coordinates (where the components are relative
to a | | * - in east, north, up coordinates (where the components are relative
to a | |
| * local coordinate system at (\e lat, \e lon, \e h)); call this | | * local coordinate system at (\e lat, \e lon, \e h)); call this | |
| * representation \e v1. | | * representation \e v1. | |
| * - in geocentric \e X, \e Y, \e Z coordinates; call this representati
on | | * - in geocentric \e X, \e Y, \e Z coordinates; call this representati
on | |
| * \e v0. | | * \e v0. | |
| * . | | * . | |
|
| * Then we have \e v1 = \e M<sup>T</sup> ⋅ \e v0, where \e | | * Then we have \e v1 = <i>M</i><sup>T</sup> ⋅ \e v0, where | |
| * M<sup>T</sup> is the transpose of \e M. | | * <i>M</i><sup>T</sup> is the transpose of \e M. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Reverse(real X, real Y, real Z, real& lat, real& lon, real& h, | | void Reverse(real X, real Y, real Z, real& lat, real& lon, real& h, | |
| std::vector<real>& M) | | std::vector<real>& M) | |
| const { | | const { | |
| if (!Init()) | | if (!Init()) | |
| return; | | return; | |
| if (M.end() == M.begin() + dim2_) { | | if (M.end() == M.begin() + dim2_) { | |
| real t[dim2_]; | | real t[dim2_]; | |
| IntReverse(X, Y, Z, lat, lon, h, t); | | IntReverse(X, Y, Z, lat, lon, h, t); | |
| std::copy(t, t + dim2_, M.begin()); | | std::copy(t, t + dim2_, M.begin()); | |
| | | | |
| skipping to change at line 247 | | skipping to change at line 253 | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return true if the object has been initialized. | | * @return true if the object has been initialized. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| bool Init() const { return _a > 0; } | | bool Init() const { return _a > 0; } | |
| /** | | /** | |
| * @return \e a the equatorial radius of the ellipsoid (meters). This
is | | * @return \e a the equatorial radius of the ellipsoid (meters). This
is | |
| * the value used in the constructor. | | * the value used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const | | Math::real MajorRadius() const | |
|
| { return Init() ? _a : Math::NaN<real>(); } | | { return Init() ? _a : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e f the flattening of the ellipsoid. This is the | | * @return \e f the flattening of the ellipsoid. This is the | |
| * value used in the constructor. | | * value used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Flattening() const | | Math::real Flattening() const | |
|
| { return Init() ? _f : Math::NaN<real>(); } | | { return Init() ? _f : Math::NaN(); } | |
| ///@} | | ///@} | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return \e r the inverse flattening of the ellipsoid. | | * @return \e r the inverse flattening of the ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real InverseFlattening() const | | Math::real InverseFlattening() const | |
|
| { return Init() ? 1/_f : Math::NaN<real>(); } | | { return Init() ? 1/_f : Math::NaN(); } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * A global instantiation of Geocentric with the parameters for the WGS
84 | | * A global instantiation of Geocentric with the parameters for the WGS
84 | |
| * ellipsoid. | | * ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const Geocentric WGS84; | | static const Geocentric& WGS84(); | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_GEOCENTRIC_HPP | | #endif // GEOGRAPHICLIB_GEOCENTRIC_HPP | |
| | | | |
End of changes. 7 change blocks. |
| 10 lines changed or deleted | | 15 lines changed or added | |
|
| Geodesic.hpp | | Geodesic.hpp | |
| | | | |
| skipping to change at line 18 | | skipping to change at line 18 | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEODESIC_HPP) | | #if !defined(GEOGRAPHICLIB_GEODESIC_HPP) | |
| #define GEOGRAPHICLIB_GEODESIC_HPP 1 | | #define GEOGRAPHICLIB_GEODESIC_HPP 1 | |
| | | | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEODESIC_ORDER) | | #if !defined(GEOGRAPHICLIB_GEODESIC_ORDER) | |
| /** | | /** | |
| * The order of the expansions used by Geodesic. | | * The order of the expansions used by Geodesic. | |
|
| | | * GEOGRAPHICLIB_GEODESIC_ORDER can be set to any integer in [0, 8]. | |
| **********************************************************************/ | | **********************************************************************/ | |
| # define GEOGRAPHICLIB_GEODESIC_ORDER \ | | # define GEOGRAPHICLIB_GEODESIC_ORDER \ | |
|
| (GEOGRAPHICLIB_PRECISION == 2 ? 6 : (GEOGRAPHICLIB_PRECISION == 1 ? 3 : 7 | | (GEOGRAPHICLIB_PRECISION == 2 ? 6 : \ | |
| )) | | (GEOGRAPHICLIB_PRECISION == 1 ? 3 : \ | |
| | | (GEOGRAPHICLIB_PRECISION == 3 ? 7 : 8))) | |
| #endif | | #endif | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| class GeodesicLine; | | class GeodesicLine; | |
| | | | |
| /** | | /** | |
| * \brief %Geodesic calculations | | * \brief %Geodesic calculations | |
| * | | * | |
| * The shortest path between two points on a ellipsoid at (\e lat1, \e lo
n1) | | * The shortest path between two points on a ellipsoid at (\e lat1, \e lo
n1) | |
| | | | |
| skipping to change at line 185 | | skipping to change at line 188 | |
| static const int nC1p_ = GEOGRAPHICLIB_GEODESIC_ORDER; | | static const int nC1p_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nA2_ = GEOGRAPHICLIB_GEODESIC_ORDER; | | static const int nA2_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC2_ = GEOGRAPHICLIB_GEODESIC_ORDER; | | static const int nC2_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nA3_ = GEOGRAPHICLIB_GEODESIC_ORDER; | | static const int nA3_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nA3x_ = nA3_; | | static const int nA3x_ = nA3_; | |
| static const int nC3_ = GEOGRAPHICLIB_GEODESIC_ORDER; | | static const int nC3_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC3x_ = (nC3_ * (nC3_ - 1)) / 2; | | static const int nC3x_ = (nC3_ * (nC3_ - 1)) / 2; | |
| static const int nC4_ = GEOGRAPHICLIB_GEODESIC_ORDER; | | static const int nC4_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2; | | static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2; | |
| static const unsigned maxit1_ = 20; | | static const unsigned maxit1_ = 20; | |
|
| static const unsigned maxit2_ = maxit1_ + | | unsigned maxit2_; | |
| std::numeric_limits<real>::digits + 10; | | real tiny_, tol0_, tol1_, tol2_, tolb_, xthresh_; | |
| | | | |
| static const real tiny_; | | | |
| static const real tol0_; | | | |
| static const real tol1_; | | | |
| static const real tol2_; | | | |
| static const real tolb_; | | | |
| static const real xthresh_; | | | |
| | | | |
| enum captype { | | enum captype { | |
| CAP_NONE = 0U, | | CAP_NONE = 0U, | |
| CAP_C1 = 1U<<0, | | CAP_C1 = 1U<<0, | |
| CAP_C1p = 1U<<1, | | CAP_C1p = 1U<<1, | |
| CAP_C2 = 1U<<2, | | CAP_C2 = 1U<<2, | |
| CAP_C3 = 1U<<3, | | CAP_C3 = 1U<<3, | |
| CAP_C4 = 1U<<4, | | CAP_C4 = 1U<<4, | |
| CAP_ALL = 0x1FU, | | CAP_ALL = 0x1FU, | |
| OUT_ALL = 0x7F80U, | | OUT_ALL = 0x7F80U, | |
| }; | | }; | |
| | | | |
| 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); | |
| ; | | | |
| static inline real AngRound(real x) { | | static inline real AngRound(real x) { | |
| // 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). | |
|
| | | using std::abs; | |
| const real z = 1/real(16); | | const real z = 1/real(16); | |
|
| volatile real y = std::abs(x); | | GEOGRAPHICLIB_VOLATILE real y = 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) { | | static inline void SinCosNorm(real& sinx, real& cosx) { | |
| real r = Math::hypot(sinx, cosx); | | real r = Math::hypot(sinx, cosx); | |
| sinx /= r; | | sinx /= r; | |
| cosx /= r; | | cosx /= r; | |
| } | | } | |
| static real Astroid(real x, real y); | | static real Astroid(real x, real y); | |
| | | | |
| skipping to change at line 343 | | skipping to change at line 339 | |
| }; | | }; | |
| | | | |
| /** \name Constructor | | /** \name Constructor | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | * @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. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * Solve the direct geodesic problem where the length of the geodesic | | * Solve the direct geodesic problem where the length of the geodesic | |
| | | | |
| skipping to change at line 882 | | skipping to change at line 878 | |
| Math::real InverseFlattening() const { return 1/_f; } | | Math::real InverseFlattening() const { return 1/_f; } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * @return total area of ellipsoid in meters<sup>2</sup>. The area of
a | | * @return total area of ellipsoid in meters<sup>2</sup>. The area of
a | |
| * polygon encircling a pole can be found by adding | | * polygon encircling a pole can be found by adding | |
| * Geodesic::EllipsoidArea()/2 to the sum of \e S12 for each side of
the | | * Geodesic::EllipsoidArea()/2 to the sum of \e S12 for each side of
the | |
| * polygon. | | * polygon. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EllipsoidArea() const | | Math::real EllipsoidArea() const | |
|
| { return 4 * Math::pi<real>() * _c2; } | | { return 4 * Math::pi() * _c2; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of Geodesic with the parameters for the WGS84 | | * A global instantiation of Geodesic with the parameters for the WGS84 | |
| * ellipsoid. | | * ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const Geodesic WGS84; | | static const Geodesic& WGS84(); | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_GEODESIC_HPP | | #endif // GEOGRAPHICLIB_GEODESIC_HPP | |
| | | | |
End of changes. 9 change blocks. |
| 20 lines changed or deleted | | 14 lines changed or added | |
|
| GeodesicExact.hpp | | GeodesicExact.hpp | |
| | | | |
| skipping to change at line 35 | | skipping to change at line 35 | |
| class GeodesicLineExact; | | class GeodesicLineExact; | |
| | | | |
| /** | | /** | |
| * \brief Exact geodesic calculations | | * \brief Exact geodesic calculations | |
| * | | * | |
| * The equations for geodesics on an ellipsoid can be expressed in terms
of | | * The equations for geodesics on an ellipsoid can be expressed in terms
of | |
| * incomplete elliptic integrals. The Geodesic class expands these integ
rals | | * incomplete elliptic integrals. The Geodesic class expands these integ
rals | |
| * in a series in the flattening \e f and this provides an accurate solut
ion | | * in a series in the flattening \e f and this provides an accurate solut
ion | |
| * for \e f ∈ [-0.01, 0.01]. The GeodesicExact class computes the | | * for \e f ∈ [-0.01, 0.01]. The GeodesicExact class computes the | |
| * ellitpic integrals directly and so provides a solution which is valid
for | | * ellitpic integrals directly and so provides a solution which is valid
for | |
|
| * all \e f. However, in practice, its use should be limited to about \e | | * all \e f. However, in practice, its use should be limited to about | |
| * b/\e a ∈ [0.01, 100] or \e f ∈ [-99, 0.99]. | | * <i>b</i>/\e a ∈ [0.01, 100] or \e f ∈ [-99, 0.99]. | |
| * | | * | |
| * For the WGS84 ellipsoid, these classes are 2--3 times \e slower than t
he | | * For the WGS84 ellipsoid, these classes are 2--3 times \e slower than t
he | |
| * series solution and 2--3 times \e less \e accurate (because it's less
easy | | * series solution and 2--3 times \e less \e accurate (because it's less
easy | |
| * to control round-off errors with the elliptic integral formulation); i
.e., | | * to control round-off errors with the elliptic integral formulation); i
.e., | |
| * the error is about 40 nm (40 nanometers) instead of 15 nm. However th
e | | * the error is about 40 nm (40 nanometers) instead of 15 nm. However th
e | |
| * error in the series solution scales as <i>f</i><sup>7</sup> while the | | * error in the series solution scales as <i>f</i><sup>7</sup> while the | |
| * error in the elliptic integral solution depends weakly on \e f. If th
e | | * error in the elliptic integral solution depends weakly on \e f. If th
e | |
|
| * quarter meridian distance is 10000 km and the ratio \e b/\e a = 1 &min | | * quarter meridian distance is 10000 km and the ratio <i>b</i>/\e a = 1 | |
| us; | | * − \e f is varied then the approximate maximum error (expressed a | |
| * \e f is varied then the approximate maximum error (expressed as a | | s a | |
| * distance) is <pre> | | * distance) is <pre> | |
| * 1 - f error (nm) | | * 1 - f error (nm) | |
| * 1/128 387 | | * 1/128 387 | |
| * 1/64 345 | | * 1/64 345 | |
| * 1/32 269 | | * 1/32 269 | |
| * 1/16 210 | | * 1/16 210 | |
| * 1/8 115 | | * 1/8 115 | |
| * 1/4 69 | | * 1/4 69 | |
| * 1/2 36 | | * 1/2 36 | |
| * 1 15 | | * 1 15 | |
| * 2 25 | | * 2 25 | |
| * 4 96 | | * 4 96 | |
| * 8 318 | | * 8 318 | |
| * 16 985 | | * 16 985 | |
| * 32 2352 | | * 32 2352 | |
| * 64 6008 | | * 64 6008 | |
| * 128 19024 | | * 128 19024 | |
| * </pre> | | * </pre> | |
| * | | * | |
| * The computation of the area in these classes is via a 30th order serie
s. | | * The computation of the area in these classes is via a 30th order serie
s. | |
|
| * This gives accurate results for \e b/\e a ∈ [1/2, 2]; the accurac | | * This gives accurate results for <i>b</i>/\e a ∈ [1/2, 2]; the | |
| y is | | * accuracy is about 8 decimal digits for <i>b</i>/\e a ∈ [1/4, 4]. | |
| * about 8 decimal digits for \e b/\e a ∈ [1/4, 4]. | | | |
| * | | * | |
| * See \ref geodellip for the formulation. See the documentation on the | | * See \ref geodellip for the formulation. See the documentation on the | |
| * Geodesic class for additional information on the geodesic problems. | | * Geodesic class for additional information on the geodesic problems. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-GeodesicExact.cpp | | * \include example-GeodesicExact.cpp | |
| * | | * | |
| * <a href="GeodSolve.1.html">GeodSolve</a> is a command-line utility | | * <a href="GeodSolve.1.html">GeodSolve</a> is a command-line utility | |
| * providing access to the functionality of GeodesicExact and | | * providing access to the functionality of GeodesicExact and | |
| * GeodesicLineExact (via the -E option). | | * GeodesicLineExact (via the -E option). | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT GeodesicExact { | | class GEOGRAPHICLIB_EXPORT GeodesicExact { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class GeodesicLineExact; | | friend class GeodesicLineExact; | |
| static const int nC4_ = GEOGRAPHICLIB_GEODESICEXACT_ORDER; | | static const int nC4_ = GEOGRAPHICLIB_GEODESICEXACT_ORDER; | |
| static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2; | | static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2; | |
| static const unsigned maxit1_ = 20; | | static const unsigned maxit1_ = 20; | |
|
| static const unsigned maxit2_ = maxit1_ + | | unsigned maxit2_; | |
| std::numeric_limits<real>::digits + 10; | | real tiny_, tol0_, tol1_, tol2_, tolb_, xthresh_; | |
| | | | |
| static const real tiny_; | | | |
| static const real tol0_; | | | |
| static const real tol1_; | | | |
| static const real tol2_; | | | |
| static const real tolb_; | | | |
| static const real xthresh_; | | | |
| | | | |
| enum captype { | | enum captype { | |
| CAP_NONE = 0U, | | CAP_NONE = 0U, | |
| CAP_E = 1U<<0, | | CAP_E = 1U<<0, | |
| // Skip 1U<<1 for compatibility with Geodesic (not required) | | // Skip 1U<<1 for compatibility with Geodesic (not required) | |
| CAP_D = 1U<<2, | | CAP_D = 1U<<2, | |
| CAP_H = 1U<<3, | | CAP_H = 1U<<3, | |
| CAP_C4 = 1U<<4, | | CAP_C4 = 1U<<4, | |
| CAP_ALL = 0x1FU, | | CAP_ALL = 0x1FU, | |
| OUT_ALL = 0x7F80U, | | OUT_ALL = 0x7F80U, | |
| }; | | }; | |
| | | | |
|
| static real CosSeries(real sinx, real cosx, const real c[], int n) | | static real CosSeries(real sinx, real cosx, const real c[], int n); | |
| ; | | | |
| static inline real AngRound(real x) { | | static inline real AngRound(real x) { | |
| // 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). | |
|
| | | using std::abs; | |
| const real z = 1/real(16); | | const real z = 1/real(16); | |
|
| volatile real y = std::abs(x); | | GEOGRAPHICLIB_VOLATILE real y = 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) { | | static inline void SinCosNorm(real& sinx, real& cosx) { | |
| real r = Math::hypot(sinx, cosx); | | real r = Math::hypot(sinx, cosx); | |
| sinx /= r; | | sinx /= r; | |
| cosx /= r; | | cosx /= r; | |
| } | | } | |
| static real Astroid(real x, real y); | | static real Astroid(real x, real y); | |
| | | | |
| skipping to change at line 151 | | skipping to change at line 144 | |
| real sbet2, real cbet2, real dn2, | | real sbet2, real cbet2, real dn2, | |
| real lam12, | | real lam12, | |
| real& salp1, real& calp1, | | real& salp1, real& calp1, | |
| real& salp2, real& calp2, real& dnm) const; | | real& salp2, real& calp2, real& dnm) const; | |
| real Lambda12(real sbet1, real cbet1, real dn1, | | real Lambda12(real sbet1, real cbet1, real dn1, | |
| real sbet2, real cbet2, real dn2, | | real sbet2, real cbet2, real dn2, | |
| real salp1, real calp1, | | real salp1, real calp1, | |
| real& salp2, real& calp2, real& sig12, | | real& salp2, real& calp2, real& sig12, | |
| real& ssig1, real& csig1, real& ssig2, real& csig2, | | real& ssig1, real& csig1, real& ssig2, real& csig2, | |
| EllipticFunction& E, | | EllipticFunction& E, | |
|
| real& omg12, bool diffp, real& dlam12) | | real& omg12, bool diffp, real& dlam12) const; | |
| const; | | | |
| | | | |
| // These are Maxima generated functions to provide series approximation
s to | | // These are Maxima generated functions to provide series approximation
s to | |
| // the integrals for the area. | | // the integrals for the area. | |
| void C4coeff(); | | void C4coeff(); | |
| void C4f(real k2, real c[]) const; | | void C4f(real k2, real c[]) const; | |
|
| | | // Large coefficients are split so that lo contains the low 52 bits and | |
| | | hi | |
| | | // the rest. This choice avoids double rounding with doubles and highe | |
| | | r | |
| | | // precision types. float coefficients will suffer double rounding; | |
| | | // however the accuracy is already lousy for floats. | |
| | | static Math::real inline reale(long long hi, long long lo) { | |
| | | using std::ldexp; | |
| | | return ldexp(real(hi), 52) + lo; | |
| | | } | |
| | | static const Math::real* rawC4coeff(); | |
| | | | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Bit masks for what calculations to do. These masks do double duty. | | * Bit masks for what calculations to do. These masks do double duty. | |
| * They signify to the GeodesicLineExact::GeodesicLineExact constructor
and | | * They signify to the GeodesicLineExact::GeodesicLineExact constructor
and | |
| * to GeodesicExact::Line what capabilities should be included in the | | * to GeodesicExact::Line what capabilities should be included in the | |
| * GeodesicLineExact object. They also specify which results to return
in | | * GeodesicLineExact object. They also specify which results to return
in | |
| * the general routines GeodesicExact::GenDirect and | | * the general routines GeodesicExact::GenDirect and | |
| * GeodesicExact::GenInverse routines. GeodesicLineExact::mask is a | | * GeodesicExact::GenInverse routines. GeodesicLineExact::mask is a | |
| | | | |
| skipping to change at line 235 | | skipping to change at line 236 | |
| }; | | }; | |
| | | | |
| /** \name Constructor | | /** \name Constructor | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | * @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. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| GeodesicExact(real a, real f); | | GeodesicExact(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 | | * Perform the direct geodesic calculation where the length of the geod
esic | |
| | | | |
| skipping to change at line 770 | | skipping to change at line 771 | |
| Math::real InverseFlattening() const { return 1/_f; } | | Math::real InverseFlattening() const { return 1/_f; } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * @return total area of ellipsoid in meters<sup>2</sup>. The area of
a | | * @return total area of ellipsoid in meters<sup>2</sup>. The area of
a | |
| * polygon encircling a pole can be found by adding | | * polygon encircling a pole can be found by adding | |
| * GeodesicExact::EllipsoidArea()/2 to the sum of \e S12 for each sid
e of | | * GeodesicExact::EllipsoidArea()/2 to the sum of \e S12 for each sid
e of | |
| * the polygon. | | * the polygon. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EllipsoidArea() const | | Math::real EllipsoidArea() const | |
|
| { return 4 * Math::pi<real>() * _c2; } | | { return 4 * Math::pi() * _c2; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of GeodesicExact with the parameters for the
WGS84 | | * A global instantiation of GeodesicExact with the parameters for the
WGS84 | |
| * ellipsoid. | | * ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const GeodesicExact WGS84; | | static const GeodesicExact& WGS84(); | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_GEODESICEXACT_HPP | | #endif // GEOGRAPHICLIB_GEODESICEXACT_HPP | |
| | | | |
End of changes. 12 change blocks. |
| 28 lines changed or deleted | | 29 lines changed or added | |
|
| GeodesicLine.hpp | | GeodesicLine.hpp | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 69 | |
| class GEOGRAPHICLIB_EXPORT GeodesicLine { | | class GEOGRAPHICLIB_EXPORT GeodesicLine { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class Geodesic; | | friend class Geodesic; | |
| static const int nC1_ = Geodesic::nC1_; | | static const int nC1_ = Geodesic::nC1_; | |
| static const int nC1p_ = Geodesic::nC1p_; | | static const int nC1p_ = Geodesic::nC1p_; | |
| static const int nC2_ = Geodesic::nC2_; | | static const int nC2_ = Geodesic::nC2_; | |
| static const int nC3_ = Geodesic::nC3_; | | static const int nC3_ = Geodesic::nC3_; | |
| static const int nC4_ = Geodesic::nC4_; | | static const int nC4_ = Geodesic::nC4_; | |
| | | | |
|
| | | real tiny_; | |
| real _lat1, _lon1, _azi1; | | real _lat1, _lon1, _azi1; | |
| real _a, _f, _b, _c2, _f1, _salp0, _calp0, _k2, | | real _a, _f, _b, _c2, _f1, _salp0, _calp0, _k2, | |
| _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, _somg1, _comg1, | | _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, _somg1, _comg1, | |
| _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41; | | _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41; | |
| // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused | | // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused | |
| real _C1a[nC1_ + 1], _C1pa[nC1p_ + 1], _C2a[nC2_ + 1], _C3a[nC3_], | | real _C1a[nC1_ + 1], _C1pa[nC1p_ + 1], _C2a[nC2_ + 1], _C3a[nC3_], | |
| _C4a[nC4_]; // all the elements of _C4a are used | | _C4a[nC4_]; // all the elements of _C4a are used | |
| unsigned _caps; | | unsigned _caps; | |
| | | | |
| enum captype { | | enum captype { | |
| | | | |
| skipping to change at line 197 | | skipping to change at line 198 | |
| * length can only be specified in terms of arc length; | | * length can only be specified in terms of arc length; | |
| * - \e caps |= GeodesicLine::ALL for all of the above. | | * - \e caps |= GeodesicLine::ALL for all of the above. | |
| * . | | * . | |
| * The default value of \e caps is GeodesicLine::ALL. | | * The default value of \e caps is GeodesicLine::ALL. | |
| * | | * | |
| * If the point is at a pole, the azimuth is defined by keeping \e lon1 | | * If the point is at a pole, the azimuth is defined by keeping \e lon1 | |
| * fixed, writing \e lat1 = ±(90° − ε), and ta
king | | * fixed, writing \e lat1 = ±(90° − ε), and ta
king | |
| * the limit ε → 0+. | | * the limit ε → 0+. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| 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); | |
| ; | | | |
| | | | |
| /** | | /** | |
| * 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() : _caps(0U) {} | | GeodesicLine() : _caps(0U) {} | |
| ///@} | | ///@} | |
| | | | |
| | | | |
| skipping to change at line 523 | | skipping to change at line 523 | |
| | | | |
| /** | | /** | |
| * @return true if the object has been initialized. | | * @return true if the object has been initialized. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| bool Init() const { return _caps != 0U; } | | bool Init() const { return _caps != 0U; } | |
| | | | |
| /** | | /** | |
| * @return \e lat1 the latitude of point 1 (degrees). | | * @return \e lat1 the latitude of point 1 (degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Latitude() const | | Math::real Latitude() const | |
|
| { return Init() ? _lat1 : Math::NaN<real>(); } | | { return Init() ? _lat1 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e lon1 the longitude of point 1 (degrees). | | * @return \e lon1 the longitude of point 1 (degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Longitude() const | | Math::real Longitude() const | |
|
| { return Init() ? _lon1 : Math::NaN<real>(); } | | { return Init() ? _lon1 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e azi1 the azimuth (degrees) of the geodesic line at point
1. | | * @return \e azi1 the azimuth (degrees) of the geodesic line at point
1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Azimuth() const | | Math::real Azimuth() const | |
|
| { return Init() ? _azi1 : Math::NaN<real>(); } | | { return Init() ? _azi1 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e azi0 the azimuth (degrees) of the geodesic line as it cro
sses | | * @return \e azi0 the azimuth (degrees) of the geodesic line as it cro
sses | |
| * the equator in a northward direction. | | * the equator in a northward direction. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialAzimuth() const { | | Math::real EquatorialAzimuth() const { | |
|
| | | using std::atan2; | |
| return Init() ? | | return Init() ? | |
|
| atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>(); | | atan2(_salp0, _calp0) / Math::degree() : Math::NaN(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a1 the arc length (degrees) between the northward equator
ial | | * @return \e a1 the arc length (degrees) between the northward equator
ial | |
| * crossing and point 1. | | * crossing and point 1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialArc() const { | | Math::real EquatorialArc() const { | |
|
| | | using std::atan2; | |
| return Init() ? | | return Init() ? | |
|
| atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>(); | | atan2(_ssig1, _csig1) / Math::degree() : Math::NaN(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a the equatorial radius of the ellipsoid (meters). This
is | | * @return \e a the equatorial radius of the ellipsoid (meters). This
is | |
| * the value inherited from the Geodesic object used in the construct
or. | | * the value inherited from the Geodesic object used in the construct
or. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const | | Math::real MajorRadius() const | |
|
| { return Init() ? _a : Math::NaN<real>(); } | | { return Init() ? _a : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e f the flattening of the ellipsoid. This is the value | | * @return \e f the flattening of the ellipsoid. This is the value | |
| * inherited from the Geodesic object used in the constructor. | | * inherited from the Geodesic object used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Flattening() const | | Math::real Flattening() const | |
|
| { return Init() ? _f : Math::NaN<real>(); } | | { return Init() ? _f : Math::NaN(); } | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return \e r the inverse flattening of the ellipsoid. | | * @return \e r the inverse flattening of the ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real InverseFlattening() const | | Math::real InverseFlattening() const | |
|
| { return Init() ? 1/_f : Math::NaN<real>(); } | | { return Init() ? 1/_f : Math::NaN(); } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * @return \e caps the computational capabilities that this object was | | * @return \e caps the computational capabilities that this object was | |
| * constructed with. LATITUDE and AZIMUTH are always included. | | * constructed with. LATITUDE and AZIMUTH are always included. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| unsigned Capabilities() const { return _caps; } | | unsigned Capabilities() const { return _caps; } | |
| | | | |
| /** | | /** | |
| * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values. | | * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values. | |
| | | | |
End of changes. 12 change blocks. |
| 10 lines changed or deleted | | 12 lines changed or added | |
|
| GeodesicLineExact.hpp | | GeodesicLineExact.hpp | |
| | | | |
| skipping to change at line 41 | | skipping to change at line 41 | |
| * providing access to the functionality of GeodesicExact and | | * providing access to the functionality of GeodesicExact and | |
| * GeodesicLineExact (via the -E option). | | * GeodesicLineExact (via the -E option). | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT GeodesicLineExact { | | class GEOGRAPHICLIB_EXPORT GeodesicLineExact { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class GeodesicExact; | | friend class GeodesicExact; | |
| static const int nC4_ = GeodesicExact::nC4_; | | static const int nC4_ = GeodesicExact::nC4_; | |
| | | | |
|
| | | real tiny_; | |
| real _lat1, _lon1, _azi1; | | real _lat1, _lon1, _azi1; | |
| real _a, _f, _b, _c2, _f1, _e2, _salp0, _calp0, _k2, | | real _a, _f, _b, _c2, _f1, _e2, _salp0, _calp0, _k2, | |
| _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, | | _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, | |
| _somg1, _comg1, _cchi1, | | _somg1, _comg1, _cchi1, | |
| _A4, _B41, _E0, _D0, _H0, _E1, _D1, _H1; | | _A4, _B41, _E0, _D0, _H0, _E1, _D1, _H1; | |
| real _C4a[nC4_]; // all the elements of _C4a are used | | real _C4a[nC4_]; // all the elements of _C4a are used | |
| EllipticFunction _E; | | EllipticFunction _E; | |
| unsigned _caps; | | unsigned _caps; | |
| | | | |
| enum captype { | | enum captype { | |
| | | | |
| skipping to change at line 170 | | skipping to change at line 171 | |
| * length can only be specified in terms of arc length; | | * length can only be specified in terms of arc length; | |
| * - \e caps |= GeodesicLineExact::ALL for all of the above. | | * - \e caps |= GeodesicLineExact::ALL for all of the above. | |
| * . | | * . | |
| * The default value of \e caps is GeodesicLineExact::ALL. | | * The default value of \e caps is GeodesicLineExact::ALL. | |
| * | | * | |
| * If the point is at a pole, the azimuth is defined by keeping \e lon1 | | * If the point is at a pole, the azimuth is defined by keeping \e lon1 | |
| * fixed, writing \e lat1 = ±(90° − ε), and ta
king | | * fixed, writing \e lat1 = ±(90° − ε), and ta
king | |
| * the limit ε → 0+. | | * the limit ε → 0+. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| GeodesicLineExact(const GeodesicExact& g, real lat1, real lon1, real az
i1, | | GeodesicLineExact(const GeodesicExact& g, real lat1, real lon1, real az
i1, | |
|
| unsigned caps = ALL) | | unsigned caps = ALL); | |
| ; | | | |
| | | | |
| /** | | /** | |
| * A default constructor. If GeodesicLineExact::Position is called on
the | | * A default constructor. If GeodesicLineExact::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 | | * calculations). The object can be set with a call to | |
| * GeodesicExact::Line. Use Init() to test whether object is still in
this | | * GeodesicExact::Line. Use Init() to test whether object is still in
this | |
| * uninitialized state. | | * uninitialized state. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| GeodesicLineExact() : _caps(0U) {} | | GeodesicLineExact() : _caps(0U) {} | |
| ///@} | | ///@} | |
| | | | |
| skipping to change at line 497 | | skipping to change at line 497 | |
| | | | |
| /** | | /** | |
| * @return true if the object has been initialized. | | * @return true if the object has been initialized. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| bool Init() const { return _caps != 0U; } | | bool Init() const { return _caps != 0U; } | |
| | | | |
| /** | | /** | |
| * @return \e lat1 the latitude of point 1 (degrees). | | * @return \e lat1 the latitude of point 1 (degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Latitude() const | | Math::real Latitude() const | |
|
| { return Init() ? _lat1 : Math::NaN<real>(); } | | { return Init() ? _lat1 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e lon1 the longitude of point 1 (degrees). | | * @return \e lon1 the longitude of point 1 (degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Longitude() const | | Math::real Longitude() const | |
|
| { return Init() ? _lon1 : Math::NaN<real>(); } | | { return Init() ? _lon1 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e azi1 the azimuth (degrees) of the geodesic line at point
1. | | * @return \e azi1 the azimuth (degrees) of the geodesic line at point
1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Azimuth() const | | Math::real Azimuth() const | |
|
| { return Init() ? _azi1 : Math::NaN<real>(); } | | { return Init() ? _azi1 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e azi0 the azimuth (degrees) of the geodesic line as it cro
sses | | * @return \e azi0 the azimuth (degrees) of the geodesic line as it cro
sses | |
| * the equator in a northward direction. | | * the equator in a northward direction. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialAzimuth() const { | | Math::real EquatorialAzimuth() const { | |
|
| | | using std::atan2; | |
| return Init() ? | | return Init() ? | |
|
| atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>(); | | atan2(_salp0, _calp0) / Math::degree() : Math::NaN(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a1 the arc length (degrees) between the northward equator
ial | | * @return \e a1 the arc length (degrees) between the northward equator
ial | |
| * crossing and point 1. | | * crossing and point 1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialArc() const { | | Math::real EquatorialArc() const { | |
|
| | | using std::atan2; | |
| return Init() ? | | return Init() ? | |
|
| atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>(); | | atan2(_ssig1, _csig1) / Math::degree() : Math::NaN(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a the equatorial radius of the ellipsoid (meters). This
is | | * @return \e a the equatorial radius of the ellipsoid (meters). This
is | |
| * the value inherited from the GeodesicExact object used in the | | * the value inherited from the GeodesicExact object used in the | |
| * constructor. | | * constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const | | Math::real MajorRadius() const | |
|
| { return Init() ? _a : Math::NaN<real>(); } | | { return Init() ? _a : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e f the flattening of the ellipsoid. This is the value | | * @return \e f the flattening of the ellipsoid. This is the value | |
| * inherited from the GeodesicExact object used in the constructor. | | * inherited from the GeodesicExact object used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Flattening() const | | Math::real Flattening() const | |
|
| { return Init() ? _f : Math::NaN<real>(); } | | { return Init() ? _f : Math::NaN(); } | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return \e r the inverse flattening of the ellipsoid. | | * @return \e r the inverse flattening of the ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real InverseFlattening() const | | Math::real InverseFlattening() const | |
|
| { return Init() ? 1/_f : Math::NaN<real>(); } | | { return Init() ? 1/_f : Math::NaN(); } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * @return \e caps the computational capabilities that this object was | | * @return \e caps the computational capabilities that this object was | |
| * constructed with. LATITUDE and AZIMUTH are always included. | | * constructed with. LATITUDE and AZIMUTH are always included. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| unsigned Capabilities() const { return _caps; } | | unsigned Capabilities() const { return _caps; } | |
| | | | |
| /** | | /** | |
| * @param[in] testcaps a set of bitor'ed GeodesicLineExact::mask values
. | | * @param[in] testcaps a set of bitor'ed GeodesicLineExact::mask values
. | |
| | | | |
End of changes. 12 change blocks. |
| 10 lines changed or deleted | | 12 lines changed or added | |
|
| Geoid.hpp | | Geoid.hpp | |
| | | | |
| skipping to change at line 23 | | skipping to change at line 23 | |
| #include <vector> | | #include <vector> | |
| #include <fstream> | | #include <fstream> | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| | | | |
| #if defined(_MSC_VER) | | #if defined(_MSC_VER) | |
| // Squelch warnings about dll vs vector and constant conditional expression
s | | // Squelch warnings about dll vs vector and constant conditional expression
s | |
| # pragma warning (push) | | # pragma warning (push) | |
| # pragma warning (disable: 4251 4127) | | # pragma warning (disable: 4251 4127) | |
| #endif | | #endif | |
| | | | |
|
| #if !defined(PGM_PIXEL_WIDTH) | | #if !defined(GEOGRAPHICLIB_GEOID_PGM_PIXEL_WIDTH) | |
| /** | | /** | |
| * The size of the pixel data in the pgm data files for the geoids. 2 is t
he | | * The size of the pixel data in the pgm data files for the geoids. 2 is t
he | |
| * standard size corresponding to a maxval 2<sup>16</sup>−1. Setting
it | | * standard size corresponding to a maxval 2<sup>16</sup>−1. Setting
it | |
| * to 4 uses a maxval of 2<sup>32</sup>−1 and changes the extension f
or | | * to 4 uses a maxval of 2<sup>32</sup>−1 and changes the extension f
or | |
| * the data files from .pgm to .pgm4. Note that the format of these pgm4 f
iles | | * the data files from .pgm to .pgm4. Note that the format of these pgm4 f
iles | |
| * is a non-standard extension of the pgm format. | | * is a non-standard extension of the pgm format. | |
| **********************************************************************/ | | **********************************************************************/ | |
|
| # define PGM_PIXEL_WIDTH 2 | | # define GEOGRAPHICLIB_GEOID_PGM_PIXEL_WIDTH 2 | |
| #endif | | #endif | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Looking up the height of the geoid | | * \brief Looking up the height of the geoid | |
| * | | * | |
| * This class evaluated the height of one of the standard geoids, EGM84, | | * This class evaluated the height of one of the standard geoids, EGM84, | |
| * EGM96, or EGM2008 by bilinear or cubic interpolation into a rectangula
r | | * EGM96, or EGM2008 by bilinear or cubic interpolation into a rectangula
r | |
| * grid of data. These geoid models are documented in | | * grid of data. These geoid models are documented in | |
| | | | |
| skipping to change at line 86 | | skipping to change at line 86 | |
| * Example of use: | | * Example of use: | |
| * \include example-Geoid.cpp | | * \include example-Geoid.cpp | |
| * | | * | |
| * <a href="GeoidEval.1.html">GeoidEval</a> is a command-line utility | | * <a href="GeoidEval.1.html">GeoidEval</a> is a command-line utility | |
| * providing access to the functionality of Geoid. | | * providing access to the functionality of Geoid. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT Geoid { | | class GEOGRAPHICLIB_EXPORT Geoid { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| #if PGM_PIXEL_WIDTH != 4 | | #if GEOGRAPHICLIB_GEOID_PGM_PIXEL_WIDTH != 4 | |
| typedef unsigned short pixel_t; | | typedef unsigned short pixel_t; | |
| static const unsigned pixel_size_ = 2; | | static const unsigned pixel_size_ = 2; | |
| static const unsigned pixel_max_ = 0xffffu; | | static const unsigned pixel_max_ = 0xffffu; | |
| #else | | #else | |
| typedef unsigned pixel_t; | | typedef unsigned pixel_t; | |
| static const unsigned pixel_size_ = 4; | | static const unsigned pixel_size_ = 4; | |
| static const unsigned pixel_max_ = 0xffffffffu; | | static const unsigned pixel_max_ = 0xffffffffu; | |
| #endif | | #endif | |
| static const unsigned stencilsize_ = 12; | | static const unsigned stencilsize_ = 12; | |
| static const unsigned nterms_ = ((3 + 1) * (3 + 2))/2; // for a cubic f
it | | static const unsigned nterms_ = ((3 + 1) * (3 + 2))/2; // for a cubic f
it | |
|
| static const real c0_; | | static const int c0_; | |
| static const real c0n_; | | static const int c0n_; | |
| static const real c0s_; | | static const int c0s_; | |
| static const real c3_[stencilsize_ * nterms_]; | | static const int c3_[stencilsize_ * nterms_]; | |
| static const real c3n_[stencilsize_ * nterms_]; | | static const int c3n_[stencilsize_ * nterms_]; | |
| static const real c3s_[stencilsize_ * nterms_]; | | static const int c3s_[stencilsize_ * nterms_]; | |
| | | | |
| std::string _name, _dir, _filename; | | std::string _name, _dir, _filename; | |
| const bool _cubic; | | const bool _cubic; | |
| const real _a, _e2, _degree, _eps; | | const real _a, _e2, _degree, _eps; | |
| mutable std::ifstream _file; | | mutable std::ifstream _file; | |
| real _rlonres, _rlatres; | | real _rlonres, _rlatres; | |
| std::string _description, _datetime; | | std::string _description, _datetime; | |
| real _offset, _scale, _maxerror, _rmserror; | | real _offset, _scale, _maxerror, _rmserror; | |
| int _width, _height; | | int _width, _height; | |
| unsigned long long _datastart, _swidth; | | unsigned long long _datastart, _swidth; | |
| | | | |
| skipping to change at line 460 | | skipping to change at line 460 | |
| return _cache ? 90 - ( _yoffset + _ysize - 1 - _cubic) / _rlatres : 0
; | | return _cache ? 90 - ( _yoffset + _ysize - 1 - _cubic) / _rlatres : 0
; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a the equatorial radius of the WGS84 ellipsoid (meters). | | * @return \e a the equatorial radius of the WGS84 ellipsoid (meters). | |
| * | | * | |
| * (The WGS84 value is returned because the supported geoid models are
all | | * (The WGS84 value is returned because the supported geoid models are
all | |
| * based on this ellipsoid.) | | * based on this ellipsoid.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const | | Math::real MajorRadius() const | |
|
| { return Constants::WGS84_a<real>(); } | | { return Constants::WGS84_a(); } | |
| | | | |
| /** | | /** | |
| * @return \e f the flattening of the WGS84 ellipsoid. | | * @return \e f the flattening of the WGS84 ellipsoid. | |
| * | | * | |
| * (The WGS84 value is returned because the supported geoid models are
all | | * (The WGS84 value is returned because the supported geoid models are
all | |
| * based on this ellipsoid.) | | * based on this ellipsoid.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real Flattening() const { return Constants::WGS84_f<real>(); } | | Math::real Flattening() const { return Constants::WGS84_f(); } | |
| ///@} | | ///@} | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return \e r the inverse flattening of the WGS84 ellipsoid. | | * @return \e r the inverse flattening of the WGS84 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real InverseFlattening() const | | Math::real InverseFlattening() const | |
|
| { return 1/Constants::WGS84_f<real>(); } | | { return 1/Constants::WGS84_f(); } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * @return the default path for geoid data files. | | * @return the default path for geoid data files. | |
| * | | * | |
|
| * This is the value of the environment variable GEOID_PATH, if set; | | * This is the value of the environment variable GEOGRAPHICLIB_GEOID_PA | |
| * otherwise, it is $GEOGRAPHICLIB_DATA/geoids if the environment varia | | TH, | |
| ble | | * if set; otherwise, it is $GEOGRAPHICLIB_DATA/geoids if the environme | |
| * GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default | | nt | |
| * (/usr/local/share/GeographicLib/geoids on non-Windows systems and | | * variable GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time | |
| * C:/Documents and Settings/All Users/Application | | * default (/usr/local/share/GeographicLib/geoids on non-Windows system | |
| * Data/GeographicLib/geoids on Windows systems). | | s | |
| | | * and C:/ProgramData/GeographicLib/geoids on Windows systems). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static std::string DefaultGeoidPath(); | | static std::string DefaultGeoidPath(); | |
| | | | |
| /** | | /** | |
| * @return the default name for the geoid. | | * @return the default name for the geoid. | |
| * | | * | |
|
| * This is the value of the environment variable GEOID_NAME, if set, | | * This is the value of the environment variable GEOGRAPHICLIB_GEOID_NA | |
| * otherwise, it is "egm96-5". The Geoid class does not use this funct | | ME, | |
| ion; | | * if set; otherwise, it is "egm96-5". The Geoid class does not use th | |
| * it is just provided as a convenience for a calling program when | | is | |
| * constructing a Geoid object. | | * function; it is just provided as a convenience for a calling program | |
| | | * when constructing a Geoid object. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static std::string DefaultGeoidName(); | | static std::string DefaultGeoidName(); | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #if defined(_MSC_VER) | | #if defined(_MSC_VER) | |
| # pragma warning (pop) | | # pragma warning (pop) | |
| #endif | | #endif | |
| | | | |
End of changes. 9 change blocks. |
| 24 lines changed or deleted | | 26 lines changed or added | |
|
| Gnomonic.hpp | | Gnomonic.hpp | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 69 | |
| * | | * | |
| * This result applies for any surface. For an ellipsoid of revolution, | | * This result applies for any surface. For an ellipsoid of revolution, | |
| * consider all geodesics whose end points are within a distance \e r of
\e | | * consider all geodesics whose end points are within a distance \e r of
\e | |
| * C. For a given \e r, the deviation is maximum when the latitude of \e
C | | * C. For a given \e r, the deviation is maximum when the latitude of \e
C | |
| * is 45°, when endpoints are a distance \e r away, and when their | | * is 45°, when endpoints are a distance \e r away, and when their | |
| * azimuths from the center are ± 45° or ± 135°. | | * azimuths from the center are ± 45° or ± 135°. | |
| * To lowest order in \e r and the flattening \e f, the deviation is \e f | | * To lowest order in \e r and the flattening \e f, the deviation is \e f | |
| * (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r. | | * (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r. | |
| * | | * | |
| * The conversions all take place using a Geodesic object (by default | | * The conversions all take place using a Geodesic object (by default | |
|
| * Geodesic::WGS84). For more information on geodesics see \ref geodesic
. | | * Geodesic::WGS84()). For more information on geodesics see \ref geodes
ic. | |
| * | | * | |
| * <b>CAUTION:</b> The definition of this projection for a sphere is | | * <b>CAUTION:</b> The definition of this projection for a sphere is | |
| * standard. However, there is no standard for how it should be extended
to | | * standard. However, there is no standard for how it should be extended
to | |
| * an ellipsoid. The choices are: | | * an ellipsoid. The choices are: | |
| * - Declare that the projection is undefined for an ellipsoid. | | * - Declare that the projection is undefined for an ellipsoid. | |
| * - Project to a tangent plane from the center of the ellipsoid. This | | * - Project to a tangent plane from the center of the ellipsoid. This | |
| * causes great ellipses to appear as straight lines in the projection; | | * causes great ellipses to appear as straight lines in the projection; | |
| * i.e., it generalizes the spherical great circle to a great ellipse. | | * i.e., it generalizes the spherical great circle to a great ellipse. | |
| * This was proposed by independently by Bowring and Williams in 1997. | | * This was proposed by independently by Bowring and Williams in 1997. | |
| * - Project to the conformal sphere with the constant of integration cho
sen | | * - Project to the conformal sphere with the constant of integration cho
sen | |
| | | | |
| skipping to change at line 104 | | skipping to change at line 104 | |
| * \include example-Gnomonic.cpp | | * \include example-Gnomonic.cpp | |
| * | | * | |
| * <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utili
ty | | * <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utili
ty | |
| * providing access to the functionality of AzimuthalEquidistant, Gnomoni
c, | | * providing access to the functionality of AzimuthalEquidistant, Gnomoni
c, | |
| * and CassiniSoldner. | | * and CassiniSoldner. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT Gnomonic { | | class GEOGRAPHICLIB_EXPORT Gnomonic { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| | | real eps0_, eps_; | |
| Geodesic _earth; | | Geodesic _earth; | |
| real _a, _f; | | real _a, _f; | |
|
| static const real eps0_; | | | |
| static const real eps_; | | | |
| static const int numit_ = 10; | | static const int numit_ = 10; | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor for Gnomonic. | | * Constructor for Gnomonic. | |
| * | | * | |
| * @param[in] earth the Geodesic object to use for geodesic calculation
s. | | * @param[in] earth the Geodesic object to use for geodesic calculation
s. | |
| * By default this uses the WGS84 ellipsoid. | | * By default this uses the WGS84 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| explicit Gnomonic(const Geodesic& earth = Geodesic::WGS84) | | explicit Gnomonic(const Geodesic& earth = Geodesic::WGS84()); | |
| : _earth(earth) | | | |
| , _a(_earth.MajorRadius()) | | | |
| , _f(_earth.Flattening()) | | | |
| {} | | | |
| | | | |
| /** | | /** | |
| * Forward projection, from geographic to gnomonic. | | * Forward projection, from geographic to gnomonic. | |
| * | | * | |
| * @param[in] lat0 latitude of center point of projection (degrees). | | * @param[in] lat0 latitude of center point of projection (degrees). | |
| * @param[in] lon0 longitude of center point of projection (degrees). | | * @param[in] lon0 longitude of center point of projection (degrees). | |
| * @param[in] lat latitude of point (degrees). | | * @param[in] lat latitude of point (degrees). | |
| * @param[in] lon longitude of point (degrees). | | * @param[in] lon longitude of point (degrees). | |
| * @param[out] x easting of point (meters). | | * @param[out] x easting of point (meters). | |
| * @param[out] y northing of point (meters). | | * @param[out] y northing of point (meters). | |
| | | | |
| skipping to change at line 164 | | skipping to change at line 159 | |
| * @param[in] y northing of point (meters). | | * @param[in] y northing of point (meters). | |
| * @param[out] lat latitude of point (degrees). | | * @param[out] lat latitude of point (degrees). | |
| * @param[out] lon longitude of point (degrees). | | * @param[out] lon longitude of point (degrees). | |
| * @param[out] azi azimuth of geodesic at point (degrees). | | * @param[out] azi azimuth of geodesic at point (degrees). | |
| * @param[out] rk reciprocal of azimuthal scale at point. | | * @param[out] rk reciprocal of azimuthal scale at point. | |
| * | | * | |
| * \e lat0 should be in the range [−90°, 90°] and \e | | * \e lat0 should be in the range [−90°, 90°] and \e | |
| * lon0 should be in the range [−540°, 540°). \e lat | | * lon0 should be in the range [−540°, 540°). \e lat | |
| * will be in the range [−90°, 90°] and \e lon will | | * will be in the range [−90°, 90°] and \e lon will | |
| * be in the range [−180°, 180°). The scale of the | | * be in the range [−180°, 180°). The scale of the | |
|
| * projection is 1/\e rk<sup>2</sup> in the "radial" direction, \e azi | | * projection is 1/<i>rk</i><sup>2</sup> in the "radial" direction, \e
azi | |
| * clockwise from true north, and is 1/\e rk in the direction perpendic
ular | | * clockwise from true north, and is 1/\e rk in the direction perpendic
ular | |
| * to this. Even though all inputs should return a valid \e lat and \e | | * to this. Even though all inputs should return a valid \e lat and \e | |
| * lon, it's possible that the procedure fails to converge for very lar
ge | | * lon, it's possible that the procedure fails to converge for very lar
ge | |
| * \e x or \e y; in this case NaNs are returned for all the output | | * \e x or \e y; in this case NaNs are returned for all the output | |
| * arguments. A call to Reverse followed by a call to Forward will ret
urn | | * arguments. A call to Reverse followed by a call to Forward will ret
urn | |
| * the original (\e x, \e y) (to roundoff). | | * the original (\e x, \e y) (to roundoff). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Reverse(real lat0, real lon0, real x, real y, | | void Reverse(real lat0, real lon0, real x, real y, | |
| real& lat, real& lon, real& azi, real& rk) const; | | real& lat, real& lon, real& azi, real& rk) const; | |
| | | | |
| | | | |
End of changes. 5 change blocks. |
| 9 lines changed or deleted | | 4 lines changed or added | |
|
| LambertConformalConic.hpp | | LambertConformalConic.hpp | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| * EPSG:3364</a>) is obtained by: | | * EPSG:3364</a>) is obtained by: | |
| * \include example-LambertConformalConic.cpp | | * \include example-LambertConformalConic.cpp | |
| * | | * | |
| * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility | | * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility | |
| * providing access to the functionality of LambertConformalConic and | | * providing access to the functionality of LambertConformalConic and | |
| * AlbersEqualArea. | | * AlbersEqualArea. | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT LambertConformalConic { | | class GEOGRAPHICLIB_EXPORT LambertConformalConic { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| | | real eps_, epsx_, tol_, ahypover_; | |
| real _a, _f, _fm, _e2, _e, _e2m; | | real _a, _f, _fm, _e2, _e, _e2m; | |
| real _sign, _n, _nc, _t0nm1, _scale, _lat0, _k0; | | real _sign, _n, _nc, _t0nm1, _scale, _lat0, _k0; | |
| real _scbet0, _tchi0, _scchi0, _psi0, _nrho0, _drhomax; | | real _scbet0, _tchi0, _scchi0, _psi0, _nrho0, _drhomax; | |
|
| static const real eps_; | | | |
| static const real epsx_; | | | |
| static const real tol_; | | | |
| static const real ahypover_; | | | |
| static const int numit_ = 5; | | static const int numit_ = 5; | |
| static inline real hyp(real x) { return Math::hypot(real(1), x); } | | static inline real hyp(real x) { return Math::hypot(real(1), x); } | |
| // e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0 | | // e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0 | |
| // - sqrt(-e2) * atan( sqrt(-e2) * x) if f < 0 | | // - sqrt(-e2) * atan( sqrt(-e2) * x) if f < 0 | |
|
| inline real eatanhe(real x) const | | inline real eatanhe(real x) const { | |
| { return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); | | using std::atan; | |
| } | | return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * atan(_e * x); | |
| | | } | |
| // Divided differences | | // Divided differences | |
| // Definition: Df(x,y) = (f(x)-f(y))/(x-y) | | // Definition: Df(x,y) = (f(x)-f(y))/(x-y) | |
| // See: | | // See: | |
| // W. M. Kahan and R. J. Fateman, | | // W. M. Kahan and R. J. Fateman, | |
| // Symbolic computation of divided differences, | | // Symbolic computation of divided differences, | |
| // SIGSAM Bull. 33(3), 7-28 (1999) | | // SIGSAM Bull. 33(3), 7-28 (1999) | |
| // http://dx.doi.org/10.1145/334714.334716 | | // http://dx.doi.org/10.1145/334714.334716 | |
| // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf | | // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf | |
| // | | // | |
| // General rules | | // General rules | |
| | | | |
| skipping to change at line 103 | | skipping to change at line 102 | |
| // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^
2)) | | // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^
2)) | |
| static inline real Dsn(real x, real y, real sx, real sy) { | | static inline real Dsn(real x, real y, real sx, real sy) { | |
| // sx = x/hyp(x) | | // sx = x/hyp(x) | |
| real t = x * y; | | real t = x * y; | |
| return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) : | | return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) : | |
| (x - y != 0 ? (sx - sy) / (x - y) : 1); | | (x - y != 0 ? (sx - sy) / (x - y) : 1); | |
| } | | } | |
| // Dlog1p(x,y) = log1p((x-y)/(1+y)/(x-y) | | // Dlog1p(x,y) = log1p((x-y)/(1+y)/(x-y) | |
| static inline real Dlog1p(real x, real y) { | | static inline real Dlog1p(real x, real y) { | |
| real t = x - y; if (t < 0) { t = -t; y = x; } | | real t = x - y; if (t < 0) { t = -t; y = x; } | |
|
| return t != 0 ? Math::log1p(t / (1 + y)) / t : 1 / (1 + x); | | return t ? Math::log1p(t / (1 + y)) / t : 1 / (1 + x); | |
| } | | } | |
| // Dexp(x,y) = exp((x+y)/2) * 2*sinh((x-y)/2)/(x-y) | | // Dexp(x,y) = exp((x+y)/2) * 2*sinh((x-y)/2)/(x-y) | |
| static inline real Dexp(real x, real y) { | | static inline real Dexp(real x, real y) { | |
|
| | | using std::sinh; using std::exp; | |
| real t = (x - y)/2; | | real t = (x - y)/2; | |
|
| return (t != 0 ? sinh(t)/t : real(1)) * exp((x + y)/2); | | return (t ? sinh(t)/t : 1) * exp((x + y)/2); | |
| } | | } | |
| // Dsinh(x,y) = 2*sinh((x-y)/2)/(x-y) * cosh((x+y)/2) | | // Dsinh(x,y) = 2*sinh((x-y)/2)/(x-y) * cosh((x+y)/2) | |
| // cosh((x+y)/2) = (c+sinh(x)*sinh(y)/c)/2 | | // cosh((x+y)/2) = (c+sinh(x)*sinh(y)/c)/2 | |
| // c=sqrt((1+cosh(x))*(1+cosh(y))) | | // c=sqrt((1+cosh(x))*(1+cosh(y))) | |
| // cosh((x+y)/2) = sqrt( (sinh(x)*sinh(y) + cosh(x)*cosh(y) + 1)/2 ) | | // cosh((x+y)/2) = sqrt( (sinh(x)*sinh(y) + cosh(x)*cosh(y) + 1)/2 ) | |
| static inline real Dsinh(real x, real y, real sx, real sy, real cx, rea
l cy) | | static inline real Dsinh(real x, real y, real sx, real sy, real cx, rea
l cy) | |
|
| // sx = sinh(x), cx = cosh(x) | | // sx = sinh(x), cx = cosh(x) | |
| { | | { | |
| // real t = (x - y)/2, c = sqrt((1 + cx) * (1 + cy)); | | // real t = (x - y)/2, c = sqrt((1 + cx) * (1 + cy)); | |
|
| // return (t != 0 ? sinh(t)/t : real(1)) * (c + sx * sy / c) /2; | | // return (t ? sinh(t)/t : real(1)) * (c + sx * sy / c) /2; | |
| | | using std::sinh; using std::sqrt; | |
| real t = (x - y)/2; | | real t = (x - y)/2; | |
|
| return (t != 0 ? sinh(t)/t : real(1)) * sqrt((sx * sy + cx * cy + 1)
/2); | | return (t ? sinh(t)/t : 1) * sqrt((sx * sy + cx * cy + 1) /2); | |
| } | | } | |
| // Dasinh(x,y) = asinh((x-y)*(x+y)/(x*sqrt(1+y^2)+y*sqrt(1+x^2)))/(x-y) | | // Dasinh(x,y) = asinh((x-y)*(x+y)/(x*sqrt(1+y^2)+y*sqrt(1+x^2)))/(x-y) | |
| // = asinh((x*sqrt(1+y^2)-y*sqrt(1+x^2)))/(x-y) | | // = asinh((x*sqrt(1+y^2)-y*sqrt(1+x^2)))/(x-y) | |
| static inline real Dasinh(real x, real y, real hx, real hy) { | | static inline real Dasinh(real x, real y, real hx, real hy) { | |
| // hx = hyp(x) | | // hx = hyp(x) | |
| real t = x - y; | | real t = x - y; | |
|
| return t != 0 ? | | return t ? | |
| Math::asinh(x*y > 0 ? t * (x+y) / (x*hy + y*hx) : x*hy - y*hx) / t
: | | Math::asinh(x*y > 0 ? t * (x+y) / (x*hy + y*hx) : x*hy - y*hx) / t
: | |
| 1/hx; | | 1/hx; | |
| } | | } | |
| // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y) | | // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y) | |
| inline real Deatanhe(real x, real y) const { | | inline real Deatanhe(real x, real y) const { | |
| real t = x - y, d = 1 - _e2 * x * y; | | real t = x - y, d = 1 - _e2 * x * y; | |
|
| return t != 0 ? eatanhe(t / d) / t : _e2 / d; | | return t ? eatanhe(t / d) / t : _e2 / d; | |
| } | | } | |
| void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1); | | void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1); | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor with a single standard parallel. | | * Constructor with a single standard parallel. | |
| * | | * | |
| * @param[in] a equatorial radius of ellipsoid (meters). | | * @param[in] a equatorial radius of ellipsoid (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] stdlat standard parallel (degrees), the circle of tangenc
y. | | * @param[in] stdlat standard parallel (degrees), the circle of tangenc
y. | |
| * @param[in] k0 scale on the standard parallel. | | * @param[in] k0 scale on the standard parallel. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k0 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k0 is | |
| * not positive. | | * not positive. | |
| * @exception GeographicErr if \e stdlat is not in [−90°, | | * @exception GeographicErr if \e stdlat is not in [−90°, | |
| * 90°]. | | * 90°]. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| LambertConformalConic(real a, real f, real stdlat, real k0); | | LambertConformalConic(real a, real f, real stdlat, real k0); | |
| | | | |
| /** | | /** | |
| * Constructor with two standard parallels. | | * Constructor with two standard parallels. | |
| * | | * | |
| * @param[in] a equatorial radius of ellipsoid (meters). | | * @param[in] a equatorial radius of ellipsoid (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] stdlat1 first standard parallel (degrees). | | * @param[in] stdlat1 first standard parallel (degrees). | |
| * @param[in] stdlat2 second standard parallel (degrees). | | * @param[in] stdlat2 second standard parallel (degrees). | |
| * @param[in] k1 scale on the standard parallels. | | * @param[in] k1 scale on the standard parallels. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k1 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k1 is | |
| * not positive. | | * not positive. | |
| * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | | * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | |
| * [−90°, 90°], or if either \e stdlat1 or \e | | * [−90°, 90°], or if either \e stdlat1 or \e | |
| * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2. | | * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| LambertConformalConic(real a, real f, real stdlat1, real stdlat2, real
k1); | | LambertConformalConic(real a, real f, real stdlat1, real stdlat2, real
k1); | |
| | | | |
| /** | | /** | |
| * Constructor with two standard parallels specified by sines and cosin
es. | | * Constructor with two standard parallels specified by sines and cosin
es. | |
| * | | * | |
| * @param[in] a equatorial radius of ellipsoid (meters). | | * @param[in] a equatorial radius of ellipsoid (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] sinlat1 sine of first standard parallel. | | * @param[in] sinlat1 sine of first standard parallel. | |
| * @param[in] coslat1 cosine of first standard parallel. | | * @param[in] coslat1 cosine of first standard parallel. | |
| * @param[in] sinlat2 sine of second standard parallel. | | * @param[in] sinlat2 sine of second standard parallel. | |
| * @param[in] coslat2 cosine of second standard parallel. | | * @param[in] coslat2 cosine of second standard parallel. | |
| * @param[in] k1 scale on the standard parallels. | | * @param[in] k1 scale on the standard parallels. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k1 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k1 is | |
| * not positive. | | * not positive. | |
| * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | | * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in | |
| * [−90°, 90°], or if either \e stdlat1 or \e | | * [−90°, 90°], or if either \e stdlat1 or \e | |
| * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2. | | * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2. | |
| * | | * | |
| * This allows parallels close to the poles to be specified accurately. | | * This allows parallels close to the poles to be specified accurately. | |
| * This routine computes the latitude of origin and the scale at this | | * This routine computes the latitude of origin and the scale at this | |
| * latitude. In the case where \e lat1 and \e lat2 are different, the | | * latitude. In the case where \e lat1 and \e lat2 are different, the | |
| * errors in this routines are as follows: if \e dlat = abs(\e lat2 &mi
nus; | | * errors in this routines are as follows: if \e dlat = abs(\e lat2 &mi
nus; | |
| * \e lat1) ≤ 160° and max(abs(\e lat1), abs(\e lat2)) ≤ 90 | | * \e lat1) ≤ 160° and max(abs(\e lat1), abs(\e lat2)) ≤ 90 | |
| | | | |
| skipping to change at line 327 | | skipping to change at line 328 | |
| * latitude of origin. | | * latitude of origin. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real CentralScale() const { return _k0; } | | Math::real CentralScale() const { return _k0; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of LambertConformalConic with the WGS84 | | * A global instantiation of LambertConformalConic with the WGS84 | |
| * ellipsoid, \e stdlat = 0, and \e k0 = 1. This degenerates to the | | * ellipsoid, \e stdlat = 0, and \e k0 = 1. This degenerates to the | |
| * Mercator projection. | | * Mercator projection. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const LambertConformalConic Mercator; | | static const LambertConformalConic& Mercator(); | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP | | #endif // GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP | |
| | | | |
End of changes. 18 change blocks. |
| 28 lines changed or deleted | | 25 lines changed or added | |
|
| LocalCartesian.hpp | | LocalCartesian.hpp | |
| | | | |
| skipping to change at line 29 | | skipping to change at line 29 | |
| * \brief Local cartesian coordinates | | * \brief Local cartesian coordinates | |
| * | | * | |
| * Convert between geodetic coordinates latitude = \e lat, longitude = \e | | * Convert between geodetic coordinates latitude = \e lat, longitude = \e | |
| * lon, height = \e h (measured vertically from the surface of the ellips
oid) | | * lon, height = \e h (measured vertically from the surface of the ellips
oid) | |
| * to local cartesian coordinates (\e x, \e y, \e z). The origin of loca
l | | * to local cartesian coordinates (\e x, \e y, \e z). The origin of loca
l | |
| * cartesian coordinate system is at \e lat = \e lat0, \e lon = \e lon0,
\e h | | * cartesian coordinate system is at \e lat = \e lat0, \e lon = \e lon0,
\e h | |
| * = \e h0. The \e z axis is normal to the ellipsoid; the \e y axis point
s | | * = \e h0. The \e z axis is normal to the ellipsoid; the \e y axis point
s | |
| * due north. The plane \e z = - \e h0 is tangent to the ellipsoid. | | * due north. The plane \e z = - \e h0 is tangent to the ellipsoid. | |
| * | | * | |
| * The conversions all take place via geocentric coordinates using a | | * The conversions all take place via geocentric coordinates using a | |
|
| * Geocentric object (by default Geocentric::WGS84). | | * Geocentric object (by default Geocentric::WGS84()). | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-LocalCartesian.cpp | | * \include example-LocalCartesian.cpp | |
| * | | * | |
| * <a href="CartConvert.1.html">CartConvert</a> is a command-line utility | | * <a href="CartConvert.1.html">CartConvert</a> is a command-line utility | |
| * providing access to the functionality of Geocentric and LocalCartesian
. | | * providing access to the functionality of Geocentric and LocalCartesian
. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT LocalCartesian { | | class GEOGRAPHICLIB_EXPORT LocalCartesian { | |
| private: | | private: | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| void MatrixMultiply(real M[dim2_]) const; | | void MatrixMultiply(real M[dim2_]) const; | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor setting the origin. | | * Constructor setting the origin. | |
| * | | * | |
| * @param[in] lat0 latitude at origin (degrees). | | * @param[in] lat0 latitude at origin (degrees). | |
| * @param[in] lon0 longitude at origin (degrees). | | * @param[in] lon0 longitude at origin (degrees). | |
| * @param[in] h0 height above ellipsoid at origin (meters); default 0. | | * @param[in] h0 height above ellipsoid at origin (meters); default 0. | |
| * @param[in] earth Geocentric object for the transformation; default | | * @param[in] earth Geocentric object for the transformation; default | |
|
| * Geocentric::WGS84. | | * Geocentric::WGS84(). | |
| * | | * | |
| * \e lat0 should be in the range [−90°, 90°]; \e | | * \e lat0 should be in the range [−90°, 90°]; \e | |
| * lon0 should be in the range [−540°, 540°). | | * lon0 should be in the range [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| LocalCartesian(real lat0, real lon0, real h0 = 0, | | LocalCartesian(real lat0, real lon0, real h0 = 0, | |
|
| const Geocentric& earth = Geocentric::WGS84) | | const Geocentric& earth = Geocentric::WGS84()) | |
| : _earth(earth) | | : _earth(earth) | |
| { Reset(lat0, lon0, h0); } | | { Reset(lat0, lon0, h0); } | |
| | | | |
| /** | | /** | |
| * Default constructor. | | * Default constructor. | |
| * | | * | |
| * @param[in] earth Geocentric object for the transformation; default | | * @param[in] earth Geocentric object for the transformation; default | |
|
| * Geocentric::WGS84. | | * Geocentric::WGS84(). | |
| * | | * | |
| * Sets \e lat0 = 0, \e lon0 = 0, \e h0 = 0. | | * Sets \e lat0 = 0, \e lon0 = 0, \e h0 = 0. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| explicit LocalCartesian(const Geocentric& earth = Geocentric::WGS84) | | explicit LocalCartesian(const Geocentric& earth = Geocentric::WGS84()) | |
| : _earth(earth) | | : _earth(earth) | |
| { Reset(real(0), real(0), real(0)); } | | { Reset(real(0), real(0), real(0)); } | |
| | | | |
| /** | | /** | |
| * Reset the origin. | | * Reset the origin. | |
| * | | * | |
| * @param[in] lat0 latitude at origin (degrees). | | * @param[in] lat0 latitude at origin (degrees). | |
| * @param[in] lon0 longitude at origin (degrees). | | * @param[in] lon0 longitude at origin (degrees). | |
| * @param[in] h0 height above ellipsoid at origin (meters); default 0. | | * @param[in] h0 height above ellipsoid at origin (meters); default 0. | |
| * | | * | |
| | | | |
| skipping to change at line 190 | | skipping to change at line 190 | |
| * | | * | |
| * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can | | * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can | |
| * express \e v as \e column vectors in one of two ways | | * express \e v as \e column vectors in one of two ways | |
| * - in east, north, up coordinates (where the components are relative
to a | | * - in east, north, up coordinates (where the components are relative
to a | |
| * local coordinate system at (\e lat, \e lon, \e h)); call this | | * local coordinate system at (\e lat, \e lon, \e h)); call this | |
| * representation \e v1. | | * representation \e v1. | |
| * - in \e x, \e y, \e z coordinates (where the components are relative
to | | * - in \e x, \e y, \e z coordinates (where the components are relative
to | |
| * the local coordinate system at (\e lat0, \e lon0, \e h0)); call th
is | | * the local coordinate system at (\e lat0, \e lon0, \e h0)); call th
is | |
| * representation \e v0. | | * representation \e v0. | |
| * . | | * . | |
|
| * Then we have \e v1 = \e M<sup>T</sup> ⋅ \e v0, where \e | | * Then we have \e v1 = <i>M</i><sup>T</sup> ⋅ \e v0, where | |
| * M<sup>T</sup> is the transpose of \e M. | | * <i>M</i><sup>T</sup> is the transpose of \e M. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Reverse(real x, real y, real z, real& lat, real& lon, real& h, | | void Reverse(real x, real y, real z, real& lat, real& lon, real& h, | |
| std::vector<real>& M) | | std::vector<real>& M) | |
| const { | | const { | |
| if (M.end() == M.begin() + dim2_) { | | if (M.end() == M.begin() + dim2_) { | |
| real t[dim2_]; | | real t[dim2_]; | |
| IntReverse(x, y, z, lat, lon, h, t); | | IntReverse(x, y, z, lat, lon, h, t); | |
| std::copy(t, t + dim2_, M.begin()); | | std::copy(t, t + dim2_, M.begin()); | |
| } else | | } else | |
| IntReverse(x, y, z, lat, lon, h, NULL); | | IntReverse(x, y, z, lat, lon, h, NULL); | |
| | | | |
End of changes. 6 change blocks. |
| 7 lines changed or deleted | | 7 lines changed or added | |
|
| MGRS.hpp | | MGRS.hpp | |
| | | | |
| skipping to change at line 34 | | skipping to change at line 34 | |
| /** | | /** | |
| * \brief Convert between UTM/UPS and %MGRS | | * \brief Convert between UTM/UPS and %MGRS | |
| * | | * | |
| * MGRS is defined in Chapter 3 of | | * MGRS is defined in Chapter 3 of | |
| * - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill, | | * - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill, | |
| * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/T
M8358_1.pdf"> | | * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/T
M8358_1.pdf"> | |
| * Datums, Ellipsoids, Grids, and Grid Reference Systems</a>, | | * Datums, Ellipsoids, Grids, and Grid Reference Systems</a>, | |
| * Defense Mapping Agency, Technical Manual TM8358.1 (1990). | | * Defense Mapping Agency, Technical Manual TM8358.1 (1990). | |
| * . | | * . | |
| * This document has been updated by the two NGA documents | | * This document has been updated by the two NGA documents | |
|
| * - <a href="https://nsgreg.nga.mil/doc/view?i=4057"> Universal Grids an | | * - <a href="http://earth-info.nga.mil/GandG/publications/NGA_STND_0037_ | |
| d | | 2_0_0_GRIDS/NGA.STND.0037_2.0.0_GRIDS.pdf"> | |
| * Grid Reference Systems</a>, NGA.STND.0037_2.0.0_GRIDS (2014). | | * Universal Grids and Grid Reference Systems</a>, | |
| * - <a href="https://nsgreg.nga.mil/doc/view?i=4056"> The Universal Grid | | * NGA.STND.0037_2.0.0_GRIDS (2014). | |
| s | | * - <a href="http://earth-info.nga.mil/GandG/publications/NGA_SIG_0012_2 | |
| * and the Transverse Mercator and Polar Stereographic Map Projections< | | _0_0_UTMUPS/NGA.SIG.0012_2.0.0_UTMUPS.pdf"> | |
| /a>, | | * The Universal Grids and the Transverse Mercator and Polar Stereograp | |
| * NGA.SIG.0012_2.0.0_UTMUPS (2014). | | hic | |
| | | * Map Projections</a>, NGA.SIG.0012_2.0.0_UTMUPS (2014). | |
| * | | * | |
| * This implementation has the following properties: | | * This implementation has the following properties: | |
| * - The conversions are closed, i.e., output from Forward is legal input
for | | * - The conversions are closed, i.e., output from Forward is legal input
for | |
| * Reverse and vice versa. Conversion in both directions preserve the | | * Reverse and vice versa. Conversion in both directions preserve the | |
| * UTM/UPS selection and the UTM zone. | | * UTM/UPS selection and the UTM zone. | |
| * - Forward followed by Reverse and vice versa is approximately the | | * - Forward followed by Reverse and vice versa is approximately the | |
| * identity. (This is affected in predictable ways by errors in | | * identity. (This is affected in predictable ways by errors in | |
| * determining the latitude band and by loss of precision in the MGRS | | * determining the latitude band and by loss of precision in the MGRS | |
| * coordinates.) | | * coordinates.) | |
| * - All MGRS coordinates truncate to legal 100 km blocks. All MGRS | | * - All MGRS coordinates truncate to legal 100 km blocks. All MGRS | |
| | | | |
| skipping to change at line 71 | | skipping to change at line 72 | |
| * - Inconsistent rules are used to determine the whether a particular MG
RS | | * - Inconsistent rules are used to determine the whether a particular MG
RS | |
| * coordinate is legal. A more systematic approach is taken here. | | * coordinate is legal. A more systematic approach is taken here. | |
| * - The underlying projections are not very accurately implemented. | | * - The underlying projections are not very accurately implemented. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-MGRS.cpp | | * \include example-MGRS.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT MGRS { | | class GEOGRAPHICLIB_EXPORT MGRS { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| // The smallest length s.t., 1.0e7 - eps_ < 1.0e7 (approx 1.9 nm) | | // The smallest length s.t., 1.0e7 - eps() < 1.0e7 (approx 1.9 nm) | |
| static const real eps_; | | static inline real eps() { | |
| // The smallest angle s.t., 90 - eps_ < 90 (approx 50e-12 arcsec) | | using std::pow; | |
| static const real angeps_; | | // 25 = ceil(log_2(2e7)) -- use half circumference here because | |
| | | // northing 195e5 is a legal in the "southern" hemisphere. | |
| | | static const real eps = pow(real(0.5), Math::digits() - 25); | |
| | | return eps; | |
| | | } | |
| | | // The smallest angle s.t., 90 - angeps() < 90 (approx 50e-12 arcsec) | |
| | | static inline real angeps() { | |
| | | using std::pow; | |
| | | // 7 = ceil(log_2(90)) | |
| | | static const real angeps = pow(real(0.5), Math::digits() - 7); | |
| | | return angeps; | |
| | | } | |
| static const std::string hemispheres_; | | static const std::string hemispheres_; | |
| static const std::string utmcols_[3]; | | static const std::string utmcols_[3]; | |
| static const std::string utmrow_; | | static const std::string utmrow_; | |
| static const std::string upscols_[4]; | | static const std::string upscols_[4]; | |
| static const std::string upsrows_[2]; | | static const std::string upsrows_[2]; | |
| static const std::string latband_; | | static const std::string latband_; | |
| static const std::string upsband_; | | static const std::string upsband_; | |
| static const std::string digits_; | | static const std::string digits_; | |
| | | | |
| static const int mineasting_[4]; | | static const int mineasting_[4]; | |
| | | | |
| skipping to change at line 106 | | skipping to change at line 118 | |
| // Maximum precision is um | | // Maximum precision is um | |
| maxprec_ = 5 + 6, | | maxprec_ = 5 + 6, | |
| }; | | }; | |
| static void CheckCoords(bool utmp, bool& northp, real& x, real& y); | | static void CheckCoords(bool utmp, bool& northp, real& x, real& y); | |
| static int UTMRow(int iband, int icol, int irow); | | static int UTMRow(int iband, int icol, int irow); | |
| | | | |
| friend class UTMUPS; // UTMUPS::StandardZone calls LatitudeBand | | friend class UTMUPS; // UTMUPS::StandardZone calls LatitudeBand | |
| // Return latitude band number [-10, 10) for the given latitude (degree
s). | | // Return latitude band number [-10, 10) for the given latitude (degree
s). | |
| // The bands are reckoned in include their southern edges. | | // The bands are reckoned in include their southern edges. | |
| static int LatitudeBand(real lat) { | | static int LatitudeBand(real lat) { | |
|
| int ilat = int(std::floor(lat)); | | using std::floor; | |
| | | int ilat = int(floor(lat)); | |
| return (std::max)(-10, (std::min)(9, (ilat + 80)/8 - 10)); | | return (std::max)(-10, (std::min)(9, (ilat + 80)/8 - 10)); | |
| } | | } | |
| // Return approximate latitude band number [-10, 10) for the given nort
hing | | // Return approximate latitude band number [-10, 10) for the given nort
hing | |
| // (meters). With this rule, each 100km tile would have a unique band | | // (meters). With this rule, each 100km tile would have a unique band | |
| // letter corresponding to the latitude at the center of the tile. Thi
s | | // letter corresponding to the latitude at the center of the tile. Thi
s | |
| // function isn't currently used. | | // function isn't currently used. | |
| static int ApproxLatitudeBand(real y) { | | static int ApproxLatitudeBand(real y) { | |
| // northing at tile center in units of tile = 100km | | // northing at tile center in units of tile = 100km | |
|
| real ya = std::floor( (std::min)(real(88), std::abs(y/tile_)) ) + | | using std::floor; using std::abs; | |
| | | real ya = floor( (std::min)(real(88), abs(y/tile_)) ) + | |
| real(0.5); | | real(0.5); | |
| // convert to lat (mult by 90/100) and then to band (divide by 8) | | // convert to lat (mult by 90/100) and then to band (divide by 8) | |
| // the +1 fine tunes the boundary between bands 3 and 4 | | // the +1 fine tunes the boundary between bands 3 and 4 | |
|
| int b = int(std::floor( ((ya * 9 + 1) / 10) / 8 )); | | int b = int(floor( ((ya * 9 + 1) / 10) / 8 )); | |
| // For the northern hemisphere we have | | // For the northern hemisphere we have | |
| // band rows num | | // band rows num | |
| // N 0 0:8 9 | | // N 0 0:8 9 | |
| // P 1 9:17 9 | | // P 1 9:17 9 | |
| // Q 2 18:26 9 | | // Q 2 18:26 9 | |
| // R 3 27:34 8 | | // R 3 27:34 8 | |
| // S 4 35:43 9 | | // S 4 35:43 9 | |
| // T 5 44:52 9 | | // T 5 44:52 9 | |
| // U 6 53:61 9 | | // U 6 53:61 9 | |
| // V 7 62:70 9 | | // V 7 62:70 9 | |
| | | | |
End of changes. 5 change blocks. |
| 15 lines changed or deleted | | 29 lines changed or added | |
|
| Math.hpp | | Math.hpp | |
| | | | |
| skipping to change at line 20 | | skipping to change at line 20 | |
| // Constants.hpp includes Math.hpp. Place this include outside Math.hpp's | | // Constants.hpp includes Math.hpp. Place this include outside Math.hpp's | |
| // include guard to enforce this ordering. | | // include guard to enforce this ordering. | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| | | | |
| #if !defined(GEOGRAPHICLIB_MATH_HPP) | | #if !defined(GEOGRAPHICLIB_MATH_HPP) | |
| #define GEOGRAPHICLIB_MATH_HPP 1 | | #define GEOGRAPHICLIB_MATH_HPP 1 | |
| | | | |
| /** | | /** | |
| * Are C++11 math functions available? | | * Are C++11 math functions available? | |
| **********************************************************************/ | | **********************************************************************/ | |
|
| #if !defined(GEOGRAPHICLIB_CPLUSPLUS11_MATH) | | #if !defined(GEOGRAPHICLIB_CXX11_MATH) | |
| // Recent versions of g++ -std=c++11 (4.7 and later?) set __cplusplus to 20
1103 | | // Recent versions of g++ -std=c++11 (4.7 and later?) set __cplusplus to 20
1103 | |
| // and support the new C++11 mathematical functions, std::atanh, etc. Howe
ver | | // and support the new C++11 mathematical functions, std::atanh, etc. Howe
ver | |
| // the Android toolchain, which uses g++ -std=c++11 (4.8 as of 2014-03-11, | | // the Android toolchain, which uses g++ -std=c++11 (4.8 as of 2014-03-11, | |
| // according to Pullan Lu), does not support std::atanh. Android toolchain
s | | // according to Pullan Lu), does not support std::atanh. Android toolchain
s | |
| // might define __ANDROID__ or ANDROID; so need to check both. | | // might define __ANDROID__ or ANDROID; so need to check both. | |
| # if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 \ | | # if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 \ | |
|
| && __cplusplus >= 201103 && !(defined(__ANDROID__) || defined(ANDROID)) | | && __cplusplus >= 201103 && \ | |
| # define GEOGRAPHICLIB_CPLUSPLUS11_MATH 1 | | !(defined(__ANDROID__) || defined(ANDROID) || defined(__CYGWIN__)) | |
| | | # define GEOGRAPHICLIB_CXX11_MATH 1 | |
| // Visual C++ 12 supports these functions | | // Visual C++ 12 supports these functions | |
| # elif defined(_MSC_VER) && _MSC_VER >= 1800 | | # elif defined(_MSC_VER) && _MSC_VER >= 1800 | |
|
| # define GEOGRAPHICLIB_CPLUSPLUS11_MATH 1 | | # define GEOGRAPHICLIB_CXX11_MATH 1 | |
| # else | | # else | |
|
| # define GEOGRAPHICLIB_CPLUSPLUS11_MATH 0 | | # define GEOGRAPHICLIB_CXX11_MATH 0 | |
| # endif | | # endif | |
| #endif | | #endif | |
| | | | |
|
| #if !defined(WORDS_BIGENDIAN) | | #if !defined(GEOGRAPHICLIB_WORDS_BIGENDIAN) | |
| # define WORDS_BIGENDIAN 0 | | # define GEOGRAPHICLIB_WORDS_BIGENDIAN 0 | |
| #endif | | #endif | |
| | | | |
|
| #if !defined(HAVE_LONG_DOUBLE) | | #if !defined(GEOGRAPHICLIB_HAVE_LONG_DOUBLE) | |
| # define HAVE_LONG_DOUBLE 0 | | # define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 0 | |
| #endif | | #endif | |
| | | | |
| #if !defined(GEOGRAPHICLIB_PRECISION) | | #if !defined(GEOGRAPHICLIB_PRECISION) | |
| /** | | /** | |
| * The precision of floating point numbers used in %GeographicLib. 1 means | | * The precision of floating point numbers used in %GeographicLib. 1 means | |
| * 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 | | * for long double to be used, GEOGRAPHICLIB_HAVE_LONG_DOUBLE needs to be | |
| that | | * defined. Note that with Microsoft Visual Studio, long double is the sam | |
| * with Microsoft Visual Studio, long double is the same as double. | | e as | |
| | | * double. | |
| **********************************************************************/ | | **********************************************************************/ | |
| # define GEOGRAPHICLIB_PRECISION 2 | | # define GEOGRAPHICLIB_PRECISION 2 | |
| #endif | | #endif | |
| | | | |
| #include <cmath> | | #include <cmath> | |
| #include <algorithm> | | #include <algorithm> | |
| #include <limits> | | #include <limits> | |
|
| #if defined(_LIBCPP_VERSION) | | | |
| #include <type_traits> | | #if GEOGRAPHICLIB_PRECISION == 4 | |
| | | #include <boost/multiprecision/float128.hpp> | |
| | | #include <boost/math/special_functions/hypot.hpp> | |
| | | #include <boost/math/special_functions/expm1.hpp> | |
| | | #include <boost/math/special_functions/log1p.hpp> | |
| | | #include <boost/math/special_functions/atanh.hpp> | |
| | | #include <boost/math/special_functions/asinh.hpp> | |
| | | #include <boost/math/special_functions/cbrt.hpp> | |
| | | #elif GEOGRAPHICLIB_PRECISION == 5 | |
| | | #include <mpreal.h> | |
| | | #endif | |
| | | | |
| | | #if GEOGRAPHICLIB_PRECISION > 3 | |
| | | // volatile keyword makes no sense for multiprec types | |
| | | #define GEOGRAPHICLIB_VOLATILE | |
| | | // Signal a convergence failure with multiprec types by throwing an excepti | |
| | | on | |
| | | // at loop exit. | |
| | | #define GEOGRAPHICLIB_PANIC \ | |
| | | (throw GeographicLib::GeographicErr("Convergence failure"), false) | |
| | | #else | |
| | | #define GEOGRAPHICLIB_VOLATILE volatile | |
| | | // Ignore convergence failures with standard floating points types by allow | |
| | | ing | |
| | | // loop to exit cleanly. | |
| | | #define GEOGRAPHICLIB_PANIC false | |
| #endif | | #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. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-Math.cpp | | * \include example-Math.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT Math { | | class GEOGRAPHICLIB_EXPORT Math { | |
| private: | | private: | |
| void dummy() { | | void dummy() { | |
|
| STATIC_ASSERT(GEOGRAPHICLIB_PRECISION >= 1 && | | GEOGRAPHICLIB_STATIC_ASSERT(GEOGRAPHICLIB_PRECISION >= 1 && | |
| GEOGRAPHICLIB_PRECISION <= 3, | | GEOGRAPHICLIB_PRECISION <= 5, | |
| "Bad value of precision"); | | "Bad value of precision"); | |
| } | | } | |
| Math(); // Disable constructor | | Math(); // Disable constructor | |
| public: | | public: | |
| | | | |
|
| #if HAVE_LONG_DOUBLE | | #if GEOGRAPHICLIB_HAVE_LONG_DOUBLE | |
| /** | | /** | |
| * The extended precision type for real numbers, used for some testing. | | * The extended precision type for real numbers, used for some testing. | |
| * This is long double on computers with this type; otherwise it is dou
ble. | | * This is long double on computers with this type; otherwise it is dou
ble. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| typedef long double extended; | | typedef long double extended; | |
| #else | | #else | |
| typedef double extended; | | typedef double extended; | |
| #endif | | #endif | |
| | | | |
| #if GEOGRAPHICLIB_PRECISION == 2 | | #if GEOGRAPHICLIB_PRECISION == 2 | |
| | | | |
| skipping to change at line 108 | | skipping to change at line 133 | |
| * The real type for %GeographicLib. Nearly all the testing has been do
ne | | * The real type for %GeographicLib. Nearly all the testing has been do
ne | |
| * with \e real = double. However, the algorithms should also work wit
h | | * with \e real = double. However, the algorithms should also work wit
h | |
| * float and long double (where available). (<b>CAUTION</b>: reasonabl
e | | * float and long double (where available). (<b>CAUTION</b>: reasonabl
e | |
| * accuracy typically cannot be obtained using floats.) | | * accuracy typically cannot be obtained using floats.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| typedef double real; | | typedef double real; | |
| #elif GEOGRAPHICLIB_PRECISION == 1 | | #elif GEOGRAPHICLIB_PRECISION == 1 | |
| typedef float real; | | typedef float real; | |
| #elif GEOGRAPHICLIB_PRECISION == 3 | | #elif GEOGRAPHICLIB_PRECISION == 3 | |
| typedef extended real; | | typedef extended real; | |
|
| | | #elif GEOGRAPHICLIB_PRECISION == 4 | |
| | | typedef boost::multiprecision::float128 real; | |
| | | #elif GEOGRAPHICLIB_PRECISION == 5 | |
| | | typedef mpfr::mpreal real; | |
| #else | | #else | |
| typedef double real; | | typedef double real; | |
| #endif | | #endif | |
| | | | |
| /** | | /** | |
|
| | | * @return the number of bits of precision in a real number. | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline int digits() { | |
| | | #if GEOGRAPHICLIB_PRECISION != 5 | |
| | | return std::numeric_limits<real>::digits; | |
| | | #else | |
| | | return std::numeric_limits<real>::digits(); | |
| | | #endif | |
| | | } | |
| | | | |
| | | /** | |
| | | * Set the binary precision of a real number. | |
| | | * | |
| | | * @param[in] ndigits the number of bits of precision. | |
| | | * @return the resulting number of bits of precision. | |
| | | * | |
| | | * This only has an effect when GEOGRAPHICLIB_PRECISION == 5. | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline int set_digits(int ndigits) { | |
| | | #if GEOGRAPHICLIB_PRECISION != 5 | |
| | | (void)ndigits; | |
| | | #else | |
| | | mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2); | |
| | | #endif | |
| | | return digits(); | |
| | | } | |
| | | | |
| | | /** | |
| | | * @return the number of decimal digits of precision in a real number. | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline int digits10() { | |
| | | #if GEOGRAPHICLIB_PRECISION != 5 | |
| | | return std::numeric_limits<real>::digits10; | |
| | | #else | |
| | | return std::numeric_limits<real>::digits10(); | |
| | | #endif | |
| | | } | |
| | | | |
| | | /** | |
| | | * Number of additional decimal digits of precision for real relative t | |
| | | o | |
| | | * double (0 for float). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline int extra_digits() { | |
| | | return | |
| | | digits10() > std::numeric_limits<double>::digits10 ? | |
| | | digits10() - std::numeric_limits<double>::digits10 : 0; | |
| | | } | |
| | | | |
| | | #if GEOGRAPHICLIB_PRECISION <= 3 | |
| | | /** | |
| * Number of additional decimal digits of precision of real relative to | | * Number of additional decimal digits of precision of real relative to | |
| * double (0 for float). | | * double (0 for float). | |
|
| | | * | |
| | | * <b>DEPRECATED</b>: use extra_digits() instead | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static const int extradigits = | | static const int extradigits = | |
| std::numeric_limits<real>::digits10 > | | std::numeric_limits<real>::digits10 > | |
| std::numeric_limits<double>::digits10 ? | | std::numeric_limits<double>::digits10 ? | |
| std::numeric_limits<real>::digits10 - | | std::numeric_limits<real>::digits10 - | |
| std::numeric_limits<double>::digits10 : 0; | | std::numeric_limits<double>::digits10 : 0; | |
|
| | | #endif | |
| | | | |
| /** | | /** | |
| * true if the machine is big-endian. | | * true if the machine is big-endian. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const bool bigendian = WORDS_BIGENDIAN; | | static const bool bigendian = GEOGRAPHICLIB_WORDS_BIGENDIAN; | |
| | | | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return π. | | * @return π. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| template<typename T> static inline T pi() | | template<typename T> static inline T pi() { | |
| { return std::atan2(T(0), -T(1)); } | | using std::atan2; | |
| | | static const T pi = atan2(T(0), T(-1)); | |
| | | return pi; | |
| | | } | |
| /** | | /** | |
| * A synonym for pi<real>(). | | * A synonym for pi<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline real pi() { return pi<real>(); } | | static inline real pi() { return pi<real>(); } | |
| | | | |
| /** | | /** | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return the number of radians in a degree. | | * @return the number of radians in a degree. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| template<typename T> static inline T degree() | | template<typename T> static inline T degree() { | |
| { return pi<T>() / T(180); } | | static const T degree = pi<T>() / 180; | |
| | | return degree; | |
| | | } | |
| /** | | /** | |
| * A synonym for degree<real>(). | | * A synonym for degree<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline real degree() { return degree<real>(); } | | static inline real degree() { return degree<real>(); } | |
| | | | |
| /** | | /** | |
| * Square a number. | | * Square a number. | |
| * | | * | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @return <i>x</i><sup>2</sup>. | | * @return <i>x</i><sup>2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T sq(T x) | | template<typename T> static inline T sq(T x) | |
| { return x * x; } | | { return x * x; } | |
| | | | |
|
| #if defined(DOXYGEN) | | | |
| /** | | /** | |
| * The hypotenuse function avoiding underflow and overflow. | | * The hypotenuse function avoiding underflow and overflow. | |
| * | | * | |
| * @tparam T the type of the arguments and the returned value. | | * @tparam T the type of the arguments and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
| * @return sqrt(<i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>). | | * @return sqrt(<i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T hypot(T x, T y) { | | template<typename T> static inline T hypot(T x, T y) { | |
|
| x = std::abs(x); y = std::abs(y); | | #if GEOGRAPHICLIB_CXX11_MATH | |
| T a = (std::max)(x, y), b = (std::min)(x, y) / (a ? a : 1); | | using std::hypot; return hypot(x, y); | |
| return a * std::sqrt(1 + b * b); | | #else | |
| | | using std::abs; using std::sqrt; | |
| | | x = abs(x); y = abs(y); | |
| | | if (x < y) std::swap(x, y); // Now x >= y >= 0 | |
| | | y /= (x ? x : 1); | |
| | | return x * sqrt(1 + y * y); | |
| // For an alternative (square-root free) method see | | // For an alternative (square-root free) method see | |
| // C. Moler and D. Morrision (1983) http://dx.doi.org/10.1147/rd.276.
0577 | | // C. Moler and D. Morrision (1983) http://dx.doi.org/10.1147/rd.276.
0577 | |
| // and A. A. Dubrulle (1983) http://dx.doi.org/10.1147/rd.276.0582 | | // and A. A. Dubrulle (1983) http://dx.doi.org/10.1147/rd.276.0582 | |
|
| } | | | |
| #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH || (defined(_MSC_VER) && _MSC_VER >= 1 | | | |
| 700) | | | |
| template<typename T> static inline T hypot(T x, T y) | | | |
| { return std::hypot(x, y); } | | | |
| # if HAVE_LONG_DOUBLE && defined(_MSC_VER) && _MSC_VER == 1700 | | | |
| // Visual C++ 11 doesn't have a long double overload for std::hypot -- | | | |
| // reported to MS on 2013-07-18 | | | |
| // http://connect.microsoft.com/VisualStudio/feedback/details/794416 | | | |
| // (Visual C++ 12 is OK) Suppress the resulting "loss of data warning" | | | |
| with | | | |
| static inline long double hypot(long double x, long double y) | | | |
| { return std::hypot(double(x), double(y)); } | | | |
| # endif | | | |
| #elif defined(_MSC_VER) | | | |
| static inline double hypot(double x, double y) | | | |
| { return _hypot(x, y); } | | | |
| # if _MSC_VER < 1400 | | | |
| // Visual C++ 7.1/VS .NET 2003 does not have _hypotf() | | | |
| static inline float hypot(float x, float y) | | | |
| { return float(_hypot(x, y)); } | | | |
| # else | | | |
| static inline float hypot(float x, float y) | | | |
| { return _hypotf(x, y); } | | | |
| # endif | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double hypot(long double x, long double y) | | | |
| { return _hypot(double(x), double(y)); } // Suppress loss of data warni | | | |
| ng | | | |
| # endif | | | |
| #else | | | |
| // Use overloading to define generic versions | | | |
| static inline double hypot(double x, double y) | | | |
| { return ::hypot(x, y); } | | | |
| static inline float hypot(float x, float y) | | | |
| { return ::hypotf(x, y); } | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double hypot(long double x, long double y) | | | |
| { return ::hypotl(x, y); } | | | |
| # endif | | | |
| #endif | | #endif | |
|
| | | } | |
| | | | |
|
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA
TH) | | | |
| /** | | /** | |
|
| * exp(\e x) − 1 accurate near \e x = 0. This is taken from | | * exp(\e x) − 1 accurate near \e x = 0. | |
| * N. J. Higham, Accuracy and Stability of Numerical Algorithms, 2nd | | | |
| * Edition (SIAM, 2002), Sec 1.14.1, p 19. | | | |
| * | | * | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @return exp(\e x) − 1. | | * @return exp(\e x) − 1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T expm1(T x) { | | template<typename T> static inline T expm1(T x) { | |
|
| | | #if GEOGRAPHICLIB_CXX11_MATH | |
| | | using std::expm1; return expm1(x); | |
| | | #else | |
| | | using std::exp; using std::abs; using std::log; | |
| volatile T | | volatile T | |
|
| y = std::exp(x), | | y = exp(x), | |
| z = y - 1; | | z = y - 1; | |
| // The reasoning here is similar to that for log1p. The expression | | // The reasoning here is similar to that for log1p. The expression | |
| // mathematically reduces to exp(x) - 1, and the factor z/log(y) = (y
- | | // mathematically reduces to exp(x) - 1, and the factor z/log(y) = (y
- | |
| // 1)/log(y) is a slowly varying quantity near y = 1 and is accuratel
y | | // 1)/log(y) is a slowly varying quantity near y = 1 and is accuratel
y | |
| // computed. | | // computed. | |
|
| return std::abs(x) > 1 ? z : (z == 0 ? x : x * z / std::log(y)); | | return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y)); | |
| } | | | |
| #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH | | | |
| template<typename T> static inline T expm1(T x) | | | |
| { return std::expm1(x); } | | | |
| #else | | | |
| static inline double expm1(double x) { return ::expm1(x); } | | | |
| static inline float expm1(float x) { return ::expm1f(x); } | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double expm1(long double x) | | | |
| { return ::expm1l(x); } | | | |
| # endif | | | |
| #endif | | #endif | |
|
| | | } | |
| | | | |
|
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA
TH) | | | |
| /** | | /** | |
| * log(1 + \e x) accurate near \e x = 0. | | * log(1 + \e x) accurate near \e x = 0. | |
| * | | * | |
|
| * This is taken from D. Goldberg, | | | |
| * <a href="http://dx.doi.org/10.1145/103162.103163">What every compute | | | |
| r | | | |
| * scientist should know about floating-point arithmetic</a> (1991), | | | |
| * Theorem 4. See also, Higham (op. cit.), Answer to Problem 1.5, p 52 | | | |
| 8. | | | |
| * | | | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @return log(1 + \e x). | | * @return log(1 + \e x). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T log1p(T x) { | | template<typename T> static inline T log1p(T x) { | |
|
| | | #if GEOGRAPHICLIB_CXX11_MATH | |
| | | using std::log1p; return log1p(x); | |
| | | #else | |
| | | using std::log; | |
| volatile T | | volatile T | |
| y = 1 + x, | | y = 1 + x, | |
| z = y - 1; | | z = y - 1; | |
| // Here's the explanation for this magic: y = 1 + z, exactly, and z | | // Here's the explanation for this magic: y = 1 + z, exactly, and z | |
| // approx x, thus log(y)/z (which is nearly constant near z = 0) retu
rns | | // approx x, thus log(y)/z (which is nearly constant near z = 0) retu
rns | |
| // a good approximation to the true log(1 + x)/x. The multiplication
x * | | // a good approximation to the true log(1 + x)/x. The multiplication
x * | |
| // (log(y)/z) introduces little additional error. | | // (log(y)/z) introduces little additional error. | |
|
| return z == 0 ? x : x * std::log(y) / z; | | return z == 0 ? x : x * log(y) / z; | |
| } | | | |
| #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH | | | |
| template<typename T> static inline T log1p(T x) | | | |
| { return std::log1p(x); } | | | |
| #else | | | |
| static inline double log1p(double x) { return ::log1p(x); } | | | |
| static inline float log1p(float x) { return ::log1pf(x); } | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double log1p(long double x) | | | |
| { return ::log1pl(x); } | | | |
| # endif | | | |
| #endif | | #endif | |
|
| | | } | |
| | | | |
|
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA
TH) | | | |
| /** | | /** | |
|
| * The inverse hyperbolic sine function. This is defined in terms of | | * The inverse hyperbolic sine function. | |
| * Math::log1p(\e x) in order to maintain accuracy near \e x = 0. In | | | |
| * addition, the odd parity of the function is enforced. | | | |
| * | | * | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @return asinh(\e x). | | * @return asinh(\e x). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T asinh(T x) { | | template<typename T> static inline T asinh(T x) { | |
|
| T y = std::abs(x); // Enforce odd parity | | #if GEOGRAPHICLIB_CXX11_MATH | |
| | | using std::asinh; return asinh(x); | |
| | | #else | |
| | | using std::abs; T y = abs(x); // Enforce odd parity | |
| y = log1p(y * (1 + y/(hypot(T(1), y) + 1))); | | y = log1p(y * (1 + y/(hypot(T(1), y) + 1))); | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
|
| } | | | |
| #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH | | | |
| template<typename T> static inline T asinh(T x) | | | |
| { return std::asinh(x); } | | | |
| #else | | | |
| static inline double asinh(double x) { return ::asinh(x); } | | | |
| static inline float asinh(float x) { return ::asinhf(x); } | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double asinh(long double x) | | | |
| { return ::asinhl(x); } | | | |
| # endif | | | |
| #endif | | #endif | |
|
| | | } | |
| | | | |
|
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA
TH) | | | |
| /** | | /** | |
|
| * The inverse hyperbolic tangent function. This is defined in terms o | | * The inverse hyperbolic tangent function. | |
| f | | | |
| * Math::log1p(\e x) in order to maintain accuracy near \e x = 0. In | | | |
| * addition, the odd parity of the function is enforced. | | | |
| * | | * | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @return atanh(\e x). | | * @return atanh(\e x). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T atanh(T x) { | | template<typename T> static inline T atanh(T x) { | |
|
| T y = std::abs(x); // Enforce odd parity | | #if GEOGRAPHICLIB_CXX11_MATH | |
| | | using std::atanh; return atanh(x); | |
| | | #else | |
| | | using std::abs; T y = abs(x); // Enforce odd parity | |
| y = log1p(2 * y/(1 - y))/2; | | y = log1p(2 * y/(1 - y))/2; | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
|
| } | | | |
| #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH | | | |
| template<typename T> static inline T atanh(T x) | | | |
| { return std::atanh(x); } | | | |
| #else | | | |
| static inline double atanh(double x) { return ::atanh(x); } | | | |
| static inline float atanh(float x) { return ::atanhf(x); } | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double atanh(long double x) | | | |
| { return ::atanhl(x); } | | | |
| # endif | | | |
| #endif | | #endif | |
|
| | | } | |
| | | | |
|
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA
TH) | | | |
| /** | | /** | |
| * The cube root function. | | * The cube root function. | |
| * | | * | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] x | | * @param[in] x | |
| * @return the real cube root of \e x. | | * @return the real cube root of \e x. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T cbrt(T x) { | | template<typename T> static inline T cbrt(T x) { | |
|
| T y = std::pow(std::abs(x), 1/T(3)); // Return the real cube root | | #if GEOGRAPHICLIB_CXX11_MATH | |
| | | using std::cbrt; return cbrt(x); | |
| | | #else | |
| | | using std::abs; using std::pow; | |
| | | T y = pow(abs(x), 1/T(3)); // Return the real cube root | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
|
| } | | | |
| #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH | | | |
| template<typename T> static inline T cbrt(T x) | | | |
| { return std::cbrt(x); } | | | |
| #else | | | |
| static inline double cbrt(double x) { return ::cbrt(x); } | | | |
| static inline float cbrt(float x) { return ::cbrtf(x); } | | | |
| # if HAVE_LONG_DOUBLE | | | |
| static inline long double cbrt(long double x) { return ::cbrtl(x); } | | | |
| # endif | | | |
| #endif | | #endif | |
|
| | | } | |
| | | | |
| /** | | /** | |
| * The error-free sum of two numbers. | | * The error-free sum of two numbers. | |
| * | | * | |
| * @tparam T the type of the argument and the returned value. | | * @tparam T the type of the argument and the returned value. | |
| * @param[in] u | | * @param[in] u | |
| * @param[in] v | | * @param[in] v | |
| * @param[out] t the exact error given by (\e u + \e v) - \e s. | | * @param[out] t the exact error given by (\e u + \e v) - \e s. | |
| * @return \e s = round(\e u + \e v). | | * @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 | | * 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.) | | * the same as one of the first two arguments.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T sum(T u, T v, T& t) { | | template<typename T> static inline T sum(T u, T v, T& t) { | |
|
| volatile T s = u + v; | | GEOGRAPHICLIB_VOLATILE T s = u + v; | |
| volatile T up = s - v; | | GEOGRAPHICLIB_VOLATILE T up = s - v; | |
| volatile T vpp = s - up; | | GEOGRAPHICLIB_VOLATILE T vpp = s - up; | |
| up -= u; | | up -= u; | |
| vpp -= v; | | vpp -= v; | |
| t = -(up + vpp); | | t = -(up + vpp); | |
| // u + v = s + t | | // u + v = s + t | |
| // = round(u + v) + t | | // = round(u + v) + t | |
| return s; | | return s; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Normalize an angle (restricted input range). | | * Normalize an angle (restricted input range). | |
| | | | |
| skipping to change at line 404 | | skipping to change at line 412 | |
| /** | | /** | |
| * Normalize an arbitrary angle. | | * Normalize an arbitrary angle. | |
| * | | * | |
| * @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°, 180°). | | * @return the angle reduced to the range [−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) | | template<typename T> static inline T AngNormalize2(T x) | |
|
| { return AngNormalize<T>(std::fmod(x, T(360))); } | | { using std::fmod; return AngNormalize<T>(fmod(x, T(360))); } | |
| | | | |
| /** | | /** | |
| * Difference of two angles reduced to [−180°, 180°] | | * Difference of two angles reduced to [−180°, 180°] | |
| * | | * | |
| * @tparam T the type of the arguments and returned value. | | * @tparam T the type of the arguments and returned value. | |
| * @param[in] x the first angle in degrees. | | * @param[in] x the first angle in degrees. | |
| * @param[in] y the second angle in degrees. | | * @param[in] y the second angle in degrees. | |
| * @return \e y − \e x, reduced to the range [−180°, | | * @return \e y − \e x, reduced to the range [−180°, | |
| * 180°]. | | * 180°]. | |
| * | | * | |
| | | | |
| skipping to change at line 430 | | skipping to change at line 438 | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T AngDiff(T x, T y) { | | template<typename T> static inline T AngDiff(T x, T y) { | |
| T t, d = sum(-x, y, t); | | T t, d = sum(-x, y, t); | |
| if ((d - T(180)) + t > T(0)) // y - x > 180 | | if ((d - T(180)) + t > T(0)) // y - x > 180 | |
| d -= T(360); // exact | | d -= T(360); // exact | |
| else if ((d + T(180)) + t <= T(0)) // y - x <= -180 | | else if ((d + T(180)) + t <= T(0)) // y - x <= -180 | |
| d += T(360); // exact | | d += T(360); // exact | |
| return d + t; | | 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) { | | template<typename T> static inline bool isfinite(T x) { | |
|
| return std::abs(x) <= (std::numeric_limits<T>::max)(); | | #if GEOGRAPHICLIB_CXX11_MATH | |
| } | | using std::isfinite; return isfinite(x); | |
| #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH) | | | |
| template<typename T> static inline bool isfinite(T x) { | | | |
| 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) { | | | |
| return std::isfinite(x); | | | |
| } | | | |
| template<typename T> static inline | | | |
| typename std::enable_if<!std::is_floating_point<T>::value, bool>::type | | | |
| isfinite(T /*x*/) { | | | |
| return true; | | | |
| } | | | |
| #else | | #else | |
|
| template<typename T> static inline bool isfinite(T x) { | | using std::abs; | |
| return std::isfinite(x); | | return abs(x) <= (std::numeric_limits<T>::max)(); | |
| } | | | |
| #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() { | | template<typename T> static inline T NaN() { | |
| 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() : | |
| | | | |
| skipping to change at line 490 | | skipping to change at line 478 | |
| static inline real NaN() { return NaN<real>(); } | | static inline real NaN() { return NaN<real>(); } | |
| | | | |
| /** | | /** | |
| * Test for NaN. | | * Test for NaN. | |
| * | | * | |
| * @tparam T the type of the argument. | | * @tparam T the type of the argument. | |
| * @param[in] x | | * @param[in] x | |
| * @return true if argument is a NaN. | | * @return true if argument is a NaN. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline bool isnan(T x) { | | template<typename T> static inline bool isnan(T x) { | |
|
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA | | #if GEOGRAPHICLIB_CXX11_MATH | |
| TH) | | using std::isnan; return isnan(x); | |
| return x != x; | | | |
| #else | | #else | |
|
| return std::isnan(x); | | return x != x; | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Infinity | | * Infinity | |
| * | | * | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
| * @return infinity if available, otherwise return the max real. | | * @return infinity if available, otherwise return the max real. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T infinity() { | | template<typename T> static inline T infinity() { | |
| | | | |
| skipping to change at line 530 | | skipping to change at line 518 | |
| template<typename T> static inline T swab(T x) { | | template<typename T> static inline T swab(T x) { | |
| union { | | union { | |
| T r; | | T r; | |
| unsigned char c[sizeof(T)]; | | unsigned char c[sizeof(T)]; | |
| } b; | | } b; | |
| b.r = x; | | b.r = x; | |
| for (int i = sizeof(T)/2; i--; ) | | for (int i = sizeof(T)/2; i--; ) | |
| std::swap(b.c[i], b.c[sizeof(T) - 1 - i]); | | std::swap(b.c[i], b.c[sizeof(T) - 1 - i]); | |
| return b.r; | | return b.r; | |
| } | | } | |
|
| | | | |
| | | #if GEOGRAPHICLIB_PRECISION == 4 | |
| | | typedef boost::math::policies::policy | |
| | | < boost::math::policies::domain_error | |
| | | <boost::math::policies::errno_on_error>, | |
| | | boost::math::policies::pole_error | |
| | | <boost::math::policies::errno_on_error>, | |
| | | boost::math::policies::overflow_error | |
| | | <boost::math::policies::errno_on_error>, | |
| | | boost::math::policies::evaluation_error | |
| | | <boost::math::policies::errno_on_error> > | |
| | | boost_special_functions_policy; | |
| | | | |
| | | static inline real hypot(real x, real y) | |
| | | { return boost::math::hypot(x, y, boost_special_functions_policy()); } | |
| | | | |
| | | static inline real expm1(real x) | |
| | | { return boost::math::expm1(x, boost_special_functions_policy()); } | |
| | | | |
| | | static inline real log1p(real x) | |
| | | { return boost::math::log1p(x, boost_special_functions_policy()); } | |
| | | | |
| | | static inline real asinh(real x) | |
| | | { return boost::math::asinh(x, boost_special_functions_policy()); } | |
| | | | |
| | | static inline real atanh(real x) | |
| | | { return boost::math::atanh(x, boost_special_functions_policy()); } | |
| | | | |
| | | static inline real cbrt(real x) | |
| | | { return boost::math::cbrt(x, boost_special_functions_policy()); } | |
| | | | |
| | | static inline bool isnan(real x) { return boost::math::isnan(x); } | |
| | | | |
| | | static inline bool isfinite(real x) { return boost::math::isfinite(x); | |
| | | } | |
| | | #endif | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_MATH_HPP | | #endif // GEOGRAPHICLIB_MATH_HPP | |
| | | | |
End of changes. 55 change blocks. |
| 183 lines changed or deleted | | 206 lines changed or added | |
|
| NormalGravity.hpp | | NormalGravity.hpp | |
| /** | | /** | |
| * \file NormalGravity.hpp | | * \file NormalGravity.hpp | |
| * \brief Header for GeographicLib::NormalGravity class | | * \brief Header for GeographicLib::NormalGravity class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un | | * Copyright (c) Charles Karney (2011-2014) <charles@karney.com> and licens | |
| der | | ed | |
| * the MIT/X11 License. For more information, see | | * under the MIT/X11 License. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_NORMALGRAVITY_HPP) | | #if !defined(GEOGRAPHICLIB_NORMALGRAVITY_HPP) | |
| #define GEOGRAPHICLIB_NORMALGRAVITY_HPP 1 | | #define GEOGRAPHICLIB_NORMALGRAVITY_HPP 1 | |
| | | | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| #include <GeographicLib/Geocentric.hpp> | | #include <GeographicLib/Geocentric.hpp> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| skipping to change at line 68 | | skipping to change at line 68 | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT NormalGravity { | | class GEOGRAPHICLIB_EXPORT NormalGravity { | |
| private: | | private: | |
| static const int maxit_ = 10; | | static const int maxit_ = 10; | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class GravityModel; | | friend class GravityModel; | |
| real _a, _GM, _omega, _f, _J2, _omega2, _aomega2; | | real _a, _GM, _omega, _f, _J2, _omega2, _aomega2; | |
| real _e2, _ep2, _b, _E, _U0, _gammae, _gammap, _q0, _m, _k, _fstar; | | real _e2, _ep2, _b, _E, _U0, _gammae, _gammap, _q0, _m, _k, _fstar; | |
| Geocentric _earth; | | Geocentric _earth; | |
|
| static Math::real qf(real ep2); | | // (atan(y)-(y-y^3/3))/y^5 (y = sqrt(x)) = 1/5-y/7+y^2/9-y^3/11... | |
| static Math::real qpf(real ep2); | | static real atan5(real x); | |
| Math::real Jn(int n) const; | | // (atan(y)-(y-y^3/3+y^5/5))/y^7 (y = sqrt(x)) = -1/7+x/9-x^2/11+x^3/13 | |
| | | ... | |
| | | static real atan7(real x); | |
| | | static real qf(real ep2); | |
| | | static real dq(real ep2); | |
| | | static real qpf(real ep2); | |
| | | real Jn(int n) const; | |
| public: | | public: | |
| | | | |
| /** \name Setting up the normal gravity | | /** \name Setting up the normal gravity | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * Constructor for the normal gravity. | | * Constructor for the normal gravity. | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
| * @param[in] GM mass constant of the ellipsoid | | * @param[in] GM mass constant of the ellipsoid | |
| * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \
e G | | * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \
e G | |
| * the gravitational constant and \e M the mass of the earth (usually | | * the gravitational constant and \e M the mass of the earth (usually | |
| * including the mass of the earth's atmosphere). | | * including the mass of the earth's atmosphere). | |
| * @param[in] omega the angular velocity (rad s<sup>−1</sup>). | | * @param[in] omega the angular velocity (rad s<sup>−1</sup>). | |
| * @param[in] f the flattening of the ellipsoid. | | * @param[in] f the flattening of the ellipsoid. | |
|
| * @param[in] J2 dynamical form factor. | | * @param[in] J2 the dynamical form factor. | |
| * @exception if \e a is not positive or the other constants are | | * @exception if \e a is not positive or the other constants are | |
| * inconsistent (see below). | | * inconsistent (see below). | |
| * | | * | |
|
| * Exactly one of \e f and \e J2 should be positive and this will be us | | * If \e omega is non-zero, then exactly one of \e f and \e J2 should b | |
| ed | | e | |
| * to define the ellipsoid. The shape of the ellipsoid can be given in | | * positive and this will be used to define the ellipsoid. The shape o | |
| one | | f | |
| * of two ways: | | * the ellipsoid can be given in one of two ways: | |
| * - geometrically, the ellipsoid is defined by the flattening \e f = (
\e a | | * - geometrically, the ellipsoid is defined by the flattening \e f = (
\e a | |
| * − \e b) / \e a, where \e a and \e b are the equatorial radiu
s | | * − \e b) / \e a, where \e a and \e b are the equatorial radiu
s | |
| * and the polar semi-axis. | | * and the polar semi-axis. | |
| * - physically, the ellipsoid is defined by the dynamical form factor | | * - physically, the ellipsoid is defined by the dynamical form factor | |
| * <i>J</i><sub>2</sub> = (\e C − \e A) / <i>Ma</i><sup>2</sup>
, | | * <i>J</i><sub>2</sub> = (\e C − \e A) / <i>Ma</i><sup>2</sup>
, | |
| * where \e A and \e C are the equatorial and polar moments of inerti
a | | * where \e A and \e C are the equatorial and polar moments of inerti
a | |
| * and \e M is the mass of the earth. | | * and \e M is the mass of the earth. | |
|
| | | * . | |
| | | * If \e omega, \e f, and \e J2 are all zero, then the ellipsoid become | |
| | | s a | |
| | | * sphere. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| NormalGravity(real a, real GM, real omega, real f, real J2); | | NormalGravity(real a, real GM, real omega, real f, real J2); | |
| | | | |
| /** | | /** | |
| * A default constructor for the normal gravity. This sets up an | | * A default constructor for the normal gravity. This sets up an | |
| * uninitialized object and is used by GravityModel which constructs th
is | | * uninitialized object and is used by GravityModel which constructs th
is | |
| * object before it has read in the parameters for the reference ellips
oid. | | * object before it has read in the parameters for the reference ellips
oid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| NormalGravity() : _a(-1) {} | | NormalGravity() : _a(-1) {} | |
| ///@} | | ///@} | |
| | | | |
| skipping to change at line 228 | | skipping to change at line 236 | |
| /** | | /** | |
| * @return true if the object has been initialized. | | * @return true if the object has been initialized. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| bool Init() const { return _a > 0; } | | bool Init() const { return _a > 0; } | |
| | | | |
| /** | | /** | |
| * @return \e a the equatorial radius of the ellipsoid (meters). This
is | | * @return \e a the equatorial radius of the ellipsoid (meters). This
is | |
| * the value used in the constructor. | | * the value used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const | | Math::real MajorRadius() const | |
|
| { return Init() ? _a : Math::NaN<real>(); } | | { return Init() ? _a : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return \e GM the mass constant of the ellipsoid | | * @return \e GM the mass constant of the ellipsoid | |
| * (m<sup>3</sup> s<sup>−2</sup>). This is the value used in t
he | | * (m<sup>3</sup> s<sup>−2</sup>). This is the value used in t
he | |
| * constructor. | | * constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MassConstant() const | | Math::real MassConstant() const | |
|
| { return Init() ? _GM : Math::NaN<real>(); } | | { return Init() ? _GM : Math::NaN(); } | |
| | | | |
| /** | | /** | |
|
| * @return \e J<sub>n</sub> the dynamical form factors of the ellipsoid | | * @return <i>J</i><sub><i>n</i></sub> the dynamical form factors of th | |
| . | | e | |
| | | * ellipsoid. | |
| * | | * | |
| * If \e n = 2 (the default), this is the value of <i>J</i><sub>2</sub> | | * If \e n = 2 (the default), this is the value of <i>J</i><sub>2</sub> | |
| * used in the constructor. Otherwise it is the zonal coefficient of t
he | | * used in the constructor. Otherwise it is the zonal coefficient of t
he | |
| * Legendre harmonic sum of the normal gravitational potential. Note t
hat | | * Legendre harmonic sum of the normal gravitational potential. Note t
hat | |
|
| * \e J<sub>n</sub> = 0 if \e n is odd. In most gravity applications, | | * <i>J</i><sub><i>n</i></sub> = 0 if \e n is odd. In most gravity | |
| * fully normalized Legendre functions are used and the corresponding | | * applications, fully normalized Legendre functions are used and the | |
| * coefficient is <i>C</i><sub><i>n</i>0</sub> = −\e J<sub>n</sub | | * corresponding coefficient is <i>C</i><sub><i>n</i>0</sub> = | |
| > / | | * −<i>J</i><sub><i>n</i></sub> / sqrt(2 \e n + 1). | |
| * sqrt(2 \e n + 1). | | | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real DynamicalFormFactor(int n = 2) const | | Math::real DynamicalFormFactor(int n = 2) const | |
|
| { return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN<real>(); } | | { return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return ω the angular velocity of the ellipsoid (rad | | * @return ω the angular velocity of the ellipsoid (rad | |
| * s<sup>−1</sup>). This is the value used in the constructor. | | * s<sup>−1</sup>). This is the value used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real AngularVelocity() const | | Math::real AngularVelocity() const | |
|
| { return Init() ? _omega : Math::NaN<real>(); } | | { return Init() ? _omega : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return <i>f</i> the flattening of the ellipsoid (\e a − \e b)
/\e | | * @return <i>f</i> the flattening of the ellipsoid (\e a − \e b)
/\e | |
| * a. | | * a. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Flattening() const | | Math::real Flattening() const | |
|
| { return Init() ? _f : Math::NaN<real>(); } | | { return Init() ? _f : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return γ<sub>e</sub> the normal gravity at equator (m | | * @return γ<sub>e</sub> the normal gravity at equator (m | |
| * s<sup>−2</sup>). | | * s<sup>−2</sup>). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialGravity() const | | Math::real EquatorialGravity() const | |
|
| { return Init() ? _gammae : Math::NaN<real>(); } | | { return Init() ? _gammae : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return γ<sub>p</sub> the normal gravity at poles (m | | * @return γ<sub>p</sub> the normal gravity at poles (m | |
| * s<sup>−2</sup>). | | * s<sup>−2</sup>). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real PolarGravity() const | | Math::real PolarGravity() const | |
|
| { return Init() ? _gammap : Math::NaN<real>(); } | | { return Init() ? _gammap : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return <i>f*</i> the gravity flattening (γ<sub>p</sub> &minus
; | | * @return <i>f*</i> the gravity flattening (γ<sub>p</sub> &minus
; | |
| * γ<sub>e</sub>) / γ<sub>e</sub>. | | * γ<sub>e</sub>) / γ<sub>e</sub>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real GravityFlattening() const | | Math::real GravityFlattening() const | |
|
| { return Init() ? _fstar : Math::NaN<real>(); } | | { return Init() ? _fstar : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return <i>U</i><sub>0</sub> the constant normal potential for the | | * @return <i>U</i><sub>0</sub> the constant normal potential for the | |
| * surface of the ellipsoid (m<sup>2</sup> s<sup>−2</sup>). | | * surface of the ellipsoid (m<sup>2</sup> s<sup>−2</sup>). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real SurfacePotential() const | | Math::real SurfacePotential() const | |
|
| { return Init() ? _U0 : Math::NaN<real>(); } | | { return Init() ? _U0 : Math::NaN(); } | |
| | | | |
| /** | | /** | |
| * @return the Geocentric object used by this instance. | | * @return the Geocentric object used by this instance. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| const Geocentric& Earth() const { return _earth; } | | const Geocentric& Earth() const { return _earth; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of NormalGravity for the WGS84 ellipsoid. | | * A global instantiation of NormalGravity for the WGS84 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const NormalGravity WGS84; | | static const NormalGravity& WGS84(); | |
| | | | |
| /** | | /** | |
| * A global instantiation of NormalGravity for the GRS80 ellipsoid. | | * A global instantiation of NormalGravity for the GRS80 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const NormalGravity GRS80; | | static const NormalGravity& GRS80(); | |
| | | | |
| | | /** | |
| | | * Compute the flattening from the dynamical form factor. | |
| | | * | |
| | | * @param[in] a equatorial radius (meters). | |
| | | * @param[in] GM mass constant of the ellipsoid | |
| | | * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \ | |
| | | e G | |
| | | * the gravitational constant and \e M the mass of the earth (usually | |
| | | * including the mass of the earth's atmosphere). | |
| | | * @param[in] omega the angular velocity (rad s<sup>−1</sup>). | |
| | | * @param[in] J2 the dynamical form factor. | |
| | | * @return \e f the flattening of the ellipsoid. | |
| | | ********************************************************************** | |
| | | / | |
| | | static Math::real J2ToFlattening(real a, real GM, real omega, real J2); | |
| | | | |
| | | /** | |
| | | * Compute the dynamical form factor from the flattening. | |
| | | * | |
| | | * @param[in] a equatorial radius (meters). | |
| | | * @param[in] GM mass constant of the ellipsoid | |
| | | * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \ | |
| | | e G | |
| | | * the gravitational constant and \e M the mass of the earth (usually | |
| | | * including the mass of the earth's atmosphere). | |
| | | * @param[in] omega the angular velocity (rad s<sup>−1</sup>). | |
| | | * @param[in] f the flattening of the ellipsoid. | |
| | | * @return \e J2 the dynamical form factor. | |
| | | ********************************************************************** | |
| | | / | |
| | | static Math::real FlatteningToJ2(real a, real GM, real omega, real f); | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_NORMALGRAVITY_HPP | | #endif // GEOGRAPHICLIB_NORMALGRAVITY_HPP | |
| | | | |
End of changes. 18 change blocks. |
| 30 lines changed or deleted | | 72 lines changed or added | |
|
| OSGB.hpp | | OSGB.hpp | |
| | | | |
| skipping to change at line 49 | | skipping to change at line 49 | |
| * datum (and vice versa). | | * datum (and vice versa). | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-OSGB.cpp | | * \include example-OSGB.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT OSGB { | | class GEOGRAPHICLIB_EXPORT OSGB { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| static const std::string letters_; | | static const std::string letters_; | |
| static const std::string digits_; | | static const std::string digits_; | |
|
| static const TransverseMercator OSGBTM_; | | static const TransverseMercator& OSGBTM(); | |
| static real northoffset_; | | static real northoffset_; | |
| static bool init_; | | static bool init_; | |
| enum { | | enum { | |
| base_ = 10, | | base_ = 10, | |
| tile_ = 100000, | | tile_ = 100000, | |
| tilelevel_ = 5, | | tilelevel_ = 5, | |
| tilegrid_ = 5, | | tilegrid_ = 5, | |
| tileoffx_ = 2 * tilegrid_, | | tileoffx_ = 2 * tilegrid_, | |
| tileoffy_ = 1 * tilegrid_, | | tileoffy_ = 1 * tilegrid_, | |
| minx_ = - tileoffx_ * tile_, | | minx_ = - tileoffx_ * tile_, | |
| | | | |
| skipping to change at line 86 | | skipping to change at line 86 | |
| * @param[out] x easting of point (meters). | | * @param[out] x easting of point (meters). | |
| * @param[out] y northing of point (meters). | | * @param[out] y northing of point (meters). | |
| * @param[out] gamma meridian convergence at point (degrees). | | * @param[out] gamma meridian convergence at point (degrees). | |
| * @param[out] k scale of projection at point. | | * @param[out] k scale of projection at point. | |
| * | | * | |
| * \e lat should be in the range [−90°, 90°]; \e lon | | * \e lat should be in the range [−90°, 90°]; \e lon | |
| * should be in the range [−540°, 540°). | | * should be in the range [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static void Forward(real lat, real lon, | | static void Forward(real lat, real lon, | |
| real& x, real& y, real& gamma, real& k) { | | real& x, real& y, real& gamma, real& k) { | |
|
| OSGBTM_.Forward(OriginLongitude(), lat, lon, x, y, gamma, k); | | OSGBTM().Forward(OriginLongitude(), lat, lon, x, y, gamma, k); | |
| x += FalseEasting(); | | x += FalseEasting(); | |
| y += computenorthoffset(); | | y += computenorthoffset(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Reverse projection, from OSGB coordinates to geographic. | | * Reverse projection, from OSGB coordinates to geographic. | |
| * | | * | |
| * @param[in] x easting of point (meters). | | * @param[in] x easting of point (meters). | |
| * @param[in] y northing of point (meters). | | * @param[in] y northing of point (meters). | |
| * @param[out] lat latitude of point (degrees). | | * @param[out] lat latitude of point (degrees). | |
| | | | |
| skipping to change at line 109 | | skipping to change at line 109 | |
| * @param[out] k scale of projection at point. | | * @param[out] k scale of projection at point. | |
| * | | * | |
| * The value of \e lon returned is in the range [−180°, | | * The value of \e lon returned is in the range [−180°, | |
| * 180°). | | * 180°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
| static void Reverse(real x, real y, | | static void Reverse(real x, real y, | |
| real& lat, real& lon, real& gamma, real& k) { | | real& lat, real& lon, real& gamma, real& k) { | |
| x -= FalseEasting(); | | x -= FalseEasting(); | |
| y -= computenorthoffset(); | | y -= computenorthoffset(); | |
|
| OSGBTM_.Reverse(OriginLongitude(), x, y, lat, lon, gamma, k); | | OSGBTM().Reverse(OriginLongitude(), x, y, lat, lon, gamma, k); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * OSGB::Forward without returning the convergence and scale. | | * OSGB::Forward without returning the convergence and scale. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static void Forward(real lat, real lon, real& x, real& y) { | | static void Forward(real lat, real lon, real& x, real& y) { | |
| real gamma, k; | | real gamma, k; | |
| Forward(lat, lon, x, y, gamma, k); | | Forward(lat, lon, x, y, gamma, k); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 185 | | skipping to change at line 185 | |
| /** \name Inspector functions | | /** \name Inspector functions | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return \e a the equatorial radius of the Airy 1830 ellipsoid (meter
s). | | * @return \e a the equatorial radius of the Airy 1830 ellipsoid (meter
s). | |
| * | | * | |
| * This is 20923713 ft converted to meters using the rule 1 ft = | | * This is 20923713 ft converted to meters using the rule 1 ft = | |
| * 10<sup>9.48401603−10</sup> m. (The Airy 1830 value is returne
d | | * 10<sup>9.48401603−10</sup> m. (The Airy 1830 value is returne
d | |
| * because the OSGB projection is based on this ellipsoid.) | | * because the OSGB projection is based on this ellipsoid.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static Math::real MajorRadius() | | static Math::real MajorRadius() { | |
| // result is about 6377563.3960320664406 m | | // result is about 6377563.3960320664406 m | |
|
| { return real(20923713) * std::pow(real(10), real(0.48401603L) - 1); } | | using std::pow; | |
| | | return pow(real(10), real(48401603 - 100000000) / 100000000) | |
| | | * 20923713; | |
| | | } | |
| | | | |
| /** | | /** | |
| * @return \e f the inverse flattening of the Airy 1830 ellipsoid. | | * @return \e f the inverse flattening of the Airy 1830 ellipsoid. | |
| * | | * | |
| * For the Airy 1830 ellipsoid, \e a = 20923713 ft and \e b = 20853810
ft; | | * For the Airy 1830 ellipsoid, \e a = 20923713 ft and \e b = 20853810
ft; | |
| * thus the flattening = (20923713 − 20853810)/20923713 = | | * thus the flattening = (20923713 − 20853810)/20923713 = | |
| * 7767/2324857 = 1/299.32496459... (The Airy 1830 value is returned | | * 7767/2324857 = 1/299.32496459... (The Airy 1830 value is returned | |
| * because the OSGB projection is based on this ellipsoid.) | | * because the OSGB projection is based on this ellipsoid.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real Flattening() | | static Math::real Flattening() | |
|
| { return real(20923713 - 20853810) / real(20923713); } | | { return real(20923713 - 20853810) / 20923713; } | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return \e r the inverse flattening of the Airy 1830 ellipsoid. | | * @return \e r the inverse flattening of the Airy 1830 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real InverseFlattening() { return 1/Flattening(); } | | static Math::real InverseFlattening() { return 1/Flattening(); } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** | | /** | |
| * @return \e k0 central scale for the OSGB projection (0.9996012717...
). | | * @return \e k0 central scale for the OSGB projection (0.9996012717...
). | |
| * | | * | |
| * C. J. Mugnier, Grids & Datums, PE&RS, Oct. 2003, states that | | * C. J. Mugnier, Grids & Datums, PE&RS, Oct. 2003, states that | |
| * this is defined as 10<sup>9.9998268−10</sup>. | | * this is defined as 10<sup>9.9998268−10</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static Math::real CentralScale() | | static Math::real CentralScale() { | |
| { return std::pow(real(10), real(9998268 - 10000000) / real(10000000)); | | using std::pow; | |
| } | | return pow(real(10), real(9998268 - 10000000) / 10000000); | |
| | | } | |
| | | | |
| /** | | /** | |
| * @return latitude of the origin for the OSGB projection (49 degrees). | | * @return latitude of the origin for the OSGB projection (49 degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real OriginLatitude() { return real(49); } | | static Math::real OriginLatitude() { return real(49); } | |
| | | | |
| /** | | /** | |
| * @return longitude of the origin for the OSGB projection (−2 | | * @return longitude of the origin for the OSGB projection (−2 | |
| * degrees). | | * degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
End of changes. 7 change blocks. |
| 9 lines changed or deleted | | 13 lines changed or added | |
|
| PolygonArea.hpp | | PolygonArea.hpp | |
| /** | | /** | |
| * \file PolygonArea.hpp | | * \file PolygonArea.hpp | |
| * \brief Header for GeographicLib::PolygonArea class | | * \brief Header for GeographicLib::PolygonArea class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2010-2011) <charles@karney.com> and licens
ed | | * Copyright (c) Charles Karney (2010-2014) <charles@karney.com> and licens
ed | |
| * under the MIT/X11 License. For more information, see | | * under the MIT/X11 License. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_POLYGONAREA_HPP) | | #if !defined(GEOGRAPHICLIB_POLYGONAREA_HPP) | |
| #define GEOGRAPHICLIB_POLYGONAREA_HPP 1 | | #define GEOGRAPHICLIB_POLYGONAREA_HPP 1 | |
| | | | |
| #include <GeographicLib/Geodesic.hpp> | | #include <GeographicLib/Geodesic.hpp> | |
|
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/GeodesicExact.hpp> | |
| #include <GeographicLib/Accumulator.hpp> | | #include <GeographicLib/Accumulator.hpp> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Polygon areas | | * \brief Polygon areas | |
| * | | * | |
| * This computes the area of a polygon whose edges are geodesics using th
e | | * This computes the area of a polygon whose edges are geodesics using th
e | |
| * method given in Section 6 of | | * method given in Section 6 of | |
| * - C. F. F. Karney, | | * - C. F. F. Karney, | |
| | | | |
| skipping to change at line 48 | | skipping to change at line 48 | |
| * then not uniquely defined. In this case, either add an intermediate | | * then not uniquely defined. In this case, either add an intermediate | |
| * vertex or add the edge ''as'' an edge (by defining its direction and | | * vertex or add the edge ''as'' an edge (by defining its direction and | |
| * length). | | * length). | |
| * | | * | |
| * The area and perimeter are accumulated in two times the standard float
ing | | * The area and perimeter are accumulated in two times the standard float
ing | |
| * point precision to guard against the loss of accuracy with many-sided | | * point precision to guard against the loss of accuracy with many-sided | |
| * polygons. At any point you can ask for the perimeter and area so far. | | * polygons. At any point you can ask for the perimeter and area so far. | |
| * There's an option to treat the points as defining a polyline instead o
f a | | * There's an option to treat the points as defining a polyline instead o
f a | |
| * polygon; in that case, only the perimeter is computed. | | * polygon; in that case, only the perimeter is computed. | |
| * | | * | |
|
| | | * This is a templated class to allow it to be used with either Geodesic | |
| | | and | |
| | | * GeodesicExact. GeographicLib::PolygonArea and | |
| | | * GeographicLib::PolygonAreaExact are typedefs for these two cases. | |
| | | * | |
| | | * @tparam GeodType the geodesic class to use. | |
| | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-PolygonArea.cpp | | * \include example-PolygonArea.cpp | |
| * | | * | |
| * <a href="Planimeter.1.html">Planimeter</a> is a command-line utility | | * <a href="Planimeter.1.html">Planimeter</a> is a command-line utility | |
| * providing access to the functionality of PolygonArea. | | * providing access to the functionality of PolygonArea. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
|
| class GEOGRAPHICLIB_EXPORT PolygonArea { | | template <class GeodType = Geodesic> | |
| | | class PolygonAreaT { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| Geodesic _earth; | | GeodType _earth; | |
| real _area0; // Full ellipsoid area | | real _area0; // Full ellipsoid area | |
| bool _polyline; // Assume polyline (don't close and skip ar
ea) | | bool _polyline; // Assume polyline (don't close and skip ar
ea) | |
| unsigned _mask; | | unsigned _mask; | |
| unsigned _num; | | unsigned _num; | |
| int _crossings; | | int _crossings; | |
|
| Accumulator<real> _areasum, _perimetersum; | | Accumulator<> _areasum, _perimetersum; | |
| real _lat0, _lon0, _lat1, _lon1; | | real _lat0, _lon0, _lat1, _lon1; | |
| static inline int transit(real lon1, real lon2) { | | static inline int transit(real lon1, real lon2) { | |
| // Return 1 or -1 if crossing prime meridian in east or west directio
n. | | // Return 1 or -1 if crossing prime meridian in east or west directio
n. | |
| // Otherwise return zero. | | // Otherwise return zero. | |
| // Compute lon12 the same way as Geodesic::Inverse. | | // Compute lon12 the same way as Geodesic::Inverse. | |
| lon1 = Math::AngNormalize(lon1); | | lon1 = Math::AngNormalize(lon1); | |
| lon2 = Math::AngNormalize(lon2); | | lon2 = Math::AngNormalize(lon2); | |
| real lon12 = Math::AngDiff(lon1, lon2); | | real lon12 = Math::AngDiff(lon1, lon2); | |
| int cross = | | int cross = | |
| lon1 < 0 && lon2 >= 0 && lon12 > 0 ? 1 : | | lon1 < 0 && lon2 >= 0 && lon12 > 0 ? 1 : | |
| (lon2 < 0 && lon1 >= 0 && lon12 < 0 ? -1 : 0); | | (lon2 < 0 && lon1 >= 0 && lon12 < 0 ? -1 : 0); | |
| return cross; | | return cross; | |
| } | | } | |
| public: | | public: | |
| | | | |
| /** | | /** | |
|
| * Constructor for PolygonArea. | | * Constructor for PolygonAreaT. | |
| * | | * | |
| * @param[in] earth the Geodesic object to use for geodesic calculation
s. | | * @param[in] earth the Geodesic object to use for geodesic calculation
s. | |
|
| * By default this uses the WGS84 ellipsoid. | | | |
| * @param[in] polyline if true that treat the points as defining a poly
line | | * @param[in] polyline if true that treat the points as defining a poly
line | |
| * instead of a polygon (default = false). | | * instead of a polygon (default = false). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| PolygonArea(const Geodesic& earth, bool polyline = false) | | PolygonAreaT(const GeodType& earth, bool polyline = false) | |
| : _earth(earth) | | : _earth(earth) | |
| , _area0(_earth.EllipsoidArea()) | | , _area0(_earth.EllipsoidArea()) | |
| , _polyline(polyline) | | , _polyline(polyline) | |
|
| , _mask(Geodesic::LATITUDE | Geodesic::LONGITUDE | Geodesic::DISTANCE | | , _mask(GeodType::LATITUDE | GeodType::LONGITUDE | GeodType::DISTANCE | |
| | | | | | |
| (_polyline ? Geodesic::NONE : Geodesic::AREA)) | | (_polyline ? GeodType::NONE : GeodType::AREA)) | |
| { Clear(); } | | { Clear(); } | |
| | | | |
| /** | | /** | |
|
| * Clear PolygonArea, allowing a new polygon to be started. | | * Clear PolygonAreaT, allowing a new polygon to be started. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Clear() { | | void Clear() { | |
| _num = 0; | | _num = 0; | |
| _crossings = 0; | | _crossings = 0; | |
| _areasum = 0; | | _areasum = 0; | |
| _perimetersum = 0; | | _perimetersum = 0; | |
|
| _lat0 = _lon0 = _lat1 = _lon1 = Math::NaN<real>(); | | _lat0 = _lon0 = _lat1 = _lon1 = Math::NaN(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Add a point to the polygon or polyline. | | * Add a point to the polygon or polyline. | |
| * | | * | |
| * @param[in] lat the latitude of the point (degrees). | | * @param[in] lat the latitude of the point (degrees). | |
| * @param[in] lon the longitude of the point (degrees). | | * @param[in] lon the longitude of the point (degrees). | |
| * | | * | |
| * \e lat should be in the range [−90°, 90°] and \e | | * \e lat should be in the range [−90°, 90°] and \e | |
| * lon should be in the range [−540°, 540°). | | * lon should be in the range [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void AddPoint(real lat, real lon); | | void AddPoint(real lat, real lon); | |
| | | | |
| /** | | /** | |
| * Add an edge to the polygon or polyline. | | * Add an edge to the polygon or polyline. | |
| * | | * | |
| * @param[in] azi azimuth at current point (degrees). | | * @param[in] azi azimuth at current point (degrees). | |
| * @param[in] s distance from current point to next point (meters). | | * @param[in] s distance from current point to next point (meters). | |
| * | | * | |
| * \e azi should be in the range [−540°, 540°). This doe
s | | * \e azi should be in the range [−540°, 540°). This doe
s | |
|
| * nothing if no points have been added yet. Use PolygonArea::CurrentP
oint | | * nothing if no points have been added yet. Use PolygonAreaT::Current
Point | |
| * to determine the position of the new vertex. | | * to determine the position of the new vertex. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void AddEdge(real azi, real s); | | void AddEdge(real azi, real s); | |
| | | | |
| /** | | /** | |
| * Return the results so far. | | * Return the results so far. | |
| * | | * | |
| * @param[in] reverse if true then clockwise (instead of counter-clockw
ise) | | * @param[in] reverse if true then clockwise (instead of counter-clockw
ise) | |
| * traversal counts as a positive area. | | * traversal counts as a positive area. | |
| * @param[in] sign if true then return a signed result for the area if | | * @param[in] sign if true then return a signed result for the area if | |
| | | | |
| skipping to change at line 153 | | skipping to change at line 159 | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| unsigned Compute(bool reverse, bool sign, | | unsigned Compute(bool reverse, bool sign, | |
| real& perimeter, real& area) const; | | real& perimeter, real& area) const; | |
| | | | |
| /** | | /** | |
| * Return the results assuming a tentative final test point is added; | | * Return the results assuming a tentative final test point is added; | |
| * however, the data for the test point is not saved. This lets you re
port | | * however, the data for the test point is not saved. This lets you re
port | |
| * a running result for the perimeter and area as the user moves the mo
use | | * a running result for the perimeter and area as the user moves the mo
use | |
| * cursor. Ordinary floating point arithmetic is used to accumulate th
e | | * cursor. Ordinary floating point arithmetic is used to accumulate th
e | |
| * data for the test point; thus the area and perimeter returned are le
ss | | * data for the test point; thus the area and perimeter returned are le
ss | |
|
| * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are | | * accurate than if PolygonAreaT::AddPoint and PolygonAreaT::Compute ar
e | |
| * used. | | * used. | |
| * | | * | |
| * @param[in] lat the latitude of the test point (degrees). | | * @param[in] lat the latitude of the test point (degrees). | |
| * @param[in] lon the longitude of the test point (degrees). | | * @param[in] lon the longitude of the test point (degrees). | |
| * @param[in] reverse if true then clockwise (instead of counter-clockw
ise) | | * @param[in] reverse if true then clockwise (instead of counter-clockw
ise) | |
| * traversal counts as a positive area. | | * traversal counts as a positive area. | |
| * @param[in] sign if true then return a signed result for the area if | | * @param[in] sign if true then return a signed result for the area if | |
| * the polygon is traversed in the "wrong" direction instead of retur
ning | | * the polygon is traversed in the "wrong" direction instead of retur
ning | |
| * the area for the rest of the earth. | | * the area for the rest of the earth. | |
| * @param[out] perimeter the approximate perimeter of the polygon or le
ngth | | * @param[out] perimeter the approximate perimeter of the polygon or le
ngth | |
| | | | |
| skipping to change at line 182 | | skipping to change at line 188 | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| unsigned TestPoint(real lat, real lon, bool reverse, bool sign, | | unsigned TestPoint(real lat, real lon, bool reverse, bool sign, | |
| real& perimeter, real& area) const; | | real& perimeter, real& area) const; | |
| | | | |
| /** | | /** | |
| * Return the results assuming a tentative final test point is added vi
a an | | * Return the results assuming a tentative final test point is added vi
a an | |
| * azimuth and distance; however, the data for the test point is not sa
ved. | | * azimuth and distance; however, the data for the test point is not sa
ved. | |
| * This lets you report a running result for the perimeter and area as
the | | * This lets you report a running result for the perimeter and area as
the | |
| * user moves the mouse cursor. Ordinary floating point arithmetic is
used | | * user moves the mouse cursor. Ordinary floating point arithmetic is
used | |
| * to accumulate the data for the test point; thus the area and perimet
er | | * to accumulate the data for the test point; thus the area and perimet
er | |
|
| * returned are less accurate than if PolygonArea::AddEdge and | | * returned are less accurate than if PolygonAreaT::AddEdge and | |
| * PolygonArea::Compute are used. | | * PolygonAreaT::Compute are used. | |
| * | | * | |
| * @param[in] azi azimuth at current point (degrees). | | * @param[in] azi azimuth at current point (degrees). | |
| * @param[in] s distance from current point to final test point (meters
). | | * @param[in] s distance from current point to final test point (meters
). | |
| * @param[in] reverse if true then clockwise (instead of counter-clockw
ise) | | * @param[in] reverse if true then clockwise (instead of counter-clockw
ise) | |
| * traversal counts as a positive area. | | * traversal counts as a positive area. | |
| * @param[in] sign if true then return a signed result for the area if | | * @param[in] sign if true then return a signed result for the area if | |
| * the polygon is traversed in the "wrong" direction instead of retur
ning | | * the polygon is traversed in the "wrong" direction instead of retur
ning | |
| * the area for the rest of the earth. | | * the area for the rest of the earth. | |
| * @param[out] perimeter the approximate perimeter of the polygon or le
ngth | | * @param[out] perimeter the approximate perimeter of the polygon or le
ngth | |
| * of the polyline (meters). | | * of the polyline (meters). | |
| | | | |
| skipping to change at line 207 | | skipping to change at line 213 | |
| * @return the number of points. | | * @return the number of points. | |
| * | | * | |
| * \e azi should be in the range [−540°, 540°). | | * \e azi should be in the range [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| unsigned TestEdge(real azi, real s, bool reverse, bool sign, | | unsigned TestEdge(real azi, real s, bool reverse, bool sign, | |
| real& perimeter, real& area) const; | | real& perimeter, real& area) const; | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
|
| * The old name for PolygonArea::TestPoint. | | * The old name for PolygonAreaT::TestPoint. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| unsigned TestCompute(real lat, real lon, bool reverse, bool sign, | | unsigned TestCompute(real lat, real lon, bool reverse, bool sign, | |
| real& perimeter, real& area) const { | | real& perimeter, real& area) const { | |
| return TestPoint(lat, lon, reverse, sign, perimeter, area); | | return TestPoint(lat, lon, reverse, sign, perimeter, area); | |
| } | | } | |
| /// \endcond | | /// \endcond | |
| | | | |
| /** \name Inspector functions | | /** \name Inspector functions | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| skipping to change at line 245 | | skipping to change at line 251 | |
| * @param[out] lon the longitude of the point (degrees). | | * @param[out] lon the longitude of the point (degrees). | |
| * | | * | |
| * If no points have been added, then NaNs are returned. Otherwise, \e
lon | | * If no points have been added, then NaNs are returned. Otherwise, \e
lon | |
| * will be in the range [−180°, 180°). | | * will be in the range [−180°, 180°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void CurrentPoint(real& lat, real& lon) const | | void CurrentPoint(real& lat, real& lon) const | |
| { lat = _lat1; lon = _lon1; } | | { lat = _lat1; lon = _lon1; } | |
| ///@} | | ///@} | |
| }; | | }; | |
| | | | |
|
| | | /** | |
| | | * @relates PolygonAreaT | |
| | | * | |
| | | * Polygon areas using Geodesic. This should be used if the flattening i | |
| | | s | |
| | | * small. | |
| | | **********************************************************************/ | |
| | | typedef PolygonAreaT<Geodesic> PolygonArea; | |
| | | | |
| | | /** | |
| | | * @relates PolygonAreaT | |
| | | * | |
| | | * Polygon areas using GeodesicExact. (But note that the implementation | |
| | | of | |
| | | * areas in GeodesicExact uses a high order series and this is only accur | |
| | | ate | |
| | | * for modest flattenings.) | |
| | | **********************************************************************/ | |
| | | typedef PolygonAreaT<GeodesicExact> PolygonAreaExact; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_POLYGONAREA_HPP | | #endif // GEOGRAPHICLIB_POLYGONAREA_HPP | |
| | | | |
End of changes. 17 change blocks. |
| 18 lines changed or deleted | | 45 lines changed or added | |
|
| SphericalHarmonic.hpp | | SphericalHarmonic.hpp | |
| | | | |
| skipping to change at line 35 | | skipping to change at line 35 | |
| V(x, y, z) = sum(n = 0..N)[ q^(n+1) * sum(m = 0..n)[ | | V(x, y, z) = sum(n = 0..N)[ q^(n+1) * sum(m = 0..n)[ | |
| (C[n,m] * cos(m*lambda) + S[n,m] * sin(m*lambda)) * | | (C[n,m] * cos(m*lambda) + S[n,m] * sin(m*lambda)) * | |
| P[n,m](cos(theta)) ] ] | | P[n,m](cos(theta)) ] ] | |
| \endverbatim | | \endverbatim | |
| * where | | * where | |
| * - <i>p</i><sup>2</sup> = <i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>, | | * - <i>p</i><sup>2</sup> = <i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>, | |
| * - <i>r</i><sup>2</sup> = <i>p</i><sup>2</sup> + <i>z</i><sup>2</sup>, | | * - <i>r</i><sup>2</sup> = <i>p</i><sup>2</sup> + <i>z</i><sup>2</sup>, | |
| * - \e q = <i>a</i>/<i>r</i>, | | * - \e q = <i>a</i>/<i>r</i>, | |
| * - θ = atan2(\e p, \e z) = the spherical \e colatitude, | | * - θ = atan2(\e p, \e z) = the spherical \e colatitude, | |
| * - λ = atan2(\e y, \e x) = the longitude. | | * - λ = atan2(\e y, \e x) = the longitude. | |
|
| * - P<sub>\e nm</sub>(\e t) is the associated Legendre polynomial of deg | | * - P<sub><i>nm</i></sub>(\e t) is the associated Legendre polynomial of | |
| ree | | * degree \e n and order \e m. | |
| * \e n and order \e m. | | | |
| * | | * | |
|
| * Two normalizations are supported for P<sub>\e nm</sub> | | * Two normalizations are supported for P<sub><i>nm</i></sub> | |
| * - fully normalized denoted by SphericalHarmonic::FULL. | | * - fully normalized denoted by SphericalHarmonic::FULL. | |
| * - Schmidt semi-normalized denoted by SphericalHarmonic::SCHMIDT. | | * - Schmidt semi-normalized denoted by SphericalHarmonic::SCHMIDT. | |
| * | | * | |
| * Clenshaw summation is used for the sums over both \e n and \e m. This | | * Clenshaw summation is used for the sums over both \e n and \e m. This | |
| * allows the computation to be carried out without the need for any | | * allows the computation to be carried out without the need for any | |
| * temporary arrays. See SphericalEngine.cpp for more information on the | | * temporary arrays. See SphericalEngine.cpp for more information on the | |
| * implementation. | | * implementation. | |
| * | | * | |
| * References: | | * References: | |
| * - C. W. Clenshaw, A note on the summation of Chebyshev series, | | * - C. W. Clenshaw, A note on the summation of Chebyshev series, | |
| | | | |
| skipping to change at line 74 | | skipping to change at line 74 | |
| | | | |
| class GEOGRAPHICLIB_EXPORT SphericalHarmonic { | | class GEOGRAPHICLIB_EXPORT SphericalHarmonic { | |
| public: | | public: | |
| /** | | /** | |
| * Supported normalizations for the associated Legendre polynomials. | | * Supported normalizations for the associated Legendre polynomials. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| enum normalization { | | enum normalization { | |
| /** | | /** | |
| * Fully normalized associated Legendre polynomials. | | * Fully normalized associated Legendre polynomials. | |
| * | | * | |
|
| * These are defined by <i>P</i><sub><i>nm</i></sub><sup>full</sup>(\ | | * These are defined by | |
| e z) | | * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(\e z) | |
| * = (−1)<sup><i>m</i></sup> sqrt(\e k (2\e n + 1) (\e n &minus | | * = (−1)<sup><i>m</i></sup> | |
| ; \e | | * sqrt(\e k (2\e n + 1) (\e n − \e m)! / (\e n + \e m)!) | |
| * m)! / (\e n + \e m)!) | | | |
| * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), where | | * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), where | |
| * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers | | * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers | |
| * function (also known as the Legendre function on the cut or the | | * function (also known as the Legendre function on the cut or the | |
| * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and
\e k | | * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and
\e k | |
| * = 1 for \e m = 0 and \e k = 2 otherwise. | | * = 1 for \e m = 0 and \e k = 2 otherwise. | |
| * | | * | |
| * The mean squared value of | | * The mean squared value of | |
| * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cosθ) | | * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cosθ) | |
| * cos(<i>m</i>λ) and | | * cos(<i>m</i>λ) and | |
| * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cosθ) | | * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cosθ) | |
| * sin(<i>m</i>λ) over the sphere is 1. | | * sin(<i>m</i>λ) over the sphere is 1. | |
| * | | * | |
| * @hideinitializer | | * @hideinitializer | |
| ********************************************************************
**/ | | ********************************************************************
**/ | |
| FULL = SphericalEngine::FULL, | | FULL = SphericalEngine::FULL, | |
| /** | | /** | |
| * Schmidt semi-normalized associated Legendre polynomials. | | * Schmidt semi-normalized associated Legendre polynomials. | |
| * | | * | |
|
| * These are defined by <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup | | * These are defined by | |
| >(\e | | * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(\e z) | |
| * z) = (−1)<sup><i>m</i></sup> sqrt(\e k (\e n − \e m)! | | * = (−1)<sup><i>m</i></sup> | |
| / | | * sqrt(\e k (\e n − \e m)! / (\e n + \e m)!) | |
| * (\e n + \e m)!) <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e | | * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), where | |
| z), | | * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers | |
| * where <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferr | | | |
| ers | | | |
| * function (also known as the Legendre function on the cut or the | | * function (also known as the Legendre function on the cut or the | |
| * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and
\e k | | * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and
\e k | |
| * = 1 for \e m = 0 and \e k = 2 otherwise. | | * = 1 for \e m = 0 and \e k = 2 otherwise. | |
| * | | * | |
| * The mean squared value of | | * The mean squared value of | |
| * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cosθ) | | * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cosθ) | |
| * cos(<i>m</i>λ) and | | * cos(<i>m</i>λ) and | |
| * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cosθ) | | * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cosθ) | |
| * sin(<i>m</i>λ) over the sphere is 1/(2\e n + 1). | | * sin(<i>m</i>λ) over the sphere is 1/(2\e n + 1). | |
| * | | * | |
| | | | |
| skipping to change at line 129 | | skipping to change at line 132 | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| SphericalEngine::coeff _c[1]; | | SphericalEngine::coeff _c[1]; | |
| real _a; | | real _a; | |
| unsigned _norm; | | unsigned _norm; | |
| | | | |
| public: | | public: | |
| /** | | /** | |
| * Constructor with a full set of coefficients specified. | | * Constructor with a full set of coefficients specified. | |
| * | | * | |
|
| * @param[in] C the coefficients \e C<sub>\e nm</sub>. | | * @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>. | |
| * @param[in] S the coefficients \e S<sub>\e nm</sub>. | | * @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>. | |
| * @param[in] N the maximum degree and order of the sum | | * @param[in] N the maximum degree and order of the sum | |
| * @param[in] a the reference radius appearing in the definition of the | | * @param[in] a the reference radius appearing in the definition of the | |
| * sum. | | * sum. | |
| * @param[in] norm the normalization for the associated Legendre | | * @param[in] norm the normalization for the associated Legendre | |
| * polynomials, either SphericalHarmonic::full (the default) or | | * polynomials, either SphericalHarmonic::full (the default) or | |
| * SphericalHarmonic::schmidt. | | * SphericalHarmonic::schmidt. | |
| * @exception GeographicErr if \e N does not satisfy \e N ≥ −1
. | | * @exception GeographicErr if \e N does not satisfy \e N ≥ −1
. | |
| * @exception GeographicErr if \e C or \e S is not big enough to hold t
he | | * @exception GeographicErr if \e C or \e S is not big enough to hold t
he | |
| * coefficients. | | * coefficients. | |
| * | | * | |
|
| * The coefficients \e C<sub>\e nm</sub> and \e S<sub>\e nm</sub> are | | * The coefficients <i>C</i><sub><i>nm</i></sub> and | |
| * stored in the one-dimensional vectors \e C and \e S which must conta | | * <i>S</i><sub><i>nm</i></sub> are stored in the one-dimensional vecto | |
| in | | rs | |
| * (\e N + 1)(\e N + 2)/2 and N (\e N + 1)/2 elements, respectively, st | | * \e C and \e S which must contain (\e N + 1)(\e N + 2)/2 and \e N (\e | |
| ored | | N + | |
| * in "column-major" order. Thus for \e N = 3, the order would be: | | * 1)/2 elements, respectively, stored in "column-major" order. Thus f | |
| | | or | |
| | | * \e N = 3, the order would be: | |
| * <i>C</i><sub>00</sub>, | | * <i>C</i><sub>00</sub>, | |
| * <i>C</i><sub>10</sub>, | | * <i>C</i><sub>10</sub>, | |
| * <i>C</i><sub>20</sub>, | | * <i>C</i><sub>20</sub>, | |
| * <i>C</i><sub>30</sub>, | | * <i>C</i><sub>30</sub>, | |
| * <i>C</i><sub>11</sub>, | | * <i>C</i><sub>11</sub>, | |
| * <i>C</i><sub>21</sub>, | | * <i>C</i><sub>21</sub>, | |
| * <i>C</i><sub>31</sub>, | | * <i>C</i><sub>31</sub>, | |
| * <i>C</i><sub>22</sub>, | | * <i>C</i><sub>22</sub>, | |
| * <i>C</i><sub>32</sub>, | | * <i>C</i><sub>32</sub>, | |
| * <i>C</i><sub>33</sub>. | | * <i>C</i><sub>33</sub>. | |
| | | | |
| skipping to change at line 174 | | skipping to change at line 178 | |
| SphericalHarmonic(const std::vector<real>& C, | | SphericalHarmonic(const std::vector<real>& C, | |
| const std::vector<real>& S, | | const std::vector<real>& S, | |
| int N, real a, unsigned norm = FULL) | | int N, real a, unsigned norm = FULL) | |
| : _a(a) | | : _a(a) | |
| , _norm(norm) | | , _norm(norm) | |
| { _c[0] = SphericalEngine::coeff(C, S, N); } | | { _c[0] = SphericalEngine::coeff(C, S, N); } | |
| | | | |
| /** | | /** | |
| * Constructor with a subset of coefficients specified. | | * Constructor with a subset of coefficients specified. | |
| * | | * | |
|
| * @param[in] C the coefficients \e C<sub>\e nm</sub>. | | * @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>. | |
| * @param[in] S the coefficients \e S<sub>\e nm</sub>. | | * @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>. | |
| * @param[in] N the degree used to determine the layout of \e C and \e
S. | | * @param[in] N the degree used to determine the layout of \e C and \e
S. | |
| * @param[in] nmx the maximum degree used in the sum. The sum over \e
n is | | * @param[in] nmx the maximum degree used in the sum. The sum over \e
n is | |
| * from 0 thru \e nmx. | | * from 0 thru \e nmx. | |
| * @param[in] mmx the maximum order used in the sum. The sum over \e m
is | | * @param[in] mmx the maximum order used in the sum. The sum over \e m
is | |
| * from 0 thru min(\e n, \e mmx). | | * from 0 thru min(\e n, \e mmx). | |
| * @param[in] a the reference radius appearing in the definition of the | | * @param[in] a the reference radius appearing in the definition of the | |
| * sum. | | * sum. | |
| * @param[in] norm the normalization for the associated Legendre | | * @param[in] norm the normalization for the associated Legendre | |
| * polynomials, either SphericalHarmonic::FULL (the default) or | | * polynomials, either SphericalHarmonic::FULL (the default) or | |
| * SphericalHarmonic::SCHMIDT. | | * SphericalHarmonic::SCHMIDT. | |
| | | | |
End of changes. 7 change blocks. |
| 27 lines changed or deleted | | 25 lines changed or added | |
|
| SphericalHarmonic2.hpp | | SphericalHarmonic2.hpp | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| #include <GeographicLib/SphericalEngine.hpp> | | #include <GeographicLib/SphericalEngine.hpp> | |
| #include <GeographicLib/CircularEngine.hpp> | | #include <GeographicLib/CircularEngine.hpp> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Spherical harmonic series with two corrections to the coefficie
nts | | * \brief Spherical harmonic series with two corrections to the coefficie
nts | |
| * | | * | |
| * This classes is similar to SphericalHarmonic, except that the coeffici
ents | | * This classes is similar to SphericalHarmonic, except that the coeffici
ents | |
|
| * \e C<sub>\e nm</sub> are replaced by \e C<sub>\e nm</sub> + \e tau' | | * <i>C</i><sub><i>nm</i></sub> are replaced by | |
| * C'<sub>\e nm</sub> + \e tau'' C''<sub>\e nm</sub> (and similarly for \ | | * <i>C</i><sub><i>nm</i></sub> + \e tau' <i>C'</i><sub><i>nm</i></sub> + | |
| e | | \e | |
| * S<sub>\e nm</sub>). | | * tau'' <i>C''</i><sub><i>nm</i></sub> (and similarly for | |
| | | * <i>S</i><sub><i>nm</i></sub>). | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-SphericalHarmonic2.cpp | | * \include example-SphericalHarmonic2.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| // Don't include the GEOGRPAHIC_EXPORT because this header-only class isn
't | | // Don't include the GEOGRPAHIC_EXPORT because this header-only class isn
't | |
| // used by any other classes in the library. | | // used by any other classes in the library. | |
| class /*GEOGRAPHICLIB_EXPORT*/ SphericalHarmonic2 { | | class /*GEOGRAPHICLIB_EXPORT*/ SphericalHarmonic2 { | |
| public: | | public: | |
| /** | | /** | |
| | | | |
| skipping to change at line 71 | | skipping to change at line 72 | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| SphericalEngine::coeff _c[3]; | | SphericalEngine::coeff _c[3]; | |
| real _a; | | real _a; | |
| unsigned _norm; | | unsigned _norm; | |
| | | | |
| public: | | public: | |
| /** | | /** | |
| * Constructor with a full set of coefficients specified. | | * Constructor with a full set of coefficients specified. | |
| * | | * | |
|
| * @param[in] C the coefficients \e C<sub>\e nm</sub>. | | * @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>. | |
| * @param[in] S the coefficients \e S<sub>\e nm</sub>. | | * @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>. | |
| * @param[in] N the maximum degree and order of the sum | | * @param[in] N the maximum degree and order of the sum | |
|
| * @param[in] C1 the coefficients \e C'<sub>\e nm</sub>. | | * @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>. | |
| * @param[in] S1 the coefficients \e S'<sub>\e nm</sub>. | | * @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>. | |
| * @param[in] N1 the maximum degree and order of the first correction | | * @param[in] N1 the maximum degree and order of the first correction | |
|
| * coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>. | | * coefficients <i>C'</i><sub><i>nm</i></sub> and | |
| * @param[in] C2 the coefficients \e C''<sub>\e nm</sub>. | | * <i>S'</i><sub><i>nm</i></sub>. | |
| * @param[in] S2 the coefficients \e S''<sub>\e nm</sub>. | | * @param[in] C2 the coefficients <i>C''</i><sub><i>nm</i></sub>. | |
| | | * @param[in] S2 the coefficients <i>S''</i><sub><i>nm</i></sub>. | |
| * @param[in] N2 the maximum degree and order of the second correction | | * @param[in] N2 the maximum degree and order of the second correction | |
|
| * coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>. | | * coefficients <i>C'</i><sub><i>nm</i></sub> and | |
| | | * <i>S'</i><sub><i>nm</i></sub>. | |
| * @param[in] a the reference radius appearing in the definition of the | | * @param[in] a the reference radius appearing in the definition of the | |
| * sum. | | * sum. | |
| * @param[in] norm the normalization for the associated Legendre | | * @param[in] norm the normalization for the associated Legendre | |
| * polynomials, either SphericalHarmonic2::FULL (the default) or | | * polynomials, either SphericalHarmonic2::FULL (the default) or | |
| * SphericalHarmonic2::SCHMIDT. | | * SphericalHarmonic2::SCHMIDT. | |
| * @exception GeographicErr if \e N and \e N1 do not satisfy \e N ≥ | | * @exception GeographicErr if \e N and \e N1 do not satisfy \e N ≥ | |
| * \e N1 ≥ −1, and similarly for \e N2. | | * \e N1 ≥ −1, and similarly for \e N2. | |
| * @exception GeographicErr if any of the vectors of coefficients is no
t | | * @exception GeographicErr if any of the vectors of coefficients is no
t | |
| * large enough. | | * large enough. | |
| * | | * | |
| | | | |
| skipping to change at line 121 | | skipping to change at line 124 | |
| if (!(N1 <= N && N2 <= N)) | | if (!(N1 <= N && N2 <= N)) | |
| throw GeographicErr("N1 and N2 cannot be larger that N"); | | throw GeographicErr("N1 and N2 cannot be larger that N"); | |
| _c[0] = SphericalEngine::coeff(C, S, N); | | _c[0] = SphericalEngine::coeff(C, S, N); | |
| _c[1] = SphericalEngine::coeff(C1, S1, N1); | | _c[1] = SphericalEngine::coeff(C1, S1, N1); | |
| _c[2] = SphericalEngine::coeff(C2, S2, N2); | | _c[2] = SphericalEngine::coeff(C2, S2, N2); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Constructor with a subset of coefficients specified. | | * Constructor with a subset of coefficients specified. | |
| * | | * | |
|
| * @param[in] C the coefficients \e C<sub>\e nm</sub>. | | * @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>. | |
| * @param[in] S the coefficients \e S<sub>\e nm</sub>. | | * @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>. | |
| * @param[in] N the degree used to determine the layout of \e C and \e
S. | | * @param[in] N the degree used to determine the layout of \e C and \e
S. | |
| * @param[in] nmx the maximum degree used in the sum. The sum over \e
n is | | * @param[in] nmx the maximum degree used in the sum. The sum over \e
n is | |
| * from 0 thru \e nmx. | | * from 0 thru \e nmx. | |
| * @param[in] mmx the maximum order used in the sum. The sum over \e m
is | | * @param[in] mmx the maximum order used in the sum. The sum over \e m
is | |
| * from 0 thru min(\e n, \e mmx). | | * from 0 thru min(\e n, \e mmx). | |
|
| * @param[in] C1 the coefficients \e C'<sub>\e nm</sub>. | | * @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>. | |
| * @param[in] S1 the coefficients \e S'<sub>\e nm</sub>. | | * @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>. | |
| * @param[in] N1 the degree used to determine the layout of \e C' and \
e | | * @param[in] N1 the degree used to determine the layout of \e C' and \
e | |
| * S'. | | * S'. | |
| * @param[in] nmx1 the maximum degree used for \e C' and \e S'. | | * @param[in] nmx1 the maximum degree used for \e C' and \e S'. | |
| * @param[in] mmx1 the maximum order used for \e C' and \e S'. | | * @param[in] mmx1 the maximum order used for \e C' and \e S'. | |
|
| * @param[in] C2 the coefficients \e C''<sub>\e nm</sub>. | | * @param[in] C2 the coefficients <i>C''</i><sub><i>nm</i></sub>. | |
| * @param[in] S2 the coefficients \e S''<sub>\e nm</sub>. | | * @param[in] S2 the coefficients <i>S''</i><sub><i>nm</i></sub>. | |
| * @param[in] N2 the degree used to determine the layout of \e C'' and
\e | | * @param[in] N2 the degree used to determine the layout of \e C'' and
\e | |
| * S''. | | * S''. | |
| * @param[in] nmx2 the maximum degree used for \e C'' and \e S''. | | * @param[in] nmx2 the maximum degree used for \e C'' and \e S''. | |
| * @param[in] mmx2 the maximum order used for \e C'' and \e S''. | | * @param[in] mmx2 the maximum order used for \e C'' and \e S''. | |
| * @param[in] a the reference radius appearing in the definition of the | | * @param[in] a the reference radius appearing in the definition of the | |
| * sum. | | * sum. | |
| * @param[in] norm the normalization for the associated Legendre | | * @param[in] norm the normalization for the associated Legendre | |
| * polynomials, either SphericalHarmonic2::FULL (the default) or | | * polynomials, either SphericalHarmonic2::FULL (the default) or | |
| * SphericalHarmonic2::SCHMIDT. | | * SphericalHarmonic2::SCHMIDT. | |
| * @exception GeographicErr if the parameters do not satisfy \e N ≥
\e | | * @exception GeographicErr if the parameters do not satisfy \e N ≥
\e | |
| | | | |
End of changes. 8 change blocks. |
| 18 lines changed or deleted | | 21 lines changed or added | |
|
| TransverseMercator.hpp | | TransverseMercator.hpp | |
| | | | |
| skipping to change at line 21 | | skipping to change at line 21 | |
| #define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP 1 | | #define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP 1 | |
| | | | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| | | | |
| #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER) | | #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER) | |
| /** | | /** | |
| * The order of the series approximation used in TransverseMercator. | | * The order of the series approximation used in TransverseMercator. | |
| * GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER can be set to any integer in [4,
8]. | | * GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER can be set to any integer in [4,
8]. | |
| **********************************************************************/ | | **********************************************************************/ | |
| # define GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER \ | | # define GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER \ | |
|
| (GEOGRAPHICLIB_PRECISION == 2 ? 6 : (GEOGRAPHICLIB_PRECISION == 1 ? 4 : 8 | | (GEOGRAPHICLIB_PRECISION == 2 ? 6 : \ | |
| )) | | (GEOGRAPHICLIB_PRECISION == 1 ? 4 : 8)) | |
| #endif | | #endif | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Transverse Mercator projection | | * \brief Transverse Mercator projection | |
| * | | * | |
| * This uses Krüger's method which evaluates the projection and its | | * This uses Krüger's method which evaluates the projection and its | |
| * inverse in terms of a series. See | | * inverse in terms of a series. See | |
| * - L. Krüger, | | * - L. Krüger, | |
| | | | |
| skipping to change at line 83 | | skipping to change at line 84 | |
| * | | * | |
| * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is
a | | * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is
a | |
| * command-line utility providing access to the functionality of | | * command-line utility providing access to the functionality of | |
| * TransverseMercator and TransverseMercatorExact. | | * TransverseMercator and TransverseMercatorExact. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT TransverseMercator { | | class GEOGRAPHICLIB_EXPORT TransverseMercator { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| static const int maxpow_ = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER; | | static const int maxpow_ = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER; | |
|
| static const real tol_; | | | |
| static const real overflow_; | | | |
| static const int numit_ = 5; | | static const int numit_ = 5; | |
|
| | | real tol_; | |
| real _a, _f, _k0, _e2, _e, _e2m, _c, _n; | | real _a, _f, _k0, _e2, _e, _e2m, _c, _n; | |
| // _alp[0] and _bet[0] unused | | // _alp[0] and _bet[0] unused | |
| real _a1, _b1, _alp[maxpow_ + 1], _bet[maxpow_ + 1]; | | real _a1, _b1, _alp[maxpow_ + 1], _bet[maxpow_ + 1]; | |
|
| | | static inline real overflow() { | |
| | | // Overflow value s.t. atan(overflow_) = pi/2 | |
| | | static const real | |
| | | overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon()); | |
| | | return overflow; | |
| | | } | |
| // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right | | // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right | |
| static inline real tanx(real x) { | | static inline real tanx(real x) { | |
|
| real t = std::tan(x); | | using std::tan; | |
| | | real t = tan(x); | |
| // Write the tests this way to ensure that tanx(NaN()) is NaN() | | // Write the tests this way to ensure that tanx(NaN()) is NaN() | |
|
| return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl | | return x >= 0 ? | |
| ow_); | | (!(t < 0) ? t : overflow()) : | |
| | | (!(t >= 0) ? t : -overflow()); | |
| } | | } | |
| // Return e * atanh(e * x) for f >= 0, else return | | // Return e * atanh(e * x) for f >= 0, else return | |
| // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0 | | // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0 | |
|
| inline real eatanhe(real x) const | | inline real eatanhe(real x) const { | |
| { return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); | | using std::atan; | |
| } | | return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * atan(_e * x); | |
| | | } | |
| real taupf(real tau) const; | | real taupf(real tau) const; | |
| real tauf(real taup) const; | | real tauf(real taup) const; | |
| | | | |
| friend class Ellipsoid; // For access to taupf, tauf. | | friend class Ellipsoid; // For access to taupf, tauf. | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
| * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | | * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe
re. | |
|
| * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten | | * Negative \e f gives a prolate ellipsoid. If \e f > 1, set | |
| ing | | * flattening to 1/\e f. | |
| * to 1/\e f. | | | |
| * @param[in] k0 central scale factor. | | * @param[in] k0 central scale factor. | |
|
| * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k0 i
s | | * @exception GeographicErr if \e a, (1 − \e f) \e a, or \e k0 is | |
| * not positive. | | * not positive. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| TransverseMercator(real a, real f, real k0); | | TransverseMercator(real a, real f, real k0); | |
| | | | |
| /** | | /** | |
| * Forward projection, from geographic to transverse Mercator. | | * Forward projection, from geographic to transverse Mercator. | |
| * | | * | |
| * @param[in] lon0 central meridian of the projection (degrees). | | * @param[in] lon0 central meridian of the projection (degrees). | |
| * @param[in] lat latitude of point (degrees). | | * @param[in] lat latitude of point (degrees). | |
| * @param[in] lon longitude of point (degrees). | | * @param[in] lon longitude of point (degrees). | |
| | | | |
| skipping to change at line 207 | | skipping to change at line 218 | |
| * k0 used in the constructor and is the scale on the central meridia
n. | | * k0 used in the constructor and is the scale on the central meridia
n. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real CentralScale() const { return _k0; } | | Math::real CentralScale() const { return _k0; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of TransverseMercator with the WGS84 ellipsoi
d | | * A global instantiation of TransverseMercator with the WGS84 ellipsoi
d | |
| * and the UTM scale factor. However, unlike UTM, no false easting or | | * and the UTM scale factor. However, unlike UTM, no false easting or | |
| * northing is added. | | * northing is added. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const TransverseMercator UTM; | | static const TransverseMercator& UTM(); | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP | | #endif // GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP | |
| | | | |
End of changes. 10 change blocks. |
| 15 lines changed or deleted | | 22 lines changed or added | |
|
| TransverseMercatorExact.hpp | | TransverseMercatorExact.hpp | |
| | | | |
| skipping to change at line 82 | | skipping to change at line 82 | |
| * \include example-TransverseMercatorExact.cpp | | * \include example-TransverseMercatorExact.cpp | |
| * | | * | |
| * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is
a | | * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is
a | |
| * command-line utility providing access to the functionality of | | * command-line utility providing access to the functionality of | |
| * TransverseMercator and TransverseMercatorExact. | | * TransverseMercator and TransverseMercatorExact. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHICLIB_EXPORT TransverseMercatorExact { | | class GEOGRAPHICLIB_EXPORT TransverseMercatorExact { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| static const real tol_; | | | |
| static const real tol1_; | | | |
| static const real tol2_; | | | |
| static const real taytol_; | | | |
| static const real overflow_; | | | |
| static const int numit_ = 10; | | static const int numit_ = 10; | |
|
| | | real tol_, tol1_, tol2_, taytol_; | |
| real _a, _f, _k0, _mu, _mv, _e; | | real _a, _f, _k0, _mu, _mv, _e; | |
| bool _extendp; | | bool _extendp; | |
| EllipticFunction _Eu, _Ev; | | EllipticFunction _Eu, _Ev; | |
|
| | | static inline real overflow() { | |
| | | // Overflow value s.t. atan(overflow_) = pi/2 | |
| | | static const real | |
| | | overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon()); | |
| | | return overflow; | |
| | | } | |
| // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right | | // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right | |
| static inline real tanx(real x) { | | static inline real tanx(real x) { | |
|
| real t = std::tan(x); | | using std::tan; | |
| | | real t = tan(x); | |
| // Write the tests this way to ensure that tanx(NaN()) is NaN() | | // Write the tests this way to ensure that tanx(NaN()) is NaN() | |
|
| return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl | | return x >= 0 ? | |
| ow_); | | (!(t < 0) ? t : overflow()) : | |
| | | (!(t >= 0) ? t : -overflow()); | |
| } | | } | |
| | | | |
| real taup(real tau) const; | | real taup(real tau) const; | |
| real taupinv(real taup) const; | | real taupinv(real taup) const; | |
| | | | |
| void zeta(real u, real snu, real cnu, real dnu, | | void zeta(real u, real snu, real cnu, real dnu, | |
| real v, real snv, real cnv, real dnv, | | real v, real snv, real cnv, real dnv, | |
| real& taup, real& lam) const; | | real& taup, real& lam) const; | |
| | | | |
| void dwdzeta(real u, real snu, real cnu, real dnu, | | void dwdzeta(real u, real snu, real cnu, real dnu, | |
| | | | |
| skipping to change at line 134 | | skipping to change at line 139 | |
| real snu, real cnu, real dnu, | | real snu, real cnu, real dnu, | |
| real snv, real cnv, real dnv, | | real snv, real cnv, real dnv, | |
| real& gamma, real& k) const; | | real& gamma, real& k) const; | |
| | | | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters). | | * @param[in] a equatorial radius (meters). | |
|
| * @param[in] f flattening of ellipsoid. If \e f > 1, set flattening | | * @param[in] f flattening of ellipsoid. If \e f > 1, set flattenin
g | |
| * to 1/\e f. | | * to 1/\e f. | |
| * @param[in] k0 central scale factor. | | * @param[in] k0 central scale factor. | |
| * @param[in] extendp use extended domain. | | * @param[in] extendp use extended domain. | |
| * @exception GeographicErr if \e a, \e f, or \e k0 is not positive. | | * @exception GeographicErr if \e a, \e f, or \e k0 is not positive. | |
| * | | * | |
| * The transverse Mercator projection has a branch point singularity at
\e | | * The transverse Mercator projection has a branch point singularity at
\e | |
| * lat = 0 and \e lon − \e lon0 = 90 (1 − \e e) or (for | | * lat = 0 and \e lon − \e lon0 = 90 (1 − \e e) or (for | |
| * TransverseMercatorExact::UTM) x = 18381 km, y = 0m. The \e extendp | | * TransverseMercatorExact::UTM) x = 18381 km, y = 0m. The \e extendp | |
| * argument governs where the branch cut is placed. With \e extendp = | | * argument governs where the branch cut is placed. With \e extendp = | |
| * false, the "standard" convention is followed, namely the cut is plac
ed | | * false, the "standard" convention is followed, namely the cut is plac
ed | |
| | | | |
| skipping to change at line 273 | | skipping to change at line 278 | |
| * k0 used in the constructor and is the scale on the central meridia
n. | | * k0 used in the constructor and is the scale on the central meridia
n. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real CentralScale() const { return _k0; } | | Math::real CentralScale() const { return _k0; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of TransverseMercatorExact with the WGS84 | | * A global instantiation of TransverseMercatorExact with the WGS84 | |
| * ellipsoid and the UTM scale factor. However, unlike UTM, no false | | * ellipsoid and the UTM scale factor. However, unlike UTM, no false | |
| * easting or northing is added. | | * easting or northing is added. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static const TransverseMercatorExact UTM; | | static const TransverseMercatorExact& UTM(); | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP | | #endif // GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP | |
| | | | |
End of changes. 7 change blocks. |
| 10 lines changed or deleted | | 14 lines changed or added | |
|
| UTMUPS.hpp | | UTMUPS.hpp | |
| | | | |
| skipping to change at line 33 | | skipping to change at line 33 | |
| * The Universal Grids: Universal Transverse Mercator (UTM) and Univers
al | | * The Universal Grids: Universal Transverse Mercator (UTM) and Univers
al | |
| * Polar Stereographic (UPS)</a>, Defense Mapping Agency, Technical Man
ual | | * Polar Stereographic (UPS)</a>, Defense Mapping Agency, Technical Man
ual | |
| * TM8358.2 (1989). | | * TM8358.2 (1989). | |
| * . | | * . | |
| * Section 2-3 defines UTM and section 3-2.4 defines UPS. This document
also | | * Section 2-3 defines UTM and section 3-2.4 defines UPS. This document
also | |
| * includes approximate algorithms for the computation of the underlying | | * includes approximate algorithms for the computation of the underlying | |
| * transverse Mercator and polar stereographic projections. Here we | | * transverse Mercator and polar stereographic projections. Here we | |
| * substitute much more accurate algorithms given by | | * substitute much more accurate algorithms given by | |
| * GeographicLib:TransverseMercator and GeographicLib:PolarStereographic. | | * GeographicLib:TransverseMercator and GeographicLib:PolarStereographic. | |
| * These are the algorithms recommended by the NGA document | | * These are the algorithms recommended by the NGA document | |
|
| * - <a href="https://nsgreg.nga.mil/doc/view?i=4056"> The Universal Grid | | * - <a href="http://earth-info.nga.mil/GandG/publications/NGA_SIG_0012_2 | |
| s | | _0_0_UTMUPS/NGA.SIG.0012_2.0.0_UTMUPS.pdf"> | |
| * and the Transverse Mercator and Polar Stereographic Map Projections< | | * The Universal Grids and the Transverse Mercator and Polar Stereograp | |
| /a>, | | hic | |
| * NGA.SIG.0012_2.0.0_UTMUPS (2014). | | * Map Projections</a>, NGA.SIG.0012_2.0.0_UTMUPS (2014). | |
| * | | * | |
| * In this implementation, the conversions are closed, i.e., output from | | * In this implementation, the conversions are closed, i.e., output from | |
| * Forward is legal input for Reverse and vice versa. The error is about
5nm | | * Forward is legal input for Reverse and vice versa. The error is about
5nm | |
| * in each direction. However, the conversion from legal UTM/UPS coordin
ates | | * in each direction. However, the conversion from legal UTM/UPS coordin
ates | |
| * to geographic coordinates and back might throw an error if the initial | | * to geographic coordinates and back might throw an error if the initial | |
| * point is within 5nm of the edge of the allowed range for the UTM/UPS | | * point is within 5nm of the edge of the allowed range for the UTM/UPS | |
| * coordinates. | | * coordinates. | |
| * | | * | |
| * The simplest way to guarantee the closed property is to define allowed | | * The simplest way to guarantee the closed property is to define allowed | |
| * ranges for the eastings and northings for UTM and UPS coordinates. Th
e | | * ranges for the eastings and northings for UTM and UPS coordinates. Th
e | |
| | | | |
| skipping to change at line 78 | | skipping to change at line 78 | |
| * hemisphere. In addition EncodeZone accepts an optional final argument
\e | | * hemisphere. In addition EncodeZone accepts an optional final argument
\e | |
| * abbrev, which, if false, results in the hemisphere being spelled out a
s in | | * abbrev, which, if false, results in the hemisphere being spelled out a
s in | |
| * "38north". | | * "38north". | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-UTMUPS.cpp | | * \include example-UTMUPS.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHICLIB_EXPORT UTMUPS { | | class GEOGRAPHICLIB_EXPORT UTMUPS { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| static const real falseeasting_[4]; | | static const int falseeasting_[4]; | |
| static const real falsenorthing_[4]; | | static const int falsenorthing_[4]; | |
| static const real mineasting_[4]; | | static const int mineasting_[4]; | |
| static const real maxeasting_[4]; | | static const int maxeasting_[4]; | |
| static const real minnorthing_[4]; | | static const int minnorthing_[4]; | |
| static const real maxnorthing_[4]; | | static const int maxnorthing_[4]; | |
| static const int epsg01N = 32601; // EPSG code for UTM 01N | | static const int epsg01N = 32601; // EPSG code for UTM 01N | |
| static const int epsg60N = 32660; // EPSG code for UTM 60N | | static const int epsg60N = 32660; // EPSG code for UTM 60N | |
| static const int epsgN = 32661; // EPSG code for UPS N | | static const int epsgN = 32661; // EPSG code for UPS N | |
| static const int epsg01S = 32701; // EPSG code for UTM 01S | | static const int epsg01S = 32701; // EPSG code for UTM 01S | |
| static const int epsg60S = 32760; // EPSG code for UTM 60S | | static const int epsg60S = 32760; // EPSG code for UTM 60S | |
| static const int epsgS = 32761; // EPSG code for UPS S | | static const int epsgS = 32761; // EPSG code for UPS S | |
| static real CentralMeridian(int zone) | | static real CentralMeridian(int zone) | |
| { return real(6 * zone - 183); } | | { return real(6 * zone - 183); } | |
| static void CheckLatLon(real lat, real lon); | | static void CheckLatLon(real lat, real lon); | |
| // Throw an error if easting or northing are outside standard ranges.
If | | // Throw an error if easting or northing are outside standard ranges.
If | |
| | | | |
| skipping to change at line 408 | | skipping to change at line 408 | |
| /** \name Inspector functions | | /** \name Inspector functions | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return \e a the equatorial radius of the WGS84 ellipsoid (meters). | | * @return \e a the equatorial radius of the WGS84 ellipsoid (meters). | |
| * | | * | |
| * (The WGS84 value is returned because the UTM and UPS projections are | | * (The WGS84 value is returned because the UTM and UPS projections are | |
| * based on this ellipsoid.) | | * based on this ellipsoid.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real MajorRadius() | | static Math::real MajorRadius() | |
|
| { return Constants::WGS84_a<real>(); } | | { return Constants::WGS84_a(); } | |
| | | | |
| /** | | /** | |
| * @return \e f the flattening of the WGS84 ellipsoid. | | * @return \e f the flattening of the WGS84 ellipsoid. | |
| * | | * | |
| * (The WGS84 value is returned because the UTM and UPS projections are | | * (The WGS84 value is returned because the UTM and UPS projections are | |
| * based on this ellipsoid.) | | * based on this ellipsoid.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real Flattening() | | static Math::real Flattening() | |
|
| { return Constants::WGS84_f<real>(); } | | { return Constants::WGS84_f(); } | |
| ///@} | | ///@} | |
| | | | |
| /// \cond SKIP | | /// \cond SKIP | |
| /** | | /** | |
| * <b>DEPRECATED</b> | | * <b>DEPRECATED</b> | |
| * @return \e r the inverse flattening of the WGS84 ellipsoid. | | * @return \e r the inverse flattening of the WGS84 ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real InverseFlattening() | | static Math::real InverseFlattening() | |
|
| { return 1/Constants::WGS84_f<real>(); } | | { return 1/Constants::WGS84_f(); } | |
| /// \endcond | | /// \endcond | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_UTMUPS_HPP | | #endif // GEOGRAPHICLIB_UTMUPS_HPP | |
| | | | |
End of changes. 5 change blocks. |
| 14 lines changed or deleted | | 14 lines changed or added | |
|
| Utility.hpp | | Utility.hpp | |
| | | | |
| skipping to change at line 267 | | skipping to change at line 267 | |
| * @tparam T the type of the argument. | | * @tparam T the type of the argument. | |
| * @param[in] x the value to be converted. | | * @param[in] x the value to be converted. | |
| * @param[in] p the precision used (default −1). | | * @param[in] p the precision used (default −1). | |
| * @exception std::bad_alloc if memory for the string can't be allocate
d. | | * @exception std::bad_alloc if memory for the string can't be allocate
d. | |
| * @return the string representation. | | * @return the string representation. | |
| * | | * | |
| * If \e p ≥ 0, then the number fixed format is used with p bits of | | * If \e p ≥ 0, then the number fixed format is used with p bits of | |
| * precision. With p < 0, there is no manipulation of the format. | | * precision. With p < 0, there is no manipulation of the format. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static std::string str(T x, int p = -1) { | | template<typename T> static std::string str(T x, int p = -1) { | |
|
| if (!std::numeric_limits<T>::is_integer && !Math::isfinite<T>(x)) | | std::ostringstream s; | |
| | | if (p >= 0) s << std::fixed << std::setprecision(p); | |
| | | s << x; return s.str(); | |
| | | } | |
| | | | |
| | | /** | |
| | | * Convert a Math::real object to a string. | |
| | | * | |
| | | * @param[in] x the value to be converted. | |
| | | * @param[in] p the precision used (default −1). | |
| | | * @exception std::bad_alloc if memory for the string can't be allocate | |
| | | d. | |
| | | * @return the string representation. | |
| | | * | |
| | | * If \e p ≥ 0, then the number fixed format is used with p bits of | |
| | | * precision. With p < 0, there is no manipulation of the format. Thi | |
| | | s is | |
| | | * an overload of str<T> which deals with inf and nan. | |
| | | ********************************************************************** | |
| | | / | |
| | | static std::string str(Math::real x, int p = -1) { | |
| | | if (!Math::isfinite(x)) | |
| return x < 0 ? std::string("-inf") : | | return x < 0 ? std::string("-inf") : | |
| (x > 0 ? std::string("inf") : std::string("nan")); | | (x > 0 ? std::string("inf") : std::string("nan")); | |
| std::ostringstream s; | | std::ostringstream s; | |
| if (p >= 0) s << std::fixed << std::setprecision(p); | | if (p >= 0) s << std::fixed << std::setprecision(p); | |
| s << x; return s.str(); | | s << x; return s.str(); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Convert a string to an object of type T. | | * Convert a string to an object of type T. | |
| * | | * | |
| | | | |
| skipping to change at line 385 | | skipping to change at line 403 | |
| * @tparam bigendp true if the external storage format is big-endian. | | * @tparam bigendp true if the external storage format is big-endian. | |
| * @param[in] str the input stream containing the data of type ExtT | | * @param[in] str the input stream containing the data of type ExtT | |
| * (external). | | * (external). | |
| * @param[out] array the output array of type IntT (internal). | | * @param[out] array the output array of type IntT (internal). | |
| * @param[in] num the size of the array. | | * @param[in] num the size of the array. | |
| * @exception GeographicErr if the data cannot be read. | | * @exception GeographicErr if the data cannot be read. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename ExtT, typename IntT, bool bigendp> | | template<typename ExtT, typename IntT, bool bigendp> | |
| static inline void readarray(std::istream& str, | | static inline void readarray(std::istream& str, | |
| IntT array[], size_t num) { | | IntT array[], size_t num) { | |
|
| | | #if GEOGRAPHICLIB_PRECISION < 4 | |
| if (sizeof(IntT) == sizeof(ExtT) && | | if (sizeof(IntT) == sizeof(ExtT) && | |
| std::numeric_limits<IntT>::is_integer == | | std::numeric_limits<IntT>::is_integer == | |
|
| std::numeric_limits<ExtT>::is_integer) { | | std::numeric_limits<ExtT>::is_integer) | |
| // Data is compatible (aside from the issue of endian-ness). | | { | |
| str.read(reinterpret_cast<char *>(array), num * sizeof(ExtT)); | | // Data is compatible (aside from the issue of endian-ness). | |
| if (!str.good()) | | str.read(reinterpret_cast<char *>(array), num * sizeof(ExtT)); | |
| throw GeographicErr("Failure reading data"); | | | |
| if (bigendp != Math::bigendian) { // endian mismatch -> swap bytes | | | |
| for (size_t i = num; i--;) | | | |
| array[i] = Math::swab<IntT>(array[i]); | | | |
| } | | | |
| } else { | | | |
| const int bufsize = 1024; // read this many values at a time | | | |
| ExtT buffer[bufsize]; // temporary buffer | | | |
| int k = int(num); // data values left to read | | | |
| int i = 0; // index into output array | | | |
| while (k) { | | | |
| int n = (std::min)(k, bufsize); | | | |
| str.read(reinterpret_cast<char *>(buffer), n * sizeof(ExtT)); | | | |
| if (!str.good()) | | if (!str.good()) | |
| throw GeographicErr("Failure reading data"); | | throw GeographicErr("Failure reading data"); | |
|
| for (int j = 0; j < n; ++j) | | if (bigendp != Math::bigendian) { // endian mismatch -> swap byte | |
| // fix endian-ness and cast to IntT | | s | |
| array[i++] = IntT(bigendp == Math::bigendian ? buffer[j] : | | for (size_t i = num; i--;) | |
| Math::swab<ExtT>(buffer[j])); | | array[i] = Math::swab<IntT>(array[i]); | |
| k -= n; | | } | |
| | | } | |
| | | else | |
| | | #endif | |
| | | { | |
| | | const int bufsize = 1024; // read this many values at a time | |
| | | ExtT buffer[bufsize]; // temporary buffer | |
| | | int k = int(num); // data values left to read | |
| | | int i = 0; // index into output array | |
| | | while (k) { | |
| | | int n = (std::min)(k, bufsize); | |
| | | str.read(reinterpret_cast<char *>(buffer), n * sizeof(ExtT)); | |
| | | if (!str.good()) | |
| | | throw GeographicErr("Failure reading data"); | |
| | | for (int j = 0; j < n; ++j) | |
| | | // fix endian-ness and cast to IntT | |
| | | array[i++] = IntT(bigendp == Math::bigendian ? buffer[j] : | |
| | | Math::swab<ExtT>(buffer[j])); | |
| | | k -= n; | |
| | | } | |
| } | | } | |
|
| } | | | |
| return; | | return; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Read data of type ExtT from a binary stream to a vector array of typ
e | | * Read data of type ExtT from a binary stream to a vector array of typ
e | |
| * IntT. The data in the file is in (bigendp ? big : little)-endian | | * IntT. The data in the file is in (bigendp ? big : little)-endian | |
| * format. | | * format. | |
| * | | * | |
| * @tparam ExtT the type of the objects in the binary stream (external)
. | | * @tparam ExtT the type of the objects in the binary stream (external)
. | |
| * @tparam IntT the type of the objects in the array (internal). | | * @tparam IntT the type of the objects in the array (internal). | |
| | | | |
| skipping to change at line 449 | | skipping to change at line 472 | |
| * @tparam ExtT the type of the objects in the binary stream (external)
. | | * @tparam ExtT the type of the objects in the binary stream (external)
. | |
| * @tparam IntT the type of the objects in the array (internal). | | * @tparam IntT the type of the objects in the array (internal). | |
| * @tparam bigendp true if the external storage format is big-endian. | | * @tparam bigendp true if the external storage format is big-endian. | |
| * @param[out] str the output stream for the data of type ExtT (externa
l). | | * @param[out] str the output stream for the data of type ExtT (externa
l). | |
| * @param[in] array the input array of type IntT (internal). | | * @param[in] array the input array of type IntT (internal). | |
| * @param[in] num the size of the array. | | * @param[in] num the size of the array. | |
| * @exception GeographicErr if the data cannot be written. | | * @exception GeographicErr if the data cannot be written. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename ExtT, typename IntT, bool bigendp> | | template<typename ExtT, typename IntT, bool bigendp> | |
| static inline void writearray(std::ostream& str, | | static inline void writearray(std::ostream& str, | |
|
| const IntT array[], size_t num) { | | const IntT array[], size_t num) { | |
| | | #if GEOGRAPHICLIB_PRECISION < 4 | |
| if (sizeof(IntT) == sizeof(ExtT) && | | if (sizeof(IntT) == sizeof(ExtT) && | |
| std::numeric_limits<IntT>::is_integer == | | std::numeric_limits<IntT>::is_integer == | |
| std::numeric_limits<ExtT>::is_integer && | | std::numeric_limits<ExtT>::is_integer && | |
|
| bigendp == Math::bigendian) { | | bigendp == Math::bigendian) | |
| // Data is compatible (including endian-ness). | | { | |
| str.write(reinterpret_cast<const char *>(array), num * sizeof(ExtT) | | // Data is compatible (including endian-ness). | |
| ); | | str.write(reinterpret_cast<const char *>(array), num * sizeof(Ext | |
| if (!str.good()) | | T)); | |
| throw GeographicErr("Failure writing data"); | | | |
| } else { | | | |
| const int bufsize = 1024; // write this many values at a time | | | |
| ExtT buffer[bufsize]; // temporary buffer | | | |
| int k = int(num); // data values left to write | | | |
| int i = 0; // index into output array | | | |
| while (k) { | | | |
| int n = (std::min)(k, bufsize); | | | |
| for (int j = 0; j < n; ++j) | | | |
| // cast to ExtT and fix endian-ness | | | |
| buffer[j] = bigendp == Math::bigendian ? ExtT(array[i++]) : | | | |
| Math::swab<ExtT>(ExtT(array[i++])); | | | |
| str.write(reinterpret_cast<const char *>(buffer), n * sizeof(ExtT | | | |
| )); | | | |
| if (!str.good()) | | if (!str.good()) | |
| throw GeographicErr("Failure writing data"); | | throw GeographicErr("Failure writing data"); | |
|
| k -= n; | | | |
| } | | } | |
|
| } | | else | |
| | | #endif | |
| | | { | |
| | | const int bufsize = 1024; // write this many values at a time | |
| | | ExtT buffer[bufsize]; // temporary buffer | |
| | | int k = int(num); // data values left to write | |
| | | int i = 0; // index into output array | |
| | | while (k) { | |
| | | int n = (std::min)(k, bufsize); | |
| | | for (int j = 0; j < n; ++j) | |
| | | // cast to ExtT and fix endian-ness | |
| | | buffer[j] = bigendp == Math::bigendian ? ExtT(array[i++]) : | |
| | | Math::swab<ExtT>(ExtT(array[i++])); | |
| | | str.write(reinterpret_cast<const char *>(buffer), n * sizeof(Ex | |
| | | tT)); | |
| | | if (!str.good()) | |
| | | throw GeographicErr("Failure writing data"); | |
| | | k -= n; | |
| | | } | |
| | | } | |
| return; | | return; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Write data in an array of type IntT as type ExtT to a binary stream. | | * Write data in an array of type IntT as type ExtT to a binary stream. | |
| * The data in the file is in (bigendp ? big : little)-endian format. | | * The data in the file is in (bigendp ? big : little)-endian format. | |
| * | | * | |
| * @tparam ExtT the type of the objects in the binary stream (external)
. | | * @tparam ExtT the type of the objects in the binary stream (external)
. | |
| * @tparam IntT the type of the objects in the array (internal). | | * @tparam IntT the type of the objects in the array (internal). | |
| * @tparam bigendp true if the external storage format is big-endian. | | * @tparam bigendp true if the external storage format is big-endian. | |
| | | | |
| skipping to change at line 505 | | skipping to change at line 533 | |
| /** | | /** | |
| * Parse a KEY VALUE line. | | * Parse a KEY VALUE line. | |
| * | | * | |
| * @param[in] line the input line. | | * @param[in] line the input line. | |
| * @param[out] key the key. | | * @param[out] key the key. | |
| * @param[out] val the value. | | * @param[out] val the value. | |
| * @exception std::bad_alloc if memory for the internal strings can't b
e | | * @exception std::bad_alloc if memory for the internal strings can't b
e | |
| * allocated. | | * allocated. | |
| * @return whether a key was found. | | * @return whether a key was found. | |
| * | | * | |
|
| * A # character and everything after it are discarded. If the results
is | | * A # character and everything after it are discarded. If the result
is | |
| * just white space, the routine returns false (and \e key and \e val a
re | | * just white space, the routine returns false (and \e key and \e val a
re | |
| * not set). Otherwise the first token is taken to be the key and the
rest | | * not set). Otherwise the first token is taken to be the key and the
rest | |
| * of the line (trimmed of leading and trailing white space) is the val
ue. | | * of the line (trimmed of leading and trailing white space) is the val
ue. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static bool ParseLine(const std::string& line, | | static bool ParseLine(const std::string& line, | |
| std::string& key, std::string& val); | | std::string& key, std::string& val); | |
| | | | |
|
| | | /** | |
| | | * Set the binary precision of a real number. | |
| | | * | |
| | | * @param[in] ndigits the number of bits of precision. If ndigits is 0 | |
| | | * (the default), then determine the precision from the environment | |
| | | * variable GEOGRAPHICLIB_DIGITS. If this is undefined, use ndigits | |
| | | = | |
| | | * 256 (i.e., about 77 decimal digits). | |
| | | * @return the resulting number of bits of precision. | |
| | | * | |
| | | * This only has an effect when GEOGRAPHICLIB_PRECISION == 5. | |
| | | ********************************************************************** | |
| | | / | |
| | | static int set_digits(int ndigits = 0); | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #if defined(_MSC_VER) | | #if defined(_MSC_VER) | |
| # pragma warning (pop) | | # pragma warning (pop) | |
| #endif | | #endif | |
| | | | |
| #endif // GEOGRAPHICLIB_UTILITY_HPP | | #endif // GEOGRAPHICLIB_UTILITY_HPP | |
| | | | |
End of changes. 11 change blocks. |
| 47 lines changed or deleted | | 94 lines changed or added | |
|