From d7fe4af1e9fcce1f601e31242dec51a9fec1a788 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 27 Jan 2023 11:16:34 +0100 Subject: [PATCH] embeddings:: implemented the cylinderHE embedding --- embeddings.cpp | 35 ++++++++++++++++++++++++++++++++++- geometry2.cpp | 4 ++++ nonisotropic.cpp | 4 ++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/embeddings.cpp b/embeddings.cpp index 08dfa780..2a31f5c9 100644 --- a/embeddings.cpp +++ b/embeddings.cpp @@ -183,6 +183,23 @@ EX namespace geom3 { g = ginf[gSpace534].g; g.gameplay_dimension = 2; } + + if(spatial_embedding == seCylinderHE && ieuclid) { + g.kind = gcProduct; + g.homogeneous_dimension--; + g.sig[2] = -1; + } + + if(spatial_embedding == seCylinderHoro && ieuclid) { + g.kind = gcProduct; + g.homogeneous_dimension--; + g.sig[2] = -1; + } + + if(spatial_embedding == seCylinderNil && ieuclid) { + g = ginf[gNil].g; + g.gameplay_dimension = 2; + } } } } @@ -562,6 +579,21 @@ struct emb_euc_cylinder : emb_euclid_noniso { } }; +struct emb_euc_cylinder_he : emb_euc_cylinder { + bool no_spin() override { return true; } + transmatrix get_lsti() override { return cspin90(0, 2); } + hyperpoint actual_to_intermediate(hyperpoint a) override { + ld z0 = zlevel(a); + a /= exp(z0); + ld y0 = atan2(a[1], a[0]); + ld x0 = asin_auto(hypot(a[0], a[1])); + return hyperpoint(x0-1, y0, z0, 1); + } + transmatrix intermediate_to_actual_translation(hyperpoint i) override { + return zpush(i[2]) * cspin(1, 0, i[1]) * xpush(i[0]); + } + }; + struct emb_euc_in_sph : emb_euclid_noniso { bool is_euc_in_sph() override { return true; } ld center_z() override { return 1; } @@ -646,7 +678,7 @@ EX unique_ptr make_embed() { if(!embedded_plane) emb1 = new emb_none; else if(any_cylinder(spatial_embedding) && mgclass() == gcEuclid) - emb1 = new emb_euc_cylinder; + emb1 = spatial_embedding == seCylinderHE ? new emb_euc_cylinder_he : new emb_euc_cylinder; else if(mgclass() == ggclass()) emb1 = new emb_same_in_same; else if(mgclass() == gcSphere && among(ggclass(), gcHyperbolic, gcEuclid)) @@ -933,6 +965,7 @@ void embedding_method::auto_configure() { if(spatial_embedding == seProductS) configure_cylinder(); if(spatial_embedding == seCylinderE) configure_cylinder(); if(spatial_embedding == seCylinderH) configure_cylinder(); + if(spatial_embedding == seCylinderHE) configure_cylinder(); } } diff --git a/geometry2.cpp b/geometry2.cpp index 7a4cab7e..44bb5021 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -241,6 +241,8 @@ void horo_distance::become(hyperpoint h1) { a = 0, b = hdist(h1, C0); else if(cgi.emb->is_euc_in_product()) a = 0, b = hdist(h1, C0); + else if(cgi.emb->is_cylinder()) + a = 0, b = hdist(h1, tile_center()); else a = 0, b = intval(h1, tile_center()); } @@ -253,6 +255,8 @@ horo_distance::horo_distance(shiftpoint h1, const shiftmatrix& T) { if(sn::in() || mhybrid || nil || sl2) become(inverse_shift(T, h1)); else if(cgi.emb->is_euc_in_product()) a = 0, b = hdist(h1.h, unshift(T * tile_center(), h1.shift)); + else if(cgi.emb->is_cylinder()) + a = 0, b = hdist(h1.h, unshift(T * tile_center(), h1.shift)); else a = 0, b = intval(h1.h, unshift(T * tile_center(), h1.shift)); } diff --git a/nonisotropic.cpp b/nonisotropic.cpp index be839dfe..4aedad5a 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -1374,6 +1374,10 @@ EX namespace hybrid { dynamicval dgc(cginf.g.kind, cginf.g.sig[2] < 0 ? gcHyperbolic : gcSphere); return f(); } + if(cgi.emb->is_cylinder()) { + dynamicval dgc(cginf.g.kind, cginf.g.sig[2] < 0 ? gcHyperbolic : gcSphere); + return f(); + } geom3::light_flip(true); finalizer ff([] { geom3::light_flip(false); }); return f();