GeographicLib  1.43
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Gnomonic.cpp
Go to the documentation of this file.
1 /**
2  * \file Gnomonic.cpp
3  * \brief Implementation for GeographicLib::Gnomonic class
4  *
5  * Copyright (c) Charles Karney (2010-2011) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
11 
12 #if defined(_MSC_VER)
13 // Squelch warnings about potentially uninitialized local variables
14 # pragma warning (disable: 4701)
15 #endif
16 
17 namespace GeographicLib {
18 
19  using namespace std;
20 
22  : eps0_(numeric_limits<real>::epsilon())
23  , eps_(real(0.01) * sqrt(eps0_))
24  , _earth(earth)
25  , _a(_earth.MajorRadius())
26  , _f(_earth.Flattening())
27  {}
28 
29  void Gnomonic::Forward(real lat0, real lon0, real lat, real lon,
30  real& x, real& y, real& azi, real& rk)
31  const {
32  real azi0, m, M, t;
33  _earth.GenInverse(lat0, lon0, lat, lon,
36  t, azi0, azi, m, M, t, t);
37  rk = M;
38  if (M <= 0)
39  x = y = Math::NaN();
40  else {
41  real rho = m/M;
42  azi0 *= Math::degree();
43  x = rho * sin(azi0);
44  y = rho * cos(azi0);
45  }
46  }
47 
48  void Gnomonic::Reverse(real lat0, real lon0, real x, real y,
49  real& lat, real& lon, real& azi, real& rk)
50  const {
51  real
52  azi0 = atan2(x, y) / Math::degree(),
53  rho = Math::hypot(x, y),
54  s = _a * atan(rho/_a);
55  bool little = rho <= _a;
56  if (!little)
57  rho = 1/rho;
58  GeodesicLine line(_earth.Line(lat0, lon0, azi0,
63  int count = numit_, trip = 0;
64  real lat1, lon1, azi1, M;
65  while (count--) {
66  real m, t;
67  line.Position(s, lat1, lon1, azi1, m, M, t);
68  if (trip)
69  break;
70  // If little, solve rho(s) = rho with drho(s)/ds = 1/M^2
71  // else solve 1/rho(s) = 1/rho with d(1/rho(s))/ds = -1/m^2
72  real ds = little ? (m/M - rho) * M * M : (rho - M/m) * m * m;
73  s -= ds;
74  // Reversed test to allow escape with NaNs
75  if (!(abs(ds) >= eps_ * _a))
76  ++trip;
77  }
78  if (trip) {
79  lat = lat1; lon = lon1; azi = azi1; rk = M;
80  } else
81  lat = lon = azi = rk = Math::NaN();
82  return;
83  }
84 
85 } // namespace GeographicLib
static T NaN()
Definition: Math.hpp:629
GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps=ALL) const
Definition: Geodesic.cpp:118
void Reverse(real lat0, real lon0, real x, real y, real &lat, real &lon, real &azi, real &rk) const
Definition: Gnomonic.cpp:48
Math::real GenInverse(real lat1, real lon1, real lat2, real lon2, unsigned outmask, real &s12, real &azi1, real &azi2, real &m12, real &M12, real &M21, real &S12) const
Definition: Geodesic.cpp:136
Header for GeographicLib::Gnomonic class.
static T hypot(T x, T y)
Definition: Math.hpp:255
static T degree()
Definition: Math.hpp:228
void Forward(real lat0, real lon0, real lat, real lon, real &x, real &y, real &azi, real &rk) const
Definition: Gnomonic.cpp:29
Gnomonic(const Geodesic &earth=Geodesic::WGS84())
Definition: Gnomonic.cpp:21
Geodesic calculations
Definition: Geodesic.hpp:171