From 6e6d0a7839ea6fd76048634c036fa824a7f5c4bf Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Mon, 12 Jul 2021 11:07:22 +0200 Subject: [PATCH] the main (heptagon) cellshape now also uses subcellshape; removed dirdist and get_vertices and introduced get_cellshape instead --- asonov.cpp | 31 ++++--- barriers.cpp | 2 +- binary-tiling.cpp | 11 ++- cell.cpp | 14 +-- celldrawer.cpp | 20 +++-- commandline.cpp | 3 +- crystal.cpp | 2 +- euclid.cpp | 32 ++----- fake.cpp | 19 ++-- geometry.cpp | 21 +++-- geometry2.cpp | 6 -- polygons.cpp | 5 +- raycaster.cpp | 2 +- reg3.cpp | 220 +++++++++++++++++++++------------------------- 14 files changed, 182 insertions(+), 206 deletions(-) diff --git a/asonov.cpp b/asonov.cpp index b4564682..63727159 100644 --- a/asonov.cpp +++ b/asonov.cpp @@ -110,24 +110,27 @@ EX void prepare() { EX void prepare_walls() { - cgi.cellshape.clear(); + auto& hsh = cgi.heptshape; + hsh = unique_ptr(new subcellshape); + auto& cs = hsh->faces; + cs.clear(); auto pt = [&] (int x, int y, int z) { return asonov::tx*x/2 + asonov::ty*y/2 + asonov::tz*z/2 + C0; }; - cgi.cellshape.push_back({pt(-1,-1,+1), pt(00,+1,+1), pt(+1,+1,+1)}); - cgi.cellshape.push_back({pt(00,-1,+1), pt(+1,+1,+1), pt(+1,-1,+1)}); - cgi.cellshape.push_back({pt(-1,+1,+1), pt(00,+1,+1), pt(-1,-1,+1)}); - cgi.cellshape.push_back({pt(-1,-1,+1), pt(+1,+1,+1), pt(00,-1,+1)}); - cgi.cellshape.push_back({pt(+1,-1,-1), pt(+1,00,-1), pt(+1,+1,-1), pt(+1,+1,+1), pt(+1,-1,+1)}); - cgi.cellshape.push_back({pt(-1,+1,-1), pt(-1,+1,+1), pt(00,+1,+1), pt(+1,+1,+1), pt(+1,+1,-1)}); - cgi.cellshape.push_back({pt(-1,-1,-1), pt(-1,00,-1), pt(+1,-1,-1)}); - cgi.cellshape.push_back({pt(-1,00,-1), pt(-1,+1,-1), pt(+1,-1,-1)}); - cgi.cellshape.push_back({pt(-1,+1,-1), pt(+1,00,-1), pt(+1,-1,-1)}); - cgi.cellshape.push_back({pt(-1,+1,-1), pt(+1,+1,-1), pt(+1,00,-1)}); - cgi.cellshape.push_back({pt(-1,+1,-1), pt(-1,00,-1), pt(-1,-1,-1), pt(-1,-1,+1), pt(-1,+1,+1)}); - cgi.cellshape.push_back({pt(+1,-1,-1), pt(+1,-1,+1), pt(00,-1,+1), pt(-1,-1,+1), pt(-1,-1,-1)}); + cs.push_back({pt(-1,-1,+1), pt(00,+1,+1), pt(+1,+1,+1)}); + cs.push_back({pt(00,-1,+1), pt(+1,+1,+1), pt(+1,-1,+1)}); + cs.push_back({pt(-1,+1,+1), pt(00,+1,+1), pt(-1,-1,+1)}); + cs.push_back({pt(-1,-1,+1), pt(+1,+1,+1), pt(00,-1,+1)}); + cs.push_back({pt(+1,-1,-1), pt(+1,00,-1), pt(+1,+1,-1), pt(+1,+1,+1), pt(+1,-1,+1)}); + cs.push_back({pt(-1,+1,-1), pt(-1,+1,+1), pt(00,+1,+1), pt(+1,+1,+1), pt(+1,+1,-1)}); + cs.push_back({pt(-1,-1,-1), pt(-1,00,-1), pt(+1,-1,-1)}); + cs.push_back({pt(-1,00,-1), pt(-1,+1,-1), pt(+1,-1,-1)}); + cs.push_back({pt(-1,+1,-1), pt(+1,00,-1), pt(+1,-1,-1)}); + cs.push_back({pt(-1,+1,-1), pt(+1,+1,-1), pt(+1,00,-1)}); + cs.push_back({pt(-1,+1,-1), pt(-1,00,-1), pt(-1,-1,-1), pt(-1,-1,+1), pt(-1,+1,+1)}); + cs.push_back({pt(+1,-1,-1), pt(+1,-1,+1), pt(00,-1,+1), pt(-1,-1,+1), pt(-1,-1,-1)}); - reg3::make_vertices_only(); + hsh->compute_hept(); } transmatrix coord_to_matrix(coord c, coord zero) { diff --git a/barriers.cpp b/barriers.cpp index fef196ac..ec8dcb4b 100644 --- a/barriers.cpp +++ b/barriers.cpp @@ -753,7 +753,7 @@ EX bool valid_dir(const vector& ad, int j, cell *c) { if(!bch) return ad[j] == 1; if(ad[j] != 2) return false; - auto ad1 = currentmap->dirdist(c, j); + auto ad1 = currentmap->get_cellshape(c).dirdist[j]; int a = 0; for(auto& dd: ad1) if(dd == 1) a++; diff --git a/binary-tiling.cpp b/binary-tiling.cpp index dbff0e17..9d163863 100644 --- a/binary-tiling.cpp +++ b/binary-tiling.cpp @@ -472,8 +472,12 @@ EX namespace bt { return gm * where; } - vector get_vertices(cell* c) override { - vector res; + subcellshape& get_cellshape(cell *c) override { + if(cgi.heptshape) + return *cgi.heptshape; + + cgi.heptshape = (std::unique_ptr) (new subcellshape); + vector& res = cgi.heptshape->vertices_only; ld yy = log(2) / 2; auto add = [&] (hyperpoint h) { res.push_back(bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2])); @@ -512,7 +516,8 @@ EX namespace bt { } default: ; } - return res; + cgi.heptshape->vertices_only_local = res; + return *cgi.heptshape; } ld spin_angle(cell *c, int d) override { diff --git a/cell.cpp b/cell.cpp index 4032a4ca..20e92765 100644 --- a/cell.cpp +++ b/cell.cpp @@ -45,7 +45,6 @@ struct hrmap { } virtual void draw_all(); virtual void draw_at(cell *at, const shiftmatrix& where); - virtual vector get_vertices(cell*); virtual void virtualRebase(heptagon*& base, transmatrix& at) { printf("virtualRebase called unexpectedly\n"); @@ -76,13 +75,13 @@ struct hrmap { return currentmap->iadj(c, i); } - /** \brief in 3D honeycombs, returns a vector v, where v[j] iff faces i and j are adjacent */ - virtual const vector& dirdist(cell *c, int i) { throw hr_exception("dirdist called unexpectedly"); } + virtual subcellshape& get_cellshape(cell *c) { throw hr_exception("get_cellshape called unexpectedly"); } /** \brief in 3D honeycombs, returns a cellwalker res at cw->move(j) such that the face pointed at by cw and res share an edge */ virtual cellwalker strafe(cellwalker cw, int j) { throw hr_exception("strafe called unexpectedly"); } - const vector& dirdist(cellwalker cw) { return dirdist(cw.at, cw.spin); } + /** \brief in 3D honeycombs, returns a vector v, where v[j] iff faces i and j are adjacent */ + const vector& dirdist(cellwalker cw) { return get_cellshape(cw.at).dirdist[cw.spin]; } }; /** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient @@ -1287,7 +1286,8 @@ EX vector adj_minefield_cells(cell *c) { } else if(adj_memo.count(c)) return adj_memo[c]; else { - const vector vertices = currentmap->get_vertices(c); + auto& ss = currentmap->get_cellshape(c); + const vector& vertices = ss.vertices_only_local; manual_celllister cl; cl.add(c); for(int i=0; i adj_minefield_cells(cell *c) { bool shares = false; if(c != c1) { transmatrix T = currentmap->relative_matrix(c1->master, c->master, C0); - for(hyperpoint h: vertices) for(hyperpoint h2: vertices) + auto& ss1 = currentmap->get_cellshape(c1); + auto& vertices1 = ss1.vertices_only_local; + for(hyperpoint h: vertices) for(hyperpoint h2: vertices1) if(hdist(h, T * h2) < 1e-6) shares = true; if(shares) res.push_back(c1); } diff --git a/celldrawer.cpp b/celldrawer.cpp index 46865f2b..4dab9017 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -864,12 +864,14 @@ void celldrawer::draw_grid() { if(!bt::in() && c->move(t) < c) continue; dynamicval g(poly_outline, gridcolor(c, c->move(t))); if(fat_edges && reg3::in()) { - for(int i=0; imove(i) || fake::split()) { - for(int j=0; jget_cellshape(c); + for(int i=0; itype; i++) if(c < c->move(i) || fake::split()) { + int face = isize(ss.faces[i]); + for(int j=0; jmove(t)), prec); if(reg3::ultra_mirror_in()) { - hyperpoint a = cgi.cellshape[i][j]; - hyperpoint b = cgi.cellshape[i][jj]; - hyperpoint d = cgi.cellshape[i][jjj]; + hyperpoint a = ss.faces[i][j]; + hyperpoint b = ss.faces[i][jj]; + hyperpoint d = ss.faces[i][jjj]; auto& mm = cgi.ultra_mirror_part; tie(a, d) = make_pair(normalize(lerp(a, b, mm)), normalize(lerp(d, b, mm))); gridline(V, a, d, stdgridcolor, prec); diff --git a/commandline.cpp b/commandline.cpp index c801ba87..6f619906 100644 --- a/commandline.cpp +++ b/commandline.cpp @@ -250,7 +250,8 @@ int arg::readCommon() { } else if(argis("-face-vertex")) { PHASE(3); start_game(); - View = cspin(0, 2, M_PI/2) * spintox(cgi.vertices_only[0]); + auto &ss = cgi.get_cellshape(cwt.at); + View = cspin(0, 2, M_PI/2) * spintox(ss.vertices_only_local[0]); } else if(argis("-face-face")) { PHASE(3); start_game(); diff --git a/crystal.cpp b/crystal.cpp index 1cc745c6..d0d3c01e 100644 --- a/crystal.cpp +++ b/crystal.cpp @@ -647,7 +647,7 @@ struct hrmap_crystal : hrmap_standard { if(go > 1e-2) continue; for(int s=0; sdirdist[d][s] == 1) for(int t=0; t gdist + .1) diff --git a/euclid.cpp b/euclid.cpp index d7e71d31..ad43108e 100644 --- a/euclid.cpp +++ b/euclid.cpp @@ -292,28 +292,8 @@ EX namespace euc { return eumove(d); } - vector get_vertices(cell* c) override { - vector res; - if(S7 < 14) - for(ld a: {-.5,.5}) for(ld b: {-.5,.5}) for(ld c: {-.5, .5}) res.push_back(hpxy3(a,b,c)); - if(S7 == 12) { - res.push_back(hpxy3(1,0,0)); - res.push_back(hpxy3(-1,0,0)); - res.push_back(hpxy3(0,1,0)); - res.push_back(hpxy3(0,-1,0)); - res.push_back(hpxy3(0,0,1)); - res.push_back(hpxy3(0,0,-1)); - } - if(S7 == 14) { - for(ld a: {-1.,-.5,0.,.5,1.}) - for(ld b: {-1.,-.5,0.,.5,1.}) - for(ld c: {-1.,-.5,0.,.5,1.}) - if(a == 0 || b == 0 || c == 0) - if(a == .5 || a == -.5 || b == .5 || b == -.5 || c == .5 || c == -.5) - if(a == 1 || a == -1 || b == 1 || b == -1 || c == 1 || c == -1) - res.push_back(hpxy3(a,b,c)); - } - return res; + subcellshape& get_cellshape(cell* c) override { + return *cgi.heptshape; } }; @@ -1300,7 +1280,10 @@ EX void generate() { auto v = euc::get_shifttable(); - auto& cs = cgi.cellshape; + auto& hsh = cgi.heptshape; + hsh = unique_ptr(new subcellshape); + + auto& cs = hsh->faces; cgi.loop = 4; cgi.schmid = 3; @@ -1365,9 +1348,8 @@ EX void generate() { } } - reg3::make_vertices_only(); + hsh->compute_hept(); #endif - } /** @brief returns true if the current geometry is based on this module diff --git a/fake.cpp b/fake.cpp index 32957929..2e8eef73 100644 --- a/fake.cpp +++ b/fake.cpp @@ -332,11 +332,11 @@ EX vector> befake(const vector>& v) { EX ld compute_around(bool setup) { auto &ucgi = *underlying_cgip; - auto fcs = befake(ucgi.cellshape); + auto fcs = befake(ucgi.heptshape->faces); if(setup) { - cgi.cellshape = fcs; - cgi.vertices_only = befake(ucgi.vertices_only); + cgi.heptshape->faces = fcs; + cgi.heptshape->compute_hept(); } hyperpoint h = Hypc; @@ -394,11 +394,10 @@ EX void generate() { cgi.face = ucgi.face; cgi.schmid = ucgi.schmid; - for(int a=0; a<16; a++) - for(int b=0; b<16; b++) { - cgi.dirs_adjacent[a][b] = ucgi.dirs_adjacent[a][b]; - cgi.next_dir[a][b] = ucgi.next_dir[a][b]; - } + auto& hsh = cgi.heptshape; + hsh = unique_ptr(new subcellshape); + + *hsh = *ucgi.heptshape; for(int b=0; b<12; b++) cgi.spins[b] = ucgi.spins[b]; @@ -487,7 +486,7 @@ EX void compute_scale() { } else if(euclid) scale = 1; else if(have_ideal) { - hyperpoint h0 = underlying_cgip->cellshape[0][0]; + hyperpoint h0 = underlying_cgip->heptshape->faces[0][0]; auto s = kleinize(h0); ld d = hypot_d(LDIM, s); scale = 1/d; @@ -517,7 +516,7 @@ EX void compute_scale() { /* ultra a bit earlier */ if(underlying == gRhombic3 || underlying == gBitrunc3) { - auto fcs = befake(underlying_cgip->cellshape[0][0]); + auto fcs = befake(underlying_cgip->heptshape->faces[0][0]); set_flag(ginf[gFake].flags, qULTRA, material(fcs) < 0); } } diff --git a/geometry.cpp b/geometry.cpp index e2fd6fbd..7fdaba9e 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -98,7 +98,7 @@ struct gi_extension { virtual ~gi_extension() {} }; -/** for subdivided 3D cells */ +/** both for 'heptagon' 3D cells and subdivided 3D cells */ struct subcellshape { vector> faces; vector> faces_local; @@ -109,6 +109,17 @@ struct subcellshape { hyperpoint cellcenter; transmatrix to_cellcenter; transmatrix from_cellcenter; + /** \brief for adjacent directions a,b, next_dir[a][b] is the next direction adjacent to a, in (counter?)clockwise order from b */ + vector> next_dir; + + /** compute all the properties based on `faces`, for the main heptagon cellshape */ + void compute_hept(); + + /** compute all the properties based on `faces`, for subcells */ + void compute_sub(); + + /** common part of compute_hept and compute_sub */ + void compute_common(); }; /** basic geometry parameters */ @@ -143,24 +154,18 @@ struct geometry_information { int loop, face, schmid; - vector> cellshape; - vector vertices_only; - transmatrix spins[32], adjmoves[32]; + unique_ptr heptshape; vector subshapes; ld adjcheck; ld strafedist; - vector> dirdist; ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part; vector ultra_mirrors; - /** \brief for adjacent directions a,b, next_dir[a][b] is the next direction adjacent to a, in (counter?)clockwise order from b */ - int next_dir[32][32]; - vector > rels; int xp_order, r_order, rx_order; diff --git a/geometry2.cpp b/geometry2.cpp index 8b324b13..49b3f4e0 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -734,12 +734,6 @@ EX hyperpoint get_warp_corner(cell *c, int cid) { return ddspin(c,cid,M_PI/S7) * xpush0(cgi.tessf/2); } -vector hrmap::get_vertices(cell* c) { - vector res; - for(int i=0; itype; i++) res.push_back(get_corner_position(c, i, 3)); - return res; - } - EX map>> brm_structure; EX void generate_brm(cell *c1) { diff --git a/polygons.cpp b/polygons.cpp index 587ac6f7..1e69d080 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1047,8 +1047,9 @@ void geometry_information::create_wall3d() { } if(euc::in() || reg3::in() || asonov::in()) { - for(int w=0; wfaces; + for(int w=0; wvertices_only))+"; i++) {\n"; fmain += "mat4 uMi = " + getM("i") + ";"; fmain += " mediump float v = ((position - uMi * position)[3] / (uMi * tangent - tangent)[3]);\n" diff --git a/reg3.cpp b/reg3.cpp index 2e0753b4..d296324e 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -13,6 +13,65 @@ namespace hr { #if MAXMDIM >= 4 +void subcellshape::compute_common() { + reg3::make_vertices_only(vertices_only, faces); + + faces_local = faces; + for(auto& face: faces_local) for(auto& v: face) v = from_cellcenter * v; + + vertices_only_local = vertices_only; + for(auto& v: vertices_only_local) v = from_cellcenter * v; + + int N = isize(faces); + + dirdist.resize(N); + for(int i=0; i cface; + for(auto& v: faces[i]) cface.insert(bucketer(v)); + for(int j=0; j 0) next_dir[a][b] = c; + } + } + +void subcellshape::compute_hept() { + cellcenter = C0; + to_cellcenter = Id; + from_cellcenter = Id; + compute_common(); + } + +void subcellshape::compute_sub() { + hyperpoint gres = Hypc; + for(auto& face: faces) { + hyperpoint res = Hypc; + for(auto& vertex: face) + res += vertex; + face_centers.push_back(normalize(res)); + gres += res; + } + cellcenter = normalize(gres); + to_cellcenter = rgpushxto0(cellcenter); + from_cellcenter = gpushxto0(cellcenter); + } + /** \brief regular three-dimensional tessellations */ EX namespace reg3 { @@ -47,14 +106,15 @@ EX namespace reg3 { if(cgflags & qULTRA) { - for(auto& v: cgi.vertices_only) { + for(auto& v: cgi.heptshape->vertices_only) { hyperpoint nei; + auto& faces = cgi.heptshape->faces; - for(int i=0; i(new subcellshape); + int& loop = cgi.loop; int& face = cgi.face; auto& spins = cgi.spins; - auto& cellshape = cgi.cellshape; + auto& cellshape = hsh->faces; auto& adjcheck = cgi.adjcheck; - auto& dirdist = cgi.dirdist; int& mid = cgi.schmid; mid = 3; @@ -255,21 +313,6 @@ EX namespace reg3 { adjcheck = hdist(tC0(cgi.adjmoves[0]), tC0(cgi.adjmoves[1])) * 1.0001; - int numedges = 0; - dirdist.resize(S7); - for(int a=0; afaces[0][0][0]); + auto vz = abs(cgi.heptshape->faces[0][0][3]); for(int x=1-sub; xfaces; for(auto& face: ss.faces) for(auto& v: face) { v[0] += vx * x; v[1] += vx * y; @@ -318,7 +352,7 @@ EX namespace reg3 { EX void generate_coxeter(flagtype f) { auto& ssh = cgi.subshapes; - for(auto& fac: cgi.cellshape) { + for(auto& fac: cgi.heptshape->faces) { hyperpoint facectr = Hypc; vector ring; hyperpoint last = fac.back(); @@ -384,8 +418,8 @@ EX namespace reg3 { if(S7 != 6) throw hr_exception("generate_plain_subcubes but no cubes"); const int sub = subcube_count; if(1) { - auto vx = abs(cgi.cellshape[0][0][0]); - auto vz = abs(cgi.cellshape[0][0][3]); + auto vx = abs(cgi.heptshape->faces[0][0][0]); + auto vz = abs(cgi.heptshape->faces[0][0][3]); auto step = hdist0(tC0(cgi.adjmoves[0])); array co; int s = bch ? 1 : 2; @@ -596,7 +630,7 @@ EX namespace reg3 { case eVariation::pure: { cgi.subshapes.emplace_back(); - cgi.subshapes[0].faces = cgi.cellshape; + cgi.subshapes[0].faces = cgi.heptshape->faces; break; } @@ -604,39 +638,7 @@ EX namespace reg3 { throw hr_exception("unknown variation in generate_subcells"); } - for(auto& ss: cgi.subshapes) { - make_vertices_only(ss.vertices_only, ss.faces); - hyperpoint gres = Hypc; - for(auto& face: ss.faces) { - hyperpoint res = Hypc; - for(auto& vertex: face) - res += vertex; - ss.face_centers.push_back(normalize(res)); - gres += res; - } - ss.cellcenter = normalize(gres); - ss.to_cellcenter = rgpushxto0(ss.cellcenter); - ss.from_cellcenter = gpushxto0(ss.cellcenter); - ss.faces_local = ss.faces; - for(auto& face: ss.faces_local) for(auto& v: face) v = ss.from_cellcenter * v; - ss.vertices_only_local = ss.vertices_only; - for(auto& v: ss.vertices_only_local) v = ss.from_cellcenter * v; - - int N = isize(ss.faces); - ss.dirdist.resize(N); - for(int i=0; i cface; - for(auto& v: ss.faces[i]) cface.insert(bucketer(v)); - for(int j=0; jfaces; + hyperpoint v = faces[0][0]; auto add = [&] (transmatrix T) { for(int i=0; i