22 , _ex(kp2() * (1 - e2() * k2 ()), - e2() * kp2(),
23 k2 () * (1 + e2() * kp2()), 1 + e2() * kp2())
24 , _ey(k2 () * (1 + e2() * kp2()), e2() * k2 (),
25 kp2() * (1 - e2() * k2 ()), 1 - e2() * k2 ())
26 , _x(
Math::sq(a()) / b() * _ex.Pi() )
27 , _y(
Math::sq(c()) / b() * _ey.Pi() )
29 _s = EquivSphere(_x, _y, _exs, _eys);
46 if (ell.
kp2() == 0 && (signbit(phi.
c()) || phi.
n() != 0))
49 if (phi.
n() != 0) p += 4 * ell.
Pi() * phi.
n();
58 y = remainder(
x, 2 * ell.
Pi());
59 n = 2 * round((
x -
y) / (2 * ell.
Pi()));
66 else if (fabs(
y) == ell.
Pi())
78 int countn = 0, countb = 0;
80 (real phi) -> pair<real, real>
82 real
s = sin(phi), c = cos(phi),
84 fp = 1 / (sqrt(ell.
kp2() + ell.
k2() * c*c) *
88 return pair<real, real>(f, fp);
90 real z = Trigfun::root(Trigfun::PIINV,
95 (void) countn; (void) countb;
100 Math::real Conformal3::F(
const EllipticFunction& ell,
ang phi) {
101 if (ell.kp2() == 0 && (signbit(phi.
c()) || phi.
n() != 0))
103 real p = ell.F(phi.
s(), phi.
c(), ell.Delta(phi.
s(), phi.
c()));
104 if (phi.
n() != 0) p += 4 * ell.K() * phi.
n();
107 Angle Conformal3::Finv(
const EllipticFunction& ell,
real x) {
109 if (ell.kp2() == 0) {
113 y = remainder(
x, 2 * ell.K());
114 n = 2 * round((
x -
y) / (2 * ell.K()));
121 else if (fabs(
y) == ell.K())
129 int countn = 0, countb = 0;
131 (real phi) -> pair<real, real>
133 real
s = sin(phi), c = cos(phi),
134 f = ell.F(
s, c, ell.Delta(
s, c)),
135 fp = 1 / sqrt(ell.kp2() + ell.k2() * c*c);
136 return pair<real, real>(f, fp);
138 real z = Trigfun::root(Trigfun::FINV,
139 Ff, fabs(
y), fabs(
y) *
Math::pi()/(2*ell.K()),
143 (void) countn; (void) countb;
150 omg = omegashift(omg, +1);
151 if (k2() == 0 && (signbit(omg.
c()) || omg.
n() != 0))
157 return omegashift(omg, -1);
161 if (kp2() == 0 && (signbit(bet.
c()) || bet.
n() != 0))
170 xa =
x(omg); ya =
y(bet);
177 Forward(bet, omg,
x,
y); m = 1/invscale(bet, omg);
181 Reverse(
x,
y, bet, omg); m = 1/invscale(bet, omg);
197 int countn = 0, countb = 0;
203 if (ny == 0) { k2 = 0;
break; }
208 k2 = 16/pow(exp(N*KK) - B, 2/N);
210 k2 = fmin(1/
real(2), 16*exp(-2*KK));
211 static const real logk2min = 2*log(numeric_limits<real>::epsilon());
213 real logk2 = log(k2);
214 if (logk2 > logk2min) {
215 auto ksolve = [nx, ny]
216 (
real logk2) -> pair<real, real>
218 real k2 = exp(logk2), kp2 = 1 - k2;
220 real f = nx * elly.
K() - ny * ellx.
K(),
221 fp = (nx * (elly.
E() - kp2 * elly.
K()) +
222 ny * (ellx.
E() - k2 * ellx.
K())) / (2 * k2 * kp2);
223 return pair<real, real>(f, k2*fp);
225 logk2 = Trigfun::root(Trigfun::KINV, ksolve, 0, logk2,
226 logk2min, -log(
real(2)),
236 elly = EllipticFunction(k2);
237 ellx = EllipticFunction(1-k2, 0, k2, 1);
238 real b =
y / elly.
K();
245 return Ellipsoid3(b, 0, k2, kp2);
249 if (ma == 0 || mb == 0) {
292 real e = sqrt(e2()), sg = sinh(e * atanh(e));
293 m = (c()/b()) * (hypot(sg,
real(1)) + sg);
294 }
else if (k2() == 0) {
296 real e = sqrt(e2()), sg = sinh(e * atan(e));
297 m = (a()/b()) / (hypot(sg,
real(1)) + sg);
300 m = sqrt(_s.k2() * _s.kp2()/(k2() * kp2())) * (b()/_s.b());
312 real ma = invscale(bet, omg);
313 ang omgs = omegashift(Finv(_exs,
x/_s.b()), -1),
314 bets = Finv(_eys,
y/_s.b()),
316 real mb = sqrt(_s.k2 () *
Math::sq(bets.c()) +
318 m = sphericalscale(ma, mb);
319 _s.elliptocart2(bets, omgs, alp, r, v);
323 Angle& gam, real& m)
const {
325 _s.cart2toellip(r, v, bets, omgs, alp);
328 real
x = _s.b() * F(_exs, omegashift(omgs, +1)),
329 y = _s.b() * F(_eys, bets);
330 real mb = sqrt(_s.k2() *
Math::sq(bets.
c()) +
334 real ma = invscale(bet, omg);
335 m = sphericalscale(ma, mb);
340 Angle& gam, real& m)
const {
344 real f = alt._s.
b()/_s.b();
345 r[0] *= f; r[1] *= f; r[2] *= f;
353 Angle& gam, real& m)
const {
354 alt.
ForwardOther(*
this, betalt, omgalt, bet, omg, gam, m);
GeographicLib::Math::real real
Header for GeographicLib::Trigfun class.
static AngleT cardinal(Math::real q)
Math::real radians() const
Elliptic integrals and functions.
Math::real alphap2() const
Math::real Delta(real sn, real cn) const
Math::real alpha2() const
Mathematical functions needed by GeographicLib.
static bool AngNorm(Angle &bet, Angle &omg, Angle &alp, bool alt=false)
Namespace for operations on triaxial ellipsoids.
Namespace for GeographicLib.
AngleT< Math::real > Angle
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)