21 , _c2(_ell.Area() / 720)
24 #if GEOGRAPHICLIB_RHUMBAREA_ORDER == 4 25 static const real coeff[] = {
27 691, 7860, -20160, 18900, 0, 56700,
29 1772, -5340, 6930, -4725, 14175,
31 -1747, 1590, -630, 4725,
37 #elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 5 38 static const real coeff[] = {
40 -79036, 22803, 259380, -665280, 623700, 0, 1871100,
42 41662, 58476, -176220, 228690, -155925, 467775,
44 18118, -57651, 52470, -20790, 155925,
46 -23011, 17160, -5115, 51975,
52 #elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 6 53 static const real coeff[] = {
55 128346268, -107884140, 31126095, 354053700, -908107200, 851350500, 0,
58 -114456994, 56868630, 79819740, -240540300, 312161850, -212837625,
61 51304574, 24731070, -78693615, 71621550, -28378350, 212837625,
63 1554472, -6282003, 4684680, -1396395, 14189175,
65 -4913956, 3205800, -791505, 8108100,
67 1092376, -234468, 2027025,
71 #elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 7 72 static const real coeff[] = {
74 -317195588, 385038804, -323652420, 93378285, 1062161100, -2724321600LL,
75 2554051500LL, 0, 7662154500LL,
77 258618446, -343370982, 170605890, 239459220, -721620900, 936485550,
78 -638512875, 1915538625,
80 -248174686, 153913722, 74193210, -236080845, 214864650, -85135050,
83 114450437, 23317080, -94230045, 70270200, -20945925, 212837625,
85 15445736, -103193076, 67321800, -16621605, 170270100,
87 -27766753, 16385640, -3517020, 30405375,
89 4892722, -939228, 6081075,
93 #elif GEOGRAPHICLIB_RHUMBAREA_ORDER == 8 94 static const real coeff[] = {
96 71374704821LL, -161769749880LL, 196369790040LL, -165062734200LL,
97 47622925350LL, 541702161000LL, -1389404016000LL, 1302566265000LL, 0,
100 -13691187484LL, 65947703730LL, -87559600410LL, 43504501950LL,
101 61062101100LL, -184013329500LL, 238803815250LL, -162820783125LL,
104 30802104839LL, -63284544930LL, 39247999110LL, 18919268550LL,
105 -60200615475LL, 54790485750LL, -21709437750LL, 162820783125LL,
107 -8934064508LL, 5836972287LL, 1189171080, -4805732295LL, 3583780200LL,
108 -1068242175, 10854718875LL,
110 50072287748LL, 3938662680LL, -26314234380LL, 17167059000LL,
111 -4238509275LL, 43418875500LL,
113 359094172, -9912730821LL, 5849673480LL, -1255576140, 10854718875LL,
115 -16053944387LL, 8733508770LL, -1676521980, 10854718875LL,
117 930092876, -162639357, 723647925,
119 -673429061, 1929727800,
122 #error "Bad value for GEOGRAPHICLIB_RHUMBAREA_ORDER" 124 GEOGRAPHICLIB_STATIC_ASSERT(
sizeof(coeff) /
sizeof(real) ==
125 ((maxpow_ + 1) * (maxpow_ + 4))/2,
126 "Coefficient array size mismatch for Rhumb");
129 for (
int l = 0; l <= maxpow_; ++l) {
135 _R[l] = d *
Math::polyval(m, coeff + o, _ell._n) / coeff[o + m + 1];
147 void Rhumb::GenInverse(real lat1, real lon1, real lat2, real lon2,
149 real& s12, real& azi12, real& S12)
const {
159 real dmudpsi = DIsometricToRectifying(psi2, psi1);
168 {
return RhumbLine(*
this, lat1, lon1, azi12, _exact); }
170 void Rhumb::GenDirect(real lat1, real lon1, real azi12, real s12,
172 real& lat2, real& lon2, real& S12)
const 173 {
Line(lat1, lon1, azi12).
GenPosition(s12, outmask, lat2, lon2, S12); }
179 return d ? (ei.
E(x) - ei.
E(y)) / d : 1;
195 real sx = sin(x), sy = sin(y), cx = cos(x), cy = cos(y);
196 real Dt = Dsin(x, y) * (sx + sy) /
197 ((cx + cy) * (sx * ei.
Delta(sy, cy) + sy * ei.
Delta(sx, cx))),
198 t = d * Dt, Dsz = 2 * Dt / (1 + t*t),
199 sz = d * Dsz, cz = (1 - t) * (1 + t) / (1 + t*t);
200 return ((sz ? ei.
E(sz, cz, ei.
Delta(sz, cz)) / sz : 1)
201 - ei.
k2() * sx * sy) * Dsz;
204 Math::real Rhumb::DRectifying(real latx, real laty)
const {
208 return (
Math::pi()/2) * _ell._b * _ell._f1 * DE(atan(tbetx), atan(tbety))
212 Math::real Rhumb::DIsometric(real latx, real laty)
const {
216 return Dasinh(tx, ty) * Dtan(latx, laty)
217 - Deatanhe(sin(phix), sin(phiy)) * Dsin(phix, phiy);
221 real x, real y,
const real c[],
int n) {
255 real p = x + y, d = x - y,
256 cp = cos(p), cd = cos(d),
257 sp = sin(p), sd = d ? sin(d)/d : 1,
258 m = 2 * cp * cd, s = sp * sd;
260 const real a[4] = {m, -s * d * d, -4 * s, m};
261 real ba[4] = {0, 0, 0, 0};
262 real bb[4] = {0, 0, 0, 0};
265 if (n > 0) b1[0] = b1[3] = c[n];
266 for (
int j = n - 1; j > 0; --j) {
269 b1[0] = a[0] * b2[0] + a[1] * b2[2] - b1[0] + c[j];
270 b1[1] = a[0] * b2[1] + a[1] * b2[3] - b1[1];
271 b1[2] = a[2] * b2[0] + a[3] * b2[2] - b1[2];
272 b1[3] = a[2] * b2[1] + a[3] * b2[3] - b1[3] + c[j];
279 real f11 = cd * sp, f12 = 2 * sd * cp;
281 s = b1[2] * f11 + b1[3] * f12;
284 real f11 = cd * cp, f12 = - 2 * sd * sp;
286 s = - b2[2] + b1[2] * f11 + b1[3] * f12;
291 Math::real Rhumb::DConformalToRectifying(real chix, real chiy)
const {
292 return 1 + SinCosSeries(
true, chix, chiy,
293 _ell.ConformalToRectifyingCoeffs(), tm_maxord);
296 Math::real Rhumb::DRectifyingToConformal(real mux, real muy)
const {
297 return 1 - SinCosSeries(
true, mux, muy,
298 _ell.RectifyingToConformalCoeffs(), tm_maxord);
301 Math::real Rhumb::DIsometricToRectifying(real psix, real psiy)
const {
306 return DRectifying(latx, laty) / DIsometric(latx, laty);
310 return DConformalToRectifying(gd(psix), gd(psiy)) * Dgd(psix, psiy);
314 Math::real Rhumb::DRectifyingToIsometric(real mux, real muy)
const {
319 DIsometric(latx, laty) / DRectifying(latx, laty) :
322 DRectifyingToConformal(mux, muy);
325 Math::real Rhumb::MeanSinXi(real psix, real psiy)
const {
326 return Dlog(cosh(psix), cosh(psiy)) * Dcosh(psix, psiy)
327 + SinCosSeries(
false, gd(psix), gd(psiy), _R, maxpow_) * Dgd(psix, psiy);
330 RhumbLine::RhumbLine(
const Rhumb& rh, real lat1, real lon1, real azi12,
339 _salp = _azi12 == -180 ? 0 : sin(alp12);
340 _calp = abs(_azi12) == 90 ? 0 : cos(alp12);
341 _mu1 = _rh._ell.RectifyingLatitude(lat1);
342 _psi1 = _rh._ell.IsometricLatitude(lat1);
343 _r1 = _rh._ell.CircleRadius(lat1);
347 real& lat2, real& lon2, real& S12)
const {
349 mu12 = s12 * _calp * 90 / _rh._ell.QuarterMeridian(),
351 real psi2, lat2x, lon2x;
352 if (abs(mu2) <= 90) {
354 lat2x = _rh._ell.InverseRectifyingLatitude(mu2);
355 real psi12 = _rh.DRectifyingToIsometric( mu2 *
Math::degree(),
357 lon2x = _salp * psi12 / _calp;
358 psi2 = _psi1 + psi12;
365 S12 = _rh._c2 * lon2x *
374 lat2x = _rh._ell.InverseRectifyingLatitude(mu2);
379 if (outmask &
LATITUDE) lat2 = lat2x;
static T AngNormalize(T x)
RhumbLine Line(real lat1, real lon1, real azi12) const
Math::real IsometricLatitude(real phi) const
Math::real InverseRectifyingLatitude(real mu) const
Rhumb(real a, real f, bool exact=true)
static T AngDiff(T x, T y, T &e)
Header for GeographicLib::Rhumb and GeographicLib::RhumbLine classes.
Elliptic integrals and functions.
Math::real QuarterMeridian() const
static const Rhumb & WGS84()
static T atan2d(T y, T x)
static T polyval(int N, const T p[], T x)
Namespace for GeographicLib.
Math::real InverseIsometricLatitude(real psi) const
Math::real Delta(real sn, real cn) const
Solve of the direct and inverse rhumb problems.
Find a sequence of points on a single rhumb line.
void GenPosition(real s12, unsigned outmask, real &lat2, real &lon2, real &S12) const
static T taupf(T tau, T es)