61 static constexpr int maxit_ = 300;
75 real _kap, _kapp, _eps, _mu, _sqrtmu, _sqrtkap, _sqrtkapp;
80 bool _umb, _meridr, _meridl, _biaxr, _biaxl;
83 static real fthtp(real c, real kap, real kapp, real eps, real mu);
84 static real fup(real cn, real kap, real kapp, real eps, real mu);
86 static real dfp(real c, real kap, real kapp, real eps);
87 static real dfvp(real cn, real dn, real kap, real kapp, real eps);
89 static real fpsip(real s, real c, real kap, real kapp,
91 static real fvp(real dn, real kap, real kapp, real eps, real mu);
93 static real fthtbiax(real tht, real eps, real mu);
95 static real dfpsibiax(real s, real c, real eps, real mu);
102 static real gthtp(real c, real kap, real kapp, real eps, real mu);
103 static real gup(real cn, real dn, real kap, real kapp,
106 static real g0p(real c, real kap, real kapp, real eps);
107 static real g0vp(real cn, real kap, real kapp, real eps);
109 static real gpsip(real s, real c, real kap, real kapp,
111 static real gvp(real cn, real dn, real kap, real kapp,
114 static real gthtbiax(real tht, real eps, real mu);
116 static real gpsibiax(real s, real c, real eps, real mu);
122 static real modang(real x, real m) {
125 real root(real z, real u0,
int* countn,
int* countb, real tol = 0)
const;
162 hfun(
bool distp, real kap, real kapp, real eps, real mu,
164 real operator()(real u)
const;
167 real deriv(real u)
const;
168 real df(real u)
const {
return _fun(u); }
169 real dfp(real u)
const {
return _fun.
deriv(u); }
172 real inv(real z,
int* countn =
nullptr,
int* countb =
nullptr)
const;
174 real fwd(real zeta)
const {
175 return _umb ? lam(zeta, _sqrtkapp) :
176 (_tx ? _ell.
F(zeta) : zeta);
178 real rev(real w)
const {
179 return _umb ? gd(w, _sqrtkapp) :
180 (_tx ? _ell.
am(w) : w);
182 int NCoeffs()
const {
return _fun.
NCoeffs(); }
183 bool txp()
const {
return _tx; }
184 real HalfPeriod()
const {
190 !_distp && _meridl ? 0 :
191 !_distp && _biaxl ? 1 - sqrt(-_mu) * _fun.
Slope() :
194 real Max()
const {
return _max; }
195 real MaxPlus()
const {
197 return fmax(_max, HalfPeriod() * (Slope() == 0 ? 1 : Slope()) / 1000);
204 Geodesic3::gamblk _gm;
231 ang bet1, ang omg1, ang alp1);
232 void setquadrant(
const fline& f,
unsigned q);
233 void pos1(
bool transpolar,
234 ang& bet10, ang& omg10, ang& alp10)
const;
243 fline(
const Geodesic3& tg,
bool neg =
false);
244 fline(
const Geodesic3& tg, Geodesic3::gamblk gm);
245 const hfun& fpsi()
const {
return _fpsi; }
246 const hfun& ftht()
const {
return _ftht; }
247 const hfun& fbet()
const {
248 return !transpolar() ? fpsi() : ftht();
250 const hfun& fomg()
const {
251 return transpolar() ? fpsi() : ftht();
253 const Geodesic3& tg()
const {
return _tg; }
254 const Ellipsoid3& t()
const {
return _tg.
t(); }
255 real gamma()
const {
return _gm.gamma; }
256 real gammax()
const {
return _gm.gammax; }
257 real kx2()
const {
return _gm.kx2; }
258 real kxp2()
const {
return _gm.kxp2; }
259 real kx()
const {
return _gm.kx; }
260 real kxp()
const {
return _gm.kxp; }
261 real nu()
const {
return _gm.nu; }
262 real nup()
const {
return _gm.nup; }
263 real deltashift()
const {
return _deltashift; }
264 bool transpolar()
const {
return _gm.transpolar; }
265 const Geodesic3::gamblk& gm()
const {
return _gm; }
269 real Hybrid0(
const fics& fic,
ang bet2,
ang omg2,
270 bool betp =
true)
const;
274 disttx Hybrid(
const fics& fic,
ang betomg2,
276 bool betp =
true)
const;
277 disttx ArcPos0(
const fics& fic,
ang tau12,
279 bool betp =
true)
const;
285 Geodesic3::gamblk _gm;
297 gline(
const Geodesic3& tg,
bool neg =
false);
298 gline(
const Geodesic3& tg,
const Geodesic3::gamblk& gm);
299 real gamma()
const {
return _gm.gamma; }
300 real gammax()
const {
return _gm.gammax; }
301 real kx2()
const {
return _gm.kx2; }
302 real kxp2()
const {
return _gm.kxp2; }
303 real kx()
const {
return _gm.kx; }
304 real kxp()
const {
return _gm.kxp; }
305 bool transpolar()
const {
return _gm.transpolar; }
306 const hfun& gpsi()
const {
return _gpsi; }
307 const hfun& gtht()
const {
return _gtht; }
308 const hfun& gbet()
const {
309 return !transpolar() ? gpsi() : gtht();
311 const hfun& gomg()
const {
312 return transpolar() ? gpsi() : gtht();
314 const Geodesic3& tg()
const {
return _tg; }
315 const Ellipsoid3& t()
const {
return _tg.t(); }
316 const Geodesic3::gamblk& gm()
const {
return _gm; }
317 real dist(gics ic, fline::disttx d)
const;
324 : z(z0), fz(fz0), gz(gz0) {}
325 bool operator<(
const zvals& t)
const {
return z < t.z; }
326 bool operator==(
const zvals& t)
const {
return z == t.z; }
331 std::vector<zvals> _s;
333 zset(
const zvals& a,
const zvals& b)
339 else if (!(a < b && a.fz <= b.fz && a.gz <= b.gz))
340 throw GeographicLib::GeographicErr(
"bad zset initializer");
342 int num()
const {
return int(_s.size()); }
343 const zvals& val(
int i)
const {
return _s[i]; }
344 const zvals& min()
const {
return _s[0]; }
345 const zvals& max()
const {
return _s.back(); }
346 int insert(zvals& t,
int flag = 0);
347 real bisect()
const {
352 real maxgap = -1;
int maxind = 0;
353 for (
int i = 0; i < num() - 1; ++i) {
354 real gap = _s[i+1].z - _s[i].z;
360 return (_s[maxind].z + _s[maxind+1].z) / 2;
370 static void solve2(
real f0,
real g0,
371 const hfun& fx,
const hfun& fy,
372 const hfun& gx,
const hfun& gy,
374 int* countn =
nullptr,
int* countb =
nullptr);
375 static void solve2u(
real f0,
real g0,
376 const hfun& fx,
const hfun& fy,
377 const hfun& gx,
const hfun& gy,
379 int* countn =
nullptr,
int* countb =
nullptr);
381 const hfun& fx,
const hfun& fy,
382 const hfun& gx,
const hfun& gy,
387 int* countn =
nullptr,
int* countb =
nullptr);
388 static void zsetsinsert(zset& xset, zset& yset,
389 zvals& xfg, zvals& yfg,
391 static void zsetsdiag(
const zset& xset,
const zset& yset,
393 static std::pair<real, real> zsetsbisect(
const zset& xset,
const zset& yset,
396 using std::fmax, std::fmin;
397 real z = mult * Geodesic3::BigValue();
398 return Math::clamp(x, -z, z);
402 using std::asinh, std::fabs;
403 return asinh(mult * x.
t());
408 return bigclamp(lamang0(x, mult));
411 using std::tan, std::asinh, std::fabs, std::copysign;
414 return fabs(x) >= Math::pi()/2 ? copysign(Geodesic3::BigValue(), x) :
415 asinh(mult * tan(x));
418 using std::atan, std::sinh;
419 return atan(sinh(x) / mult);
423 return ang(sinh(u), mult, 0);
426 using std::cosh, std::sinh, std::hypot;
427 return mult == 1 ? cosh(u) : hypot(sinh(u), mult) / mult;
430 const hfun& fbet()
const {
return _f.fbet(); }
431 const hfun& fomg()
const {
return _f.fomg(); }
432 const hfun& fpsi()
const {
return _f.fpsi(); }
433 const hfun& ftht()
const {
return _f.ftht(); }
434 const hfun& gbet()
const {
return _g.gbet(); }
435 const hfun& gomg()
const {
return _g.gomg(); }
436 const hfun& gpsi()
const {
return _g.gpsi(); }
437 const hfun& gtht()
const {
return _g.gtht(); }
442 static std::pair<real, real> remx(
real x,
real y,
bool alt =
false) {
443 using std::remainder, std::rint;
444 real z = remainder(x, y);
446 if (z == -y/2) z = y/2;
448 if (z == y/2) z = -y/2;
450 return std::pair<real, real>(z, rint((x - z) / y));
456 static std::pair<real, real> remx(
ang x,
bool alt =
false) {
459 if (signbit(x.
c())) {
464 if (alt && signbit(x.
s())) {
467 }
else if (!alt && !signbit(x.
s())) {
472 return std::pair<real, real>(x.
radians0(), m + 2*x.
n());
474 static bool biaxspecial(
const Geodesic3& tg,
real gamma) {
476 return Geodesic3::biaxp_ && (tg.t().k2() == 0 || tg.t().kp2() == 0) &&
477 gamma != 0 && fabs(gamma) < tg._ellipthresh;
481 GeodesicLine3(fline f, fline::fics fic, gline g, gline::gics gic);
483 GeodesicLine3(
const Geodesic3& tg);
490 void Hybrid(Angle betomg2,
491 Angle& bet2a, Angle& omg2a, Angle& alp2a,
492 real& s12,
bool betp =
true)
const;
502 GeodesicLine3(
const Geodesic3& tg, Angle bet1, Angle omg1, Angle alp1);
512 GeodesicLine3(
const Geodesic3& tg,
real bet1,
real omg1,
real alp1);
521 void Position(
real s12, Angle& bet2, Angle& omg2, Angle& alp2)
const;
534 bool unroll =
true)
const;
564 void pos1(
real& bet1,
real& omg1,
real& alp1,
bool unroll =
true)
const;