GeographicLib 2.5
CassiniSoldner.cpp
Go to the documentation of this file.
1/**
2 * \file CassiniSoldner.cpp
3 * \brief Implementation for GeographicLib::CassiniSoldner class
4 *
5 * Copyright (c) Charles Karney (2009-2022) <karney@alum.mit.edu> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
11
12namespace GeographicLib {
13
14 using namespace std;
15
17 : _earth(earth) {}
18
19 CassiniSoldner::CassiniSoldner(real lat0, real lon0, const Geodesic& earth)
20 : _earth(earth)
21 { Reset(lat0, lon0); }
22
23 void CassiniSoldner::Reset(real lat0, real lon0) {
24 _meridian = _earth.Line(lat0, lon0, real(0),
28 real f = _earth.Flattening();
29 Math::sincosd(LatitudeOrigin(), _sbet0, _cbet0);
30 _sbet0 *= (1 - f);
31 Math::norm(_sbet0, _cbet0);
32 }
33
34 void CassiniSoldner::Forward(real lat, real lon, real& x, real& y,
35 real& azi, real& rk) const {
36 if (!Init())
37 return;
38 real dlon = Math::AngDiff(LongitudeOrigin(), lon);
39 real sig12, s12, azi1, azi2;
40 sig12 = _earth.Inverse(lat, -fabs(dlon), lat, fabs(dlon), s12, azi1, azi2);
41 sig12 *= real(0.5);
42 s12 *= real(0.5);
43 if (s12 == 0) {
44 real da = Math::AngDiff(azi1, azi2)/2;
45 if (fabs(dlon) <= Math::qd) {
46 azi1 = Math::qd - da;
47 azi2 = Math::qd + da;
48 } else {
49 azi1 = -Math::qd - da;
50 azi2 = -Math::qd + da;
51 }
52 }
53 if (signbit(dlon)) {
54 azi2 = azi1;
55 s12 = -s12;
56 sig12 = -sig12;
57 }
58 x = s12;
59 azi = Math::AngNormalize(azi2);
60 GeodesicLine perp(_earth.Line(lat, dlon, azi, Geodesic::GEODESICSCALE));
61 real t;
62 perp.GenPosition(true, -sig12,
64 t, t, t, t, t, t, rk, t);
65
66 real salp0, calp0;
67 Math::sincosd(perp.EquatorialAzimuth(), salp0, calp0);
68 real
69 sbet1 = lat >=0 ? calp0 : -calp0,
70 cbet1 = fabs(dlon) <= Math::qd ? fabs(salp0) : -fabs(salp0),
71 sbet01 = sbet1 * _cbet0 - cbet1 * _sbet0,
72 cbet01 = cbet1 * _cbet0 + sbet1 * _sbet0,
73 sig01 = atan2(sbet01, cbet01) / Math::degree();
74 _meridian.GenPosition(true, sig01,
76 t, t, t, y, t, t, t, t);
77 }
78
79 void CassiniSoldner::Reverse(real x, real y, real& lat, real& lon,
80 real& azi, real& rk) const {
81 if (!Init())
82 return;
83 real lat1, lon1;
84 real azi0, t;
85 _meridian.Position(y, lat1, lon1, azi0);
86 _earth.Direct(lat1, lon1, azi0 + Math::qd, x, lat, lon, azi, rk, t);
87 }
88
89} // namespace GeographicLib
Header for GeographicLib::CassiniSoldner class.
CassiniSoldner(const Geodesic &earth=Geodesic::WGS84())
void Reverse(real x, real y, real &lat, real &lon, real &azi, real &rk) const
void Forward(real lat, real lon, real &x, real &y, real &azi, real &rk) const
void Reset(real lat0, real lon0)
Math::real EquatorialAzimuth() const
Math::real Position(real s12, real &lat2, real &lon2, real &azi2, real &m12, real &M12, real &M21, real &S12) const
Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask, real &lat2, real &lon2, real &azi2, real &s12, real &m12, real &M12, real &M21, real &S12) const
Geodesic calculations
Definition Geodesic.hpp:175
Math::real Flattening() const
Definition Geodesic.hpp:969
Math::real Direct(real lat1, real lon1, real azi1, real s12, real &lat2, real &lon2, real &azi2, real &m12, real &M12, real &M21, real &S12) const
Definition Geodesic.hpp:394
GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps=ALL) const
Definition Geodesic.cpp:123
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, real &s12, real &azi1, real &azi2, real &m12, real &M12, real &M21, real &S12) const
Definition Geodesic.hpp:689
static T degree()
Definition Math.hpp:209
static void sincosd(T x, T &sinx, T &cosx)
Definition Math.cpp:101
static void norm(T &x, T &y)
Definition Math.hpp:231
static constexpr int qd
degrees per quarter turn
Definition Math.hpp:145
static T AngNormalize(T x)
Definition Math.cpp:66
static T AngDiff(T x, T y, T &e)
Definition Math.cpp:77
Namespace for GeographicLib.