diff --git a/hypgraph.cpp b/hypgraph.cpp index 4931e67f..6ca91edf 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -211,7 +211,7 @@ bool hypot_zlev(ld zlev, ld& d, ld& df, ld& zf) { int twopoint_sphere_flips; bool twopoint_do_flips; -ld find_zlev(hyperpoint& H) { +EX ld find_zlev(hyperpoint& H) { if(spatial_graphics) { ld zlev = zlevel(H); diff --git a/rogueviz/extra-projections.cpp b/rogueviz/extra-projections.cpp index 7a69397f..17e64d62 100644 --- a/rogueviz/extra-projections.cpp +++ b/rogueviz/extra-projections.cpp @@ -31,6 +31,13 @@ template void add_complex(const char *name, flagtype flag, const T& f) }); } +template void add_extra(const char *name, flagtype flag, const T& f) { + int q = isize(mdinf); + mdinf.emplace_back(modelinfo{name, name, name, mf::euc_boring | mf::broken | flag, 0, 0, 0, 0, 0, nullptr}); + while(isize(extra_projections) < q) extra_projections.emplace_back(); + extra_projections.emplace_back(f); + } + template void add_band(const char *name, flagtype flag, const T& f) { int q = isize(mdinf); mdinf.emplace_back(modelinfo{name, name, name, mf::euc_boring | mf::broken | flag, 0, 0, 0, 0, 0, nullptr}); @@ -181,6 +188,57 @@ void add_extra_projections() { x = ax; y = ay; }); + + add_extra("double horocyclic", 0, [] (shiftpoint& H_orig, hyperpoint& H, hyperpoint& ret) { + ret = H; + + if(hyperbolic) { + + find_zlev(H); + + models::apply_orientation_yz(H[1], H[2]); + models::apply_orientation(H[0], H[1]); + + hyperpoint h1 = deparabolic13(H); + ret[1] = h1[1]; + + h1 = deparabolic13(cspin90(0, 1) * H); + ret[0] = -h1[1]; + + if(GDIM == 3) { + h1 = deparabolic13(cspin90(2, 1) * H); + ret[0] = -h1[2]; + } + } + + ret[LDIM] = 1; + + if(hyperbolic) { + models::apply_orientation(ret[1], ret[0]); + models::apply_orientation_yz(ret[2], ret[1]); + } + }); + + add_extra("azimuthal cylindrical", 0, [] (shiftpoint& H_orig, hyperpoint& H, hyperpoint& ret) { + find_zlev(H); + models::apply_orientation_yz(H[1], H[2]); + models::apply_orientation(H[0], H[1]); + + ld x, y; + y = asin_auto(H[1]); + x = asin_auto_clamp(H[0] / cos_auto(y)); + + if(sphere) { + if(H[LDIM] < 0 && x > 0) x = M_PI - x; + else if(H[LDIM] < 0 && x <= 0) x = -M_PI - x; + } + x += H_orig.shift; + + ret[0] = x; + ret[1] = H[1] / H[0] * x; + if(GDIM == 2) ret[2] = H[2] / H[0] * x; + ret[LDIM] = 1; + }); } void gen_dual() {