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();
378 if constexpr (debug_) msg =
"A.b.2 general bet1/2 = 0 non-equatorial";
383 alp2 =
ang(kp() * omg2.
s(), k() * bet2.
c());
386 fic = TL::fline::fics(lf, bet2, omg2, alp2);
389 real delta = (lf.transpolar() ? -1 : 1) * fic.delta;
409 ang(exp(lf.deltashift()/2 - delta), 1));
410 fic = TL::fline::fics(lf, bet1, omg1, alp1);
411 d = lf.ArcPos0(fic, (betp ? bet2 - bet1 : omg2 - omg1).base(),
412 bet2a, omg2a, alp2, betp);
413 if constexpr (debug_) msg =
"B.a umbilic to general";
415 }
else if (bet1.
c() == 0) {
419 if (!signbit(omg2.
s())) {
430 if constexpr (debug_) msg =
"B.b general bet1 = -90";
432 }
else if (omg1.
s() == 0) {
444 alpa =
ang(-numeric_limits<real>::epsilon()/(1<<20), -1, 0,
true);
445 alpb =
ang(-numeric_limits<real>::epsilon()/(1<<20), 1, 0,
true);
449 if constexpr (debug_) msg =
"B.c general omg1 = 0";
454 alpa =
ang( kp() * fabs(omg1.
s()), k() * fabs(bet1.
c()));
457 fic = TL::fline::fics(lf, bet1, omg1, alpb);
458 unsigned qb = 0U, qa = 3U;
459 if constexpr (debug_) msg =
"B.d general";
460 for (; !done && qb <= 4U; ++qb, ++qa) {
466 f[qb] = lf.Hybrid0(fic, bet2, omg2);
467 if constexpr (debug_)
468 cout <<
"f[qb] " << qb <<
" " << f[qb] <<
"\n";
469 if (fabs(f[qb]) < 2*numeric_limits<real>::epsilon()) {
471 d = lf.Hybrid(fic, bet2, bet2a, omg2a, alp2);
472 if constexpr (debug_) msg =
"B.d accidental umbilic";
473 backside = signbit(bet2a.
c());
478 if (qb && (f[qa & 3U] < 0 && f[qb & 3U] > 0) &&
483 f[qb & 3U] - f[qa & 3U] < 4) {
487 if constexpr (debug_)
488 cout <<
"fDD " << done <<
" " << qa <<
" " << qb <<
" "
489 << f[qa & 3U] <<
" " << f[qb & 3U] <<
"\n";
491 fa = f[qa & 3U]; fb = f[qb & 3U];
497 int countn = 0, countb = 0;
500 if constexpr (debug_)
501 cout <<
"X " << done <<
" " << msg <<
"\n";
503 [
this, &bet1, &omg1, &bet2, &omg2]
504 (
const ang& alp) -> real
506 return HybridA(bet1, omg1, alp, bet2, omg2,
true);
511 if constexpr (debug_)
512 cout <<
"ALP1 " <<
real(alp1) <<
"\n";
513 lf = TL::fline(this->
t(), gamma(bet1, omg1, alp1));
514 fic = TL::fline::fics(lf, bet1, omg1, alp1);
530 if (hybridalt_ && (swapomg_ || omg1.
s() <= fabs(omg2.
s())))
531 betp = (lf.transpolar() ?
532 2 * (aa + lf.gammax()) > (aa + bb) :
533 2 * (bb + lf.gammax()) < (aa + bb));
534 d = lf.Hybrid(fic, betp ? bet2 : omg2, bet2a, omg2a, alp2, betp);
536 backside = (betp || bet2.
c() != 0) && signbit(bet2a.
c());
539 if (!biaxial() && backside) alp2.
reflect(
true,
true);
542 TL::gline lg(this->
t(), lf.gm());
543 TL::gline::gics gic(lg, fic);
544 s12 = lg.dist(gic, d);
546 if constexpr (debug_)
548 << flip1 << flip2 << swap12 << swapomg
549 << flipz << flipy << flipx << flipomg
550 << lf.transpolar() <<
"\n";
551 if constexpr (debug_)
553 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
554 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
562 if constexpr (debug_)
564 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
565 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
573 if constexpr (debug_)
575 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
576 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
591 if constexpr (debug_)
593 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
594 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
602 if constexpr (debug_)
604 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
605 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
608 if (lf.transpolar()) {
610 calp1 = copysign(hypot(k()/kp()*bet1.
c(), lf.nu()), alp1.
c()),
611 calp2 = copysign(hypot(k()/kp()*bet2.
c(), lf.nu()), alp2.
c()),
612 salp1 = (lf.nu() < lf.nup() ?
613 (omg1.
s() - lf.nu()) * (omg1.
s() + lf.nu()) :
614 (lf.nup() - omg1.
c()) * (lf.nup() + omg1.
c())),
615 salp2 = (lf.nu() < lf.nup() ?
616 (omg2.
s() - lf.nu()) * (omg2.
s() + lf.nu()) :
617 (lf.nup() - omg2.
c()) * (lf.nup() + omg2.
c()));
618 salp1 = -copysign(signbit(salp1) ? 0 : sqrt(salp1), alp2.
s());
619 salp2 = -copysign(signbit(salp2) ? 0 : sqrt(salp2), alp1.
s());
620 alp1 =
ang(salp1, calp1);
621 alp2 =
ang(salp2, calp2);
624 salp1 = -copysign(hypot(kp()/k()*omg1.
s(), lf.nu()), alp1.
s()),
625 salp2 = -copysign(hypot(kp()/k()*omg2.
s(), lf.nu()), alp2.
s()),
626 calp1 = (lf.nu() < lf.nup() ?
627 (bet1.
c() - lf.nu()) * (bet1.
c() + lf.nu()) :
628 (lf.nup() - bet1.
s()) * (lf.nup() + bet1.
s())),
629 calp2 = (lf.nu() < lf.nup() ?
630 (bet2.
c() - lf.nu()) * (bet2.
c() + lf.nu()) :
631 (lf.nup() - bet2.
s()) * (lf.nup() + bet2.
s()));
632 calp1 = copysign(signbit(calp1) ? 0 : sqrt(calp1), alp1.
c());
633 calp2 = copysign(signbit(calp2) ? 0 : sqrt(calp2), alp2.
c());
634 alp1 =
ang(salp1, calp1);
635 alp2 =
ang(salp2, calp2);
645 if (umb2 && !biaxial())
651 if constexpr (debug_)
653 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
654 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
655 if (flip1)
t().Flip(bet1, omg1, alp1);
656 if (flip2)
t().Flip(bet2, omg2, alp2);
658 if constexpr (debug_)
660 <<
real(bet1) <<
" " <<
real(omg1) <<
" " <<
real(alp1) <<
" "
661 <<
real(bet2) <<
" " <<
real(omg2) <<
" " <<
real(alp2) <<
"\n";
663 fic = TL::fline::fics(lf, bet10, omg10, alp1);
664 gic = TL::gline::gics(lg, fic);
665 gic.s13 = signbit(s12) ? 0 : s12;
668 return TL(std::move(lf), std::move(fic), std::move(lg), std::move(gic));