55 ang bet10(bet1), omg10(omg1);
58 bool flip1 =
t().
AngNorm(bet1, omg1, prolate()),
59 flip2 =
t().
AngNorm(bet2, omg2, prolate());
64 ang tmp1(prolate() ? omg2 : bet1), tmp2(prolate() ? omg1 : bet2);
66 ang tmp12 = tmp2 - tmp1;
67 swap12 = tmp12.
s() > 0;
68 if (!biaxial() && tmp12.
s() == 0) {
70 tmp1 = omg1; tmp2 = omg2;
73 swap12 = tmp12.
s() < 0;
86 }
else if (prolate()) {
93 bool swapomg = swapomg_ &&
95 !(bet1.
c() == 0 && omg2.
s() == 0) &&
96 fabs(omg2.
s()) < fabs(omg1.
s());
97 if (swapomg)
swap(omg1, omg2);
99 bool flipz = bet1.
s() > 0;
105 bool flipy = prolate() ? signbit(bet2.
c()) :
106 signbit(omg1.
s()) || (omg1.
s() == 0 && signbit(omg2.
s()));
116 bool flipx = signbit(omg1.
c());
121 bool flipomg = bet2.
c() == 0 && signbit(omg2.
s());
124 if (flipomg) omg2.
reflect(
true);
126 bool umb1 = bet1.
c() == 0 && omg1.
s() == 0,
127 umb2 = bet2.
c() == 0 && omg2.
s() == 0;
224 TL::fline lf = _umbline->_f;
230 if constexpr (debug_)
231 cout <<
"COORDS " <<
real(bet1) <<
" " <<
real(omg1) <<
" "
232 <<
real(bet2) <<
" " <<
real(omg2) <<
"\n";
235 bool done =
false, backside =
false;
236 if (bet1.
c() * omg1.
s() == 0 && bet2.
c() * omg2.
s() == 0) {
238 if (umb1 && umb2 && bet2.
s() > 0 && omg2.
c() < 0) {
241 alp1 = biaxial() ?
ang(k(), kp(), 0,
true) :
242 ang(exp(lf.deltashift()/2), 1);
243 fic = TL::fline::fics(lf, bet1, omg1, alp1);
244 bool betp = k2() < kp2();
247 d = lf.ArcPos0(fic,
ang::cardinal(2), bet2a, omg2a, alp2, betp);
248 if constexpr (debug_) msg =
"A.c opposite umbilics";
249 backside = signbit(bet2a.
c());
251 }
else if (bet1.
c() == 0 && bet2.
c() == 0) {
258 fic = TL::fline::fics(lf, bet1, omg1, alp1);
259 ang omg12 = omg2 - omg1;
260 if (omg12.
s() == 0 && omg12.
c() < 0) {
264 TL::fline::disttx{ (biaxial() ? 1 : -1 ) *
Math::pi()/2,
268 TL::fline::disttx{ -BigValue(), BigValue(), 0 };
269 if constexpr (debug_) msg =
"A.c.2 adjacent EW umbilics";
272 d = lf.ArcPos0(fic, omg12.
base(), bet2a, omg2a, alp2,
false);
273 if constexpr (debug_) msg =
"A.c.2 bet1/2 = -90";
284 fic = TL::fline::fics(lf, bet1, omg1, alp1);
286 if (omg1.
s() == 0 && omg2.
s() == 0) {
291 TL::fline::disttx{ BigValue(), -BigValue(), 0 };
293 if constexpr (debug_) msg =
"A.c.3 adjacent NS umbilics";
304 if (omg2a.
s() >= -numeric_limits<real>::epsilon()/2) {
306 ang omg12 = omg2 + omg1;
308 d = lf.ArcPos0(fic, omg12.
base(), bet2a, omg2a, alp2,
false);
309 if (!biaxial() && signbit(omg2a.
s()))
311 if constexpr (debug_) msg =
"A.c.3 bet1/2 = -/+90 meridional";
316 (void) lf.ArcPos0(fic,
ang::cardinal(-2), bet2a, omg2a, alp2);
320 if constexpr (debug_)
321 msg =
"A.c.3 general bet1/2 = -/+90, non-meridional";
324 if constexpr (debug_)
326 <<
real(alpa) <<
" " << fa <<
" "
327 <<
real(alpb) <<
" " << fb <<
"\n";
337 alp1 = oblate() ? omg2 :
342 (omg1.
s() == 0 && !prolate() ? 0 : -1)) :
343 (omg2.
c() > 0 ? 0 : 2)));
344 fic = TL::fline::fics(lf, bet1, omg1, alp1);
346 lf.ArcPos0(fic, (omg2-omg1).base(), bet2a, omg2a, alp2,
false) :
347 lf.Hybrid(fic, bet2, bet2a, omg2a, alp2);
348 if (prolate() && signbit(bet2a.
c()))
350 if constexpr (debug_) msg =
"A.c.4 other meridional";
351 backside = signbit(bet2a.
c());
354 }
else if (bet1.
s() == 0 && bet2.
s() == 0) {
356 ang omg12 = (omg2 - omg1).base();
357 int E = signbit(omg12.
s()) ? -1 : 1;
361 lf = TL::fline(this->
t(), gamma(bet1, omg1, alp1));
362 fic = TL::fline::fics(lf, bet1, omg1, alp1);
363 (void) lf.ArcPos0(fic,
ang::cardinal(2), bet2a, omg2a, alp2);
365 if (E * omg2a.
s() >= -numeric_limits<real>::epsilon()/2) {
367 d = lf.ArcPos0(fic, omg12.
flipsign(E), bet2a, omg2a, alp2,
false);
368 if constexpr (debug_) msg =
"A.b.1 bet1/2 = 0 equatorial";
374 (E > 0 ? fa : fb) = omg2a.
radians0();
375 (void) lf.ArcPos0(fic,
ang::cardinal(-2), bet2a, omg2a, alp2);
377 (E > 0 ? fb : fa) = omg2a.
radians0();
409 if constexpr (debug_) msg =
"A.b.2 general bet1/2 = 0 non-equatorial";
414 alp2 =
ang(kp() * omg2.
s(), k() * bet2.
c());
417 fic = TL::fline::fics(lf, bet2, omg2, alp2);
420 real delta = (lf.transpolar() ? -1 : 1) * fic.delta;
440 ang(exp(lf.deltashift()/2 - delta), 1));
441 fic = TL::fline::fics(lf, bet1, omg1, alp1);
442 d = lf.ArcPos0(fic, (betp ? bet2 - bet1 : omg2 - omg1).base(),
443 bet2a, omg2a, alp2, betp);
444 if constexpr (debug_) msg =
"B.a umbilic to general";
446 }
else if (bet1.
c() == 0) {
450 if (!signbit(omg2.
s())) {
461 if constexpr (debug_) msg =
"B.b general bet1 = -90";
463 }
else if (omg1.
s() == 0) {
475 alpa =
ang(-numeric_limits<real>::epsilon()/(1<<20), -1, 0,
true);
476 alpb =
ang(-numeric_limits<real>::epsilon()/(1<<20), 1, 0,
true);
480 if constexpr (debug_) msg =
"B.c general omg1 = 0";
485 alpa =
ang( kp() * fabs(omg1.
s()), k() * fabs(bet1.
c()));
488 fic = TL::fline::fics(lf, bet1, omg1, alpb);
489 unsigned qb = 0U, qa = 3U;
490 if constexpr (debug_) msg =
"B.d general";
491 for (; !done && qb <= 4U; ++qb, ++qa) {
497 f[qb] = lf.Hybrid0(fic, bet2, omg2);
498 if constexpr (debug_)
499 cout <<
"f[qb] " << qb <<
" " << f[qb] <<
"\n";
500 if (fabs(f[qb]) < 2*numeric_limits<real>::epsilon()) {
502 d = lf.Hybrid(fic, bet2, bet2a, omg2a, alp2);
503 if constexpr (debug_) msg =
"B.d accidental umbilic";
504 backside = signbit(bet2a.
c());
509 if (qb && (f[qa & 3U] < 0 && f[qb & 3U] > 0) &&
514 f[qb & 3U] - f[qa & 3U] < 4) {
518 if constexpr (debug_)
519 cout <<
"fDD " << done <<
" " << qa <<
" " << qb <<
" "
520 << f[qa & 3U] <<
" " << f[qb & 3U] <<
"\n";
522 fa = f[qa & 3U]; fb = f[qb & 3U];
528 int countn = 0, countb = 0;
531 if constexpr (debug_)
532 cout <<
"X " << done <<
" " << msg <<
"\n";
534 [
this, &bet1, &omg1, &bet2, &omg2]
535 (
const ang& alp) -> real
537 return HybridA(bet1, omg1, alp, bet2, omg2,
true);
542 if constexpr (debug_)
543 cout <<
"ALP1 " <<
real(alp1) <<
"\n";
544 lf = TL::fline(this->
t(), gamma(bet1, omg1, alp1));
545 fic = TL::fline::fics(lf, bet1, omg1, alp1);
561 if (hybridalt_ && (swapomg_ || omg1.
s() <= fabs(omg2.
s())))
562 betp = (lf.transpolar() ?
563 2 * (aa + lf.gammax()) > (aa + bb) :
564 2 * (bb + lf.gammax()) < (aa + bb));
565 d = lf.Hybrid(fic, betp ? bet2 : omg2, bet2a, omg2a, alp2, betp);
567 backside = (betp || bet2.
c() != 0) && signbit(bet2a.
c());
570 if (!biaxial() && backside) alp2.
reflect(
true,
true);
573 TL::gline lg(this->
t(), lf.gm());
574 TL::gline::gics gic(lg, fic);
575 s12 = lg.dist(gic, d);
577 if constexpr (debug_)
579 << flip1 << flip2 << swap12 << swapomg
580 << flipz << flipy << flipx << flipomg
581 << lf.transpolar() <<
"\n";
582 if constexpr (debug_)
584 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
585 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
593 if constexpr (debug_)
595 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
596 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
604 if constexpr (debug_)
606 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
607 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
622 if constexpr (debug_)
624 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
625 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
633 if constexpr (debug_)
635 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
636 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
639 if (lf.transpolar()) {
641 calp1 = copysign(hypot(k()/kp()*bet1.
c(), lf.nu()), alp1.
c()),
642 calp2 = copysign(hypot(k()/kp()*bet2.
c(), lf.nu()), alp2.
c()),
643 salp1 = (lf.nu() < lf.nup() ?
644 (omg1.
s() - lf.nu()) * (omg1.
s() + lf.nu()) :
645 (lf.nup() - omg1.
c()) * (lf.nup() + omg1.
c())),
646 salp2 = (lf.nu() < lf.nup() ?
647 (omg2.
s() - lf.nu()) * (omg2.
s() + lf.nu()) :
648 (lf.nup() - omg2.
c()) * (lf.nup() + omg2.
c()));
649 salp1 = -copysign(signbit(salp1) ? 0 : sqrt(salp1), alp2.
s());
650 salp2 = -copysign(signbit(salp2) ? 0 : sqrt(salp2), alp1.
s());
651 alp1 =
ang(salp1, calp1);
652 alp2 =
ang(salp2, calp2);
655 salp1 = -copysign(hypot(kp()/k()*omg1.
s(), lf.nu()), alp1.
s()),
656 salp2 = -copysign(hypot(kp()/k()*omg2.
s(), lf.nu()), alp2.
s()),
657 calp1 = (lf.nu() < lf.nup() ?
658 (bet1.
c() - lf.nu()) * (bet1.
c() + lf.nu()) :
659 (lf.nup() - bet1.
s()) * (lf.nup() + bet1.
s())),
660 calp2 = (lf.nu() < lf.nup() ?
661 (bet2.
c() - lf.nu()) * (bet2.
c() + lf.nu()) :
662 (lf.nup() - bet2.
s()) * (lf.nup() + bet2.
s()));
663 calp1 = copysign(signbit(calp1) ? 0 : sqrt(calp1), alp1.
c());
664 calp2 = copysign(signbit(calp2) ? 0 : sqrt(calp2), alp2.
c());
665 alp1 =
ang(salp1, calp1);
666 alp2 =
ang(salp2, calp2);
676 if (umb2 && !biaxial())
682 if constexpr (debug_)
684 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
685 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
686 if (flip1)
t().Flip(bet1, omg1, alp1);
687 if (flip2)
t().Flip(bet2, omg2, alp2);
689 if constexpr (debug_)
691 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
692 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
694 fic = TL::fline::fics(lf, bet10, omg10, alp1);
695 gic = TL::gline::gics(lg, fic);
696 gic.s13 = signbit(s12) ? 0 : s12;
699 return TL(std::move(lf), std::move(fic), std::move(lg), std::move(gic));