diff --git a/arbitrile.cpp b/arbitrile.cpp index 614cf43b..bb00956c 100644 --- a/arbitrile.cpp +++ b/arbitrile.cpp @@ -1396,11 +1396,7 @@ geometryinfo1& arbi_tiling::get_geometry() { return ginf[gEuclid].g; } -map > > altmap; - -EX map> arbi_matrix; - -EX hrmap *current_altmap; +EX backed_map bm; heptagon *build_child(heptspin p, pair adj); @@ -1539,30 +1535,12 @@ struct hrmap_arbi : hrmap { origin->s = hsOrigin; origin->c7 = newCell(origin->type, origin); - heptagon *alt = NULL; - - if(mhyperbolic) { - dynamicval g(geometry, gNormal); - alt = init_heptagon(S7); - alt->s = hsOrigin; - alt->alt = alt; - current_altmap = newAltMap(alt); - } - - transmatrix T = lxpush(.01241) * spin(1.4117) * lxpush(0.1241) * Id; - arbi_matrix[origin] = make_pair(alt, T); - altmap[alt].emplace_back(origin, T); + bm.initialize(origin); } ~hrmap_arbi() { clearfrom(origin); - altmap.clear(); - arbi_matrix.clear(); - if(current_altmap) { - dynamicval g(geometry, gNormal); - delete current_altmap; - current_altmap = NULL; - } + bm.clear(); } void verify() override { } @@ -1619,34 +1597,24 @@ struct hrmap_arbi : hrmap { return h1; } - const auto& p = arbi_matrix[h]; + const auto& p = bm.where[h]; heptagon *alt = p.first; transmatrix T = p.second * adj(h, d); - if(mhyperbolic) { - dynamicval g(geometry, gNormal); - dynamicval cm(currentmap, current_altmap); - // transmatrix U = T; - current_altmap->virtualRebase(alt, T); - // U = U * inverse(T); - } + transmatrix U; + bm.rebase(alt, T, U); fixmatrix(T); - if(meuclid) { - /* hash the rough coordinates as heptagon* alt */ - size_t s = size_t(T[0][LDIM]+.261) * 124101 + size_t(T[1][LDIM]+.261) * 82143; - alt = (heptagon*) s; - } - - for(auto& p2: altmap[alt]) if(id_of(p2.first) == co.sid) { + for(auto& p2: bm.what_at[alt]) if(id_of(p2.first) == co.sid) { connection_t co1 = co; if(find_connection(T, p2.second, co1)) { if(p2.first->move(co1.eid)) { throw hr_exception("already connected!"); } h->c.connect(d, p2.first, co1.eid, co1.mirror); + bm.handle_precision_errors(p2.first); return p2.first; } } @@ -1658,8 +1626,7 @@ struct hrmap_arbi : hrmap { h1->emeraldval = h->emeraldval ^ co.mirror; h->c.connect(d, h1, co.eid, co.mirror); - arbi_matrix[h1] = make_pair(alt, T); - altmap[alt].emplace_back(h1, T); + bm.assign(h1, alt, T); return h1; } @@ -2262,11 +2229,7 @@ EX void swap_vertices() { } #if MAXMDIM >= 4 -auto hooksw = addHook(hooks_swapdim, 100, [] { - swap_vertices(); - for(auto& p: altmap) for(auto& pp: p.second) swapmatrix(pp.second); - for(auto& p: arbi_matrix) swapmatrix(p.second.second); - }); +auto hooksw = addHook(hooks_swapdim, 100, [] { swap_vertices(); bm.swapdim(); }); #endif EX bool support_dice(int x) { diff --git a/archimedean.cpp b/archimedean.cpp index f8c03274..f4f403b3 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -560,11 +560,7 @@ ld archimedean_tiling::scale() { return edgelength; } -map > > altmap; - -EX map> archimedean_gmatrix; - -EX hrmap *current_altmap; +EX backed_map bm; heptagon *build_child(heptspin p, pair adj); @@ -576,20 +572,6 @@ void connectHeptagons(heptspin hi, heptspin hs); /** @brief should we use gmatrix to compute relative_matrix faster? (not while in fake Archimedean) */ EX bool use_gmatrix = true; -/** @brief like adj, but in pure - * not used by arcm itself, but used in fake arcm - */ - -EX geometry_information *alt_cgip[2]; - -EX geometry_information *find_alt_cgip() { - auto& galt_cgip = alt_cgip[embedded_plane]; - if(galt_cgip) return galt_cgip; - check_cgi(); - cgi.require_basics(); - return galt_cgip = cgip; - } - struct hrmap_archimedean : hrmap { map eucdata; heptagon *origin; @@ -605,30 +587,8 @@ struct hrmap_archimedean : hrmap { parent_index_of(origin) = DUAL ? 1 : 0; id_of(origin) = id; origin->c7 = newCell(N0/DUALMUL, origin); - - heptagon *alt = NULL; - - if(hyperbolic) { - bool f = geom3::flipped; - if(f) geom3::light_flip(false); - if(1) { - dynamicval g(geometry, gNormal); - dynamicval gv(variation, eVariation::pure); - dynamicval gi(cgip, find_alt_cgip()); - alt = init_heptagon(S7); - alt->s = hsOrigin; - alt->alt = alt; - current_altmap = newAltMap(alt); - } - if(f) geom3::light_flip(true); - } - bool f = geom3::flipped; - if(f) geom3::light_flip(false); - transmatrix T = lxpush(.01241) * spin(1.4117) * lxpush(0.1241) * Id; - if(f) geom3::light_flip(true); - archimedean_gmatrix[origin] = make_pair(alt, T); - altmap[alt].emplace_back(origin, T); + bm.initialize(origin); if(current.real_faces == 0 && DUAL) { heptspin hs(origin, 0); @@ -646,7 +606,7 @@ struct hrmap_archimedean : hrmap { for(int s=2; s<2*current.N; s+=2) { heptspin hs(o0, s); heptagon *hnew = build_child(hs, current.get_adj(hs)); - // no need to specify archimedean_gmatrix and altmap + // no need to specify where and what_at hnew->c.connect(1, heptspin(o1, 2*current.N-s)); } o1->c.connect(1, o0, 2*current.N-1, false); @@ -663,16 +623,9 @@ struct hrmap_archimedean : hrmap { ~hrmap_archimedean() { clearfrom(origin); - altmap.clear(); - archimedean_gmatrix.clear(); - if(current_altmap) { - dynamicval g(geometry, gNormal); - dynamicval gv(variation, eVariation::pure); - dynamicval gi(cgip, find_alt_cgip()); - delete current_altmap; - current_altmap = NULL; - } + bm.clear(); } + void verify() override { } heptagon *create_step(heptagon *h, int d) override { @@ -702,33 +655,18 @@ struct hrmap_archimedean : hrmap { // * spin(-tri[id][pi+i].first) * lxpush(t.second) * pispin * spin(tri[id'][p'+d'].first) - auto& p1 = archimedean_gmatrix[h]; - - heptagon *alt = p1.first; - + auto& p1 = bm.where[h]; + + heptagon *alt = p1.first; auto alt0 = alt; + transmatrix T = p1.second * spin(-t1.first) * lxpush(t1.second); transmatrix U = Id; - if(hyperbolic) { - dynamicval uc(cgip->use_count, cgip->use_count+1); - dynamicval g(geometry, gNormal); - dynamicval gv(variation, eVariation::pure); - dynamicval gi(cgip, find_alt_cgip()); - dynamicval cm(currentmap, current_altmap); - U = T; - current_altmap->virtualRebase(alt, T); - U = U * iso_inverse(T); - } - - if(euclid) { - /* hash the rough coordinates as heptagon* alt */ - size_t s = size_t(T[0][LDIM]+.261) * 124101 + size_t(T[1][LDIM]+.261) * 82143; - alt = (heptagon*) s; - } - + bm.rebase(alt, T, U); + if(debug_geometry) println(hlog, "look for: ", alt, " / ", kz(T * C0)); - - for(auto& p2: altmap[alt]) if(same_point_may_warn(p2.second * tile_center(), T * tile_center())) { + + for(auto& p2: bm.what_at[alt]) if(same_point_may_warn(p2.second * tile_center(), T * tile_center())) { if(debug_geometry) println(hlog, "cell found: ", p2.first); for(int d2=0; d2degree(); d2++) { heptspin hs(p2.first, d2); @@ -742,14 +680,17 @@ struct hrmap_archimedean : hrmap { // p1.second * spinm(-t1.first) * lxpush(t1.second) * spin(pi+t2.first) == p2.second // bring p1 and p2 closer, to prevent floating point errors - if(hyperbolic) { + if(hyperbolic && false) { fixup_matrix(p1.second, U * p2.second * spin(-M_PI - t2.first) * lxpush(-t1.second) * spin(t1.first), 0.25); fixup_matrix(p2.second, T1, 0.25); + for(auto& z: bm.what_at[alt0]) if(z.first == h) z.second = p1.second; + bm.where[p2.first].second = p2.second; } while(skip_digons(hs, -1)) hs--; connectHeptagons(hi, hs); connect_digons_too(hi, hs); + bm.handle_precision_errors(h); return h->move(d); } } @@ -761,8 +702,7 @@ struct hrmap_archimedean : hrmap { fixmatrix(T1); heptagon *hnew = build_child(hi, current.get_adj(hi)); - altmap[alt].emplace_back(hnew, T1); - archimedean_gmatrix[hnew] = make_pair(alt, T1); + bm.assign(hnew, alt, T1); connect_digons_too(hi, heptspin(hnew, 0)); return hnew; @@ -797,7 +737,13 @@ struct hrmap_archimedean : hrmap { } } + transmatrix adj(heptagon *h, int dir) override { + return current_or_fake().adjcell_matrix(h, dir); + } + transmatrix adj(cell *c, int dir) override { + if(!PURE) for(int i=0; imaster->type; i++) if(c->master->move(i) == c->cmove(dir)->master) + return adj(c->master, i); return calc_relative_matrix(c->cmove(dir), c, C0); } @@ -925,7 +871,7 @@ heptagon *build_child(heptspin p, pair adj) { } else h->fieldval = -100; - h->fiftyval = isize(archimedean_gmatrix); + h->fiftyval = isize(bm.where); if(p.at->s == hsOrigin) h->rval1 = 1 + (p.spin % 2); else { @@ -949,7 +895,7 @@ void connect_digons_too(heptspin h1, heptspin h2) { if(skip_digons(h1, -1)) { h1--, h2++; heptagon *hnew = build_child(h1, current.get_adj(h1)); - // no need to specify archimedean_gmatrix and altmap + // no need to specify where and what_at hnew->c.connect(1, h2); h1--, h2++; if(debug_archimedean_map) println(hlog, hr::format("OL2 %p.%d ~ %p.%d\n", hr::voidp(h1.at), h1.spin, hr::voidp(h2.at), h2.spin)); @@ -1131,7 +1077,7 @@ int readArgs() { #if CAP_COMMANDLINE auto hook = addHook(hooks_args, 100, readArgs) -+ addHook(hooks_gamedata, 0, [] (gamedata* gd) { gd->store(altmap); gd->store(archimedean_gmatrix); gd->store(current_altmap); }); ++ addHook(hooks_gamedata, 0, [] (gamedata* gd) { bm.store(gd); }); #endif @@ -1139,20 +1085,7 @@ auto hook = auto hooksw = addHook(hooks_swapdim, 100, [] { if(!arcm::in()) return; - - dynamicval g(geometry, gNormal); - dynamicval gv(variation, eVariation::pure); - - alt_cgip[0] = nullptr; - alt_cgip[1] = nullptr; - - dynamicval gi(cgip, find_alt_cgip()); - - for(auto& p: altmap) for(auto& pp: p.second) swapmatrix(pp.second); - for(auto& p: archimedean_gmatrix) swapmatrix(p.second.second); - - alt_cgip[0] = nullptr; - alt_cgip[1] = nullptr; + bm.swapdim(); }); #endif diff --git a/cell.cpp b/cell.cpp index 2ed87a29..6158e94a 100644 --- a/cell.cpp +++ b/cell.cpp @@ -1273,12 +1273,12 @@ int ld_to_int(ld x) { #if CAP_ARCM EX gp::loc pseudocoords(cell *c) { - transmatrix T = arcm::archimedean_gmatrix[c->master].second; + transmatrix T = arcm::bm.where[c->master].second; return {ld_to_int(T[0][LDIM]), ld_to_int((spin(60._deg) * T)[0][LDIM])}; } EX cdata *arcmCdata(cell *c) { - auto &agm = arcm::archimedean_gmatrix; + auto &agm = arcm::bm.where; if(!agm.count(c->master) || !agm[c->master].first) { forCellEx(c1, c) if(agm.count(c->master) && agm[c->master].first) return arcmCdata(c1); static cdata dummy; @@ -1286,7 +1286,7 @@ EX cdata *arcmCdata(cell *c) { } heptagon *h2 = agm[c->master].first; dynamicval g(geometry, gNormal); - dynamicval cm(currentmap, arcm::current_altmap); + dynamicval cm(currentmap, arcm::bm.current_altmap); return getHeptagonCdata(h2); } #endif diff --git a/geometry.cpp b/geometry.cpp index d4d69646..c2c21bac 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1474,8 +1474,8 @@ EX void check_cgi() { if(mhybrid) hybrid::underlying_cgip->timestamp = ntimestamp; if(fake::in() || (mhybrid && PIU(fake::in()))) fake::underlying_cgip->timestamp = ntimestamp; #if CAP_ARCM - if(arcm::alt_cgip[0]) arcm::alt_cgip[0]->timestamp = ntimestamp; - if(arcm::alt_cgip[1]) arcm::alt_cgip[1]->timestamp = ntimestamp; + if(arcm::bm.alt_cgip[0]) arcm::bm.alt_cgip[0]->timestamp = ntimestamp; + if(arcm::bm.alt_cgip[1]) arcm::bm.alt_cgip[1]->timestamp = ntimestamp; #endif int limit = 3; diff --git a/hyper.cpp b/hyper.cpp index a9c080da..ce55affb 100644 --- a/hyper.cpp +++ b/hyper.cpp @@ -38,6 +38,7 @@ #include "asonov.cpp" #include "kite.cpp" #include "aperiodic-hat.cpp" +#include "backed-map.cpp" #include "archimedean.cpp" #include "arbitrile.cpp" #include "rulegen.cpp"