Gnomonic.cpp
Go to the documentation of this file.
/**
* \file Gnomonic.cpp
* \brief Implementation for GeographicLib::Gnomonic class
*
* Copyright (c) Charles Karney (2010-2022) <karney@alum.mit.edu> and licensed
* under the MIT/X11 License. For more information, see
* https://geographiclib.sourceforge.io/
**********************************************************************/
#include <GeographicLib/Gnomonic.hpp>
#if defined(_MSC_VER)
// Squelch warnings about potentially uninitialized local variables and
// constant conditional expressions
# pragma warning (disable: 4701 4127)
#endif
namespace GeographicLib {
using namespace std;
Gnomonic::Gnomonic(const Geodesic& earth)
: eps0_(numeric_limits<real>::epsilon())
, eps_(real(0.01) * sqrt(eps0_))
, _earth(earth)
, _a(_earth.EquatorialRadius())
, _f(_earth.Flattening())
{}
void Gnomonic::Forward(real lat0, real lon0, real lat, real lon,
real& x, real& y, real& azi, real& rk) const {
real azi0, m, M, t;
_earth.GenInverse(lat0, lon0, lat, lon,
Geodesic::AZIMUTH | Geodesic::REDUCEDLENGTH |
Geodesic::GEODESICSCALE,
t, azi0, azi, m, M, t, t);
rk = M;
if (M <= 0)
x = y = Math::NaN();
else {
real rho = m/M;
Math::sincosd(azi0, x, y);
x *= rho; y *= rho;
}
}
void Gnomonic::Reverse(real lat0, real lon0, real x, real y,
real& lat, real& lon, real& azi, real& rk) const {
real
azi0 = Math::atan2d(x, y),
rho = hypot(x, y),
s = _a * atan(rho/_a);
bool little = rho <= _a;
if (!little)
rho = 1/rho;
GeodesicLine line(_earth.Line(lat0, lon0, azi0,
Geodesic::LATITUDE | Geodesic::LONGITUDE |
Geodesic::AZIMUTH | Geodesic::DISTANCE_IN |
Geodesic::REDUCEDLENGTH |
Geodesic::GEODESICSCALE));
int count = numit_, trip = 0;
real lat1, lon1, azi1, M;
while (count-- || GEOGRAPHICLIB_PANIC) {
real m, t;
line.Position(s, lat1, lon1, azi1, m, M, t);
if (trip)
break;
// If little, solve rho(s) = rho with drho(s)/ds = 1/M^2
// else solve 1/rho(s) = 1/rho with d(1/rho(s))/ds = -1/m^2
real ds = little ? (m - rho * M) * M : (rho * m - M) * m;
s -= ds;
// Reversed test to allow escape with NaNs
if (!(fabs(ds) >= eps_ * _a))
++trip;
}
if (trip) {
lat = lat1; lon = lon1; azi = azi1; rk = M;
} else
lat = lon = azi = rk = Math::NaN();
return;
}
} // namespace GeographicLib
Gnomonic.hpp
Header for GeographicLib::Gnomonic class.
GEOGRAPHICLIB_PANIC
#define GEOGRAPHICLIB_PANIC
Definition: Math.hpp:62
GeographicLib::GeodesicLine
A geodesic line.
Definition: GeodesicLine.hpp:74
GeographicLib::GeodesicLine::Position
Math::real Position(real s12, real &lat2, real &lon2, real &azi2, real &m12, real &M12, real &M21, real &S12) const
Definition: GeodesicLine.hpp:298
GeographicLib::Geodesic
Geodesic calculations
Definition: Geodesic.hpp:175
GeographicLib::Geodesic::Line
GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps=ALL) const
Definition: Geodesic.cpp:124
GeographicLib::Geodesic::REDUCEDLENGTH
@ REDUCEDLENGTH
Definition: Geodesic.hpp:313
GeographicLib::Geodesic::LATITUDE
@ LATITUDE
Definition: Geodesic.hpp:279
GeographicLib::Geodesic::LONGITUDE
@ LONGITUDE
Definition: Geodesic.hpp:284
GeographicLib::Geodesic::AZIMUTH
@ AZIMUTH
Definition: Geodesic.hpp:291
GeographicLib::Geodesic::DISTANCE_IN
@ DISTANCE_IN
Definition: Geodesic.hpp:308
GeographicLib::Geodesic::GEODESICSCALE
@ GEODESICSCALE
Definition: Geodesic.hpp:318
GeographicLib::Gnomonic::Gnomonic
Gnomonic(const Geodesic &earth=Geodesic::WGS84())
Definition: Gnomonic.cpp:22
GeographicLib::Gnomonic::Forward
void Forward(real lat0, real lon0, real lat, real lon, real &x, real &y, real &azi, real &rk) const
Definition: Gnomonic.cpp:30
GeographicLib::Gnomonic::Reverse
void Reverse(real lat0, real lon0, real x, real y, real &lat, real &lon, real &azi, real &rk) const
Definition: Gnomonic.cpp:47
GeographicLib::Math::sincosd
static void sincosd(T x, T &sinx, T &cosx)
Definition: Math.cpp:106
GeographicLib::Math::atan2d
static T atan2d(T y, T x)
Definition: Math.cpp:183
GeographicLib::Math::NaN
static T NaN()
Definition: Math.cpp:250
GeographicLib
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
std
Definition: NearestNeighbor.hpp:812