16# pragma warning (disable: 5055)
29 , _rm(_aux.RectifyingRadius(_exact))
30 , _c2(_aux.AuthalicRadiusSquared(_exact) *
Math::degree())
31 , _lL(_exact ? 8 : Lmax_)
43 void Rhumb::AreaCoeffs() {
47 static const real eps = numeric_limits<real>::epsilon()/2;
51 DST fft(L); fft.transform(f, c.data()); L *= 2;
58 int Lmax = 1<<(int(ceil(log2(max(
Math::digits(), 64)))) + 6);
59 for (_lL = 0; L <= Lmax && _lL == 0; L *=2) {
60 fft.reset(L/2); c.resize(L); fft.refine(f, c.data());
62 for (
int l = 0, k = -1; l < L; ++l) {
64 _pP[l] = (c[l] + (l+1 < L ? c[l+1] : 0)) / (-4 * (l+1));
65 if (fabs(_pP[l]) <= eps) {
69 if (k >= 0 && l - k + 1 >= (l + 1 + 7) / 8) {
71 _lL = l + 1; _pP.resize(_lL);
break;
77 _lL = int(_pP.size());
82#if GEOGRAPHICLIB_RHUMBAREA_ORDER == 4
83 static const real coeffs[] = {
90#elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 5
91 static const real coeffs[] = {
100#elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 6
101 static const real coeffs[] = {
103 138734126/
real(638512875), -102614/
real(467775), 596/
real(2025),
105 17749373/
real(425675250), -24562/
real(155925), 1543/
real(4725),
107 1882432/
real(8513505), -38068/
real(155925), 152/
real(945),
110 62464/
real(2027025), -101/
real(17325),
113#elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 7
114 static const real coeffs[] = {
116 -565017322/
real(1915538625), 138734126/
real(638512875),
119 -1969276/
real(58046625), 17749373/
real(425675250), -24562/
real(155925),
121 -58573784/
real(638512875), 1882432/
real(8513505), -38068/
real(155925),
123 -6975184/
real(42567525), 268864/
real(2027025), -752/
real(10395),
125 -112832/
real(1447875), 62464/
real(2027025), -101/
real(17325),
126 -4096/
real(289575), 11537/
real(4054050),
129#elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 8
130 static const real coeffs[] = {
132 188270561816LL/
real(488462349375LL), -565017322/
real(1915538625),
133 138734126/
real(638512875), -102614/
real(467775), 596/
real(2025),
135 2332829602LL/
real(23260111875LL), -1969276/
real(58046625),
136 17749373/
real(425675250), -24562/
real(155925), 1543/
real(4725),
138 -41570288/
real(930404475), -58573784/
real(638512875),
139 1882432/
real(8513505), -38068/
real(155925), 152/
real(945),
141 1538774036/
real(10854718875LL), -6975184/
real(42567525),
143 436821248/
real(3618239625LL), -112832/
real(1447875),
144 62464/
real(2027025), -101/
real(17325),
145 3059776/
real(80405325), -4096/
real(289575), 11537/
real(4054050),
146 4193792/
real(723647925), -311/
real(525525),
147 1097653/
real(1929727800),
150#error "Bad value for GEOGRAPHICLIB_RHUMBAREA_ORDER"
153 static_assert(
sizeof(coeffs) /
sizeof(
real) ==
154 (Lmax_ * (Lmax_ + 1))/2,
155 "Coefficient array size mismatch for Rhumb");
158 for (
int l = 0; l < Lmax_; ++l) {
159 int m = Lmax_ - l - 1;
168 Rhumb::qIntegrand::qIntegrand(
const AuxLatitude& aux)
185 betaa,
true).normalized()),
187 phia ,
true).normalized()),
189 phia ,
true).normalized());
190 real schi = chia.y(), cchi = chia.x(), sxi = xia.y(), cxi = xia.x(),
191 cphi = phia.x(), cbeta = betaa.x();
192 return (1 - _aux.Flattening()) *
193 ( fabs(schi) < fabs(cchi) ? sxi - schi :
194 (cchi - cxi) * (cxi + cchi) / (sxi + schi) ) / (cphi * cbeta);
210 void Rhumb::GenInverse(real lat1, real lon1, real lat2, real lon2,
212 real& s12, real& azi12, real& S12)
const {
219 lam12 = lon12 * Math::degree<real>(),
226 if (isinf(psi1) || isinf(psi2)) {
230 phi1, _exact).
radians()) * _rm;
232 real h = hypot(lam12, psi12);
234 real dmudpsi = _exact ?
238 s12 = h * dmudpsi * _rm;
242 S12 = _c2 * lon12 * MeanSinXi(chi1, chi2);
246 {
return RhumbLine(*
this, lat1, lon1, azi12); }
248 void Rhumb::GenDirect(real lat1, real lon1, real azi12, real s12,
250 real& lat2, real& lon2, real& S12)
const
251 {
Line(lat1, lon1, azi12).
GenPosition(s12, outmask, lat2, lon2, S12); }
262 betay.radians() - betax.radians(),
263 betax.y(), betax.x(), betay.y(), betay.x(),
265 tx = chix.
tan(), ty = chiy.
tan(),
273 RhumbLine::RhumbLine(
const Rhumb& rh,
real lat1,
real lon1,
real azi12)
275 , _lat1(Math::LatFix(lat1))
277 , _azi12(Math::AngNormalize(azi12))
282 _phi1, _rh._exact).degrees();
289 real& lat2, real& lon2, real& S12)
const {
301 lat2x = phi2.degrees();
302 real dmudpsi = _rh._exact ?
306 lon2x = r12 * _salp / dmudpsi;
308 S12 = _rh._c2 * lon2x * _rh.MeanSinXi(_chi1, chi2);
322 if (outmask &
LATITUDE) lat2 = lat2x;
Header for GeographicLib::DST class.
GeographicLib::Math::real real
Header for GeographicLib::Rhumb and GeographicLib::RhumbLine classes.
An accurate representation of angles.
Math::real radians() const
AuxAngle normalized() const
Math::real degrees() const
AuxAngle Convert(int auxin, int auxout, const AuxAngle &zeta, bool exact=false) const
static Math::real Dlam(real x, real y)
Math::real DParametric(const AuxAngle &phi1, const AuxAngle &phi2) const
Math::real DConvert(int auxin, int auxout, const AuxAngle &zeta1, const AuxAngle &zeta2) const
Math::real DIsometric(const AuxAngle &phi1, const AuxAngle &phi2) const
static Math::real Dp0Dpsi(real x, real y)
static Math::real DClenshaw(bool sinp, real Delta, real szeta1, real czeta1, real szeta2, real czeta2, const real c[], int K)
Math::real DRectifying(const AuxAngle &phi1, const AuxAngle &phi2) const
Discrete sine transforms.
Mathematical functions needed by GeographicLib.
static void sincosd(T x, T &sinx, T &cosx)
static T atan2d(T y, T x)
static T AngNormalize(T x)
static T polyval(int N, const T p[], T x)
static T AngDiff(T x, T y, T &e)
@ hd
degrees per half turn
@ qd
degrees per quarter turn
Find a sequence of points on a single rhumb line.
void GenPosition(real s12, unsigned outmask, real &lat2, real &lon2, real &S12) const
Solve of the direct and inverse rhumb problems.
RhumbLine Line(real lat1, real lon1, real azi12) const
Rhumb(real a, real f, bool exact=false)
static const Rhumb & WGS84()
Namespace for GeographicLib.