diff --git a/archimedean.cpp b/archimedean.cpp index 115a439b..ab3d3247 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -76,10 +76,12 @@ struct archimedean_tiling { string world_size(); void get_nom_denom(int& anom, int& adenom); - geometryinfo1& get_geometry(); + geometryinfo1& get_geometry(ld mul = 1); eGeometryClass get_class() { return get_geometry().kind; } bool get_step_values(int& steps, int& single_step); + + transmatrix adjcell_matrix(heptagon *h, int d); ld scale(); }; @@ -96,6 +98,12 @@ static const int sfSEMILINE = 16; #endif EX archimedean_tiling current; +EX archimedean_tiling fake_current; + +EX archimedean_tiling& current_or_fake() { + if(fake::in()) return fake_current; + return current; + } /** id of vertex in the archimedean tiling * odd numbers = reflected tiles @@ -354,9 +362,9 @@ void archimedean_tiling::regroup() { } } -geometryinfo1& archimedean_tiling::get_geometry() { - if(euclidean_angle_sum < 1.999999) return ginf[gSphere].g; - else if(euclidean_angle_sum > 2.000001) return ginf[gNormal].g; +geometryinfo1& archimedean_tiling::get_geometry(ld mul) { + if(euclidean_angle_sum * mul < 1.999999) return ginf[gSphere].g; + else if(euclidean_angle_sum * mul > 2.000001) return ginf[gNormal].g; else return ginf[gEuclid].g; } @@ -366,6 +374,8 @@ void archimedean_tiling::compute_geometry() { DEBB(DF_GEOM, (format("euclidean_angle_sum = %f\n", float(euclidean_angle_sum)))); + bool infake = fake::in(); + dynamicval dv(geometry, gArchimedean); /* compute the geometry */ @@ -374,6 +384,15 @@ void archimedean_tiling::compute_geometry() { alphas.resize(N); ld elmin = 0, elmax = hyperbolic ? 10 : sphere ? M_PI : 1; + ld total = M_PI; + + dynamicval dgi(ginf[geometry].g, ginf[geometry].g); + + if(infake) { + total *= N / fake::around; + ginf[geometry].g = get_geometry(fake::around / N); + } + /* inradius[N] is used in farcorner and nearcorner. Probably a bug */ if(real_faces == 2) { @@ -422,7 +441,7 @@ void archimedean_tiling::compute_geometry() { println(hlog, "edgelength = ", edgelength, " angles = ", alphas, " inradius = ", inradius, " circumradius = ", circumradius); if(isnan(alpha_total)) elmax = edgelength; - else if(sphere ^ (alpha_total > M_PI)) elmin = edgelength; + else if(sphere ^ (alpha_total > total)) elmin = edgelength; else elmax = edgelength; if(euclid) break; } @@ -474,7 +493,13 @@ bool skip_digons(heptspin hs, int step); void connect_digons_too(heptspin h1, heptspin h2); void fixup_matrix(transmatrix& T, const transmatrix& X, ld step); void connectHeptagons(heptspin hi, heptspin hs); -transmatrix adjcell_matrix(heptagon *h, int d); + +/** @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 + */ struct hrmap_archimedean : hrmap { map eucdata; @@ -573,7 +598,9 @@ struct hrmap_archimedean : hrmap { heptagon *create_step(heptagon *h, int d) override { DEBB(DF_GEOM, (format("%p.%d ~ ?\n", hr::voidp(h), d))); - + + dynamicval gi(ginf[geometry].g, ginf[gArchimedean].g); + heptspin hi(h, d); while(skip_digons(hi, 1)) hi++; @@ -668,7 +695,7 @@ struct hrmap_archimedean : hrmap { if(DUAL && (i&1)) continue; h->cmove(i); if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue; - transmatrix V1 = V * adjcell_matrix(h, i); + transmatrix V1 = V * current.adjcell_matrix(h, i); bandfixer bf(V1); dq::enqueue(h->move(i), V1); } @@ -680,21 +707,22 @@ struct hrmap_archimedean : hrmap { } transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override { - if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7)) + if(use_gmatrix && gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7)) return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7]; transmatrix gm = Id, where = Id; + auto& cof = current_or_fake(); while(h1 != h2) { for(int i=0; imove(i) == h2) { - return gm * adjcell_matrix(h1, i) * where; + return gm * cof.adjcell_matrix(h1, i) * where; } } if(h1->distance > h2->distance) { - gm = gm * adjcell_matrix(h1, 0); + gm = gm * cof.adjcell_matrix(h1, 0); h1 = h1->move(0); } else { - where = inverse(adjcell_matrix(h2, 0)) * where; + where = inverse(cof.adjcell_matrix(h2, 0)) * where; h2 = h2->move(0); } } @@ -702,16 +730,17 @@ struct hrmap_archimedean : hrmap { } ld spin_angle(cell *c, int d) override { + auto &cof = current_or_fake(); if(PURE) { - auto& t1 = arcm::current.get_triangle(c->master, d-1); + auto& t1 = cof.get_triangle(c->master, d-1); return -(t1.first + M_PI / c->type); } else if(DUAL) { - auto& t1 = arcm::current.get_triangle(c->master, 2*d); + auto& t1 = cof.get_triangle(c->master, 2*d); return -t1.first; } else { /* BITRUNCATED */ - auto& t1 = arcm::current.get_triangle(c->master, d); + auto& t1 = cof.get_triangle(c->master, d); return -t1.first; } } @@ -826,13 +855,13 @@ pair& archimedean_tiling::get_triangle(const pair& p, int delt return triangles[p.first][gmod(p.second + delta, isize(adjacent[p.first]))]; } -transmatrix adjcell_matrix(heptagon *h, int d) { - auto& t1 = current.get_triangle(h, d); +transmatrix archimedean_tiling::adjcell_matrix(heptagon *h, int d) { + auto& t1 = get_triangle(h, d); heptagon *h2 = h->move(d); int d2 = h->c.spin(d); - auto& t2 = current.get_triangle(h2, d2); + auto& t2 = get_triangle(h2, d2); return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first); } diff --git a/cell.cpp b/cell.cpp index 4bf4dcbc..08313799 100644 --- a/cell.cpp +++ b/cell.cpp @@ -917,6 +917,7 @@ EX cdata *arcmCdata(cell *c) { } EX int getCdata(cell *c, int j) { + if(fake::in()) return FPIU(getCdata(c, j)); if(hybri) { c = hybrid::get_where(c).first; return PIU(getBits(c)); } else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->val[j]; else if(arcm::in() && euclid) @@ -935,6 +936,7 @@ EX int getCdata(cell *c, int j) { } EX int getBits(cell *c) { + if(fake::in()) return FPIU(getBits(c)); if(hybri) { c = hybrid::get_where(c).first; return PIU(getBits(c)); } else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->bits; else if(arcm::in() && euclid) diff --git a/fake.cpp b/fake.cpp index 649c3305..3c79021c 100644 --- a/fake.cpp +++ b/fake.cpp @@ -54,7 +54,11 @@ EX namespace fake { for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL; } - ~hrmap_fake() { delete underlying_map; } + ~hrmap_fake() { + in_underlying([this] { + delete underlying_map; + }); + } heptagon *create_step(heptagon *parent, int d) override { parent->c.connect(d, parent, d, false); @@ -65,6 +69,7 @@ EX namespace fake { transmatrix S1, S2; ld dist; in_underlying([c, d, &S1, &S2, &dist] { + dynamicval u(arcm::use_gmatrix, false); transmatrix T = currentmap->adj(c, d); S1 = rspintox(tC0(T)); transmatrix T1 = spintox(tC0(T)) * T; @@ -72,7 +77,14 @@ EX namespace fake { S2 = xpush(-dist) * T1; }); - if(WDIM == 2) { + if(arcm::in()) { + int t = arcm::id_of(c->master); + int t2 = arcm::id_of(c->move(d)->master); + auto& cof = arcm::current_or_fake(); + cgi.adjcheck = cof.inradius[t/2] + cof.inradius[t2/2]; + } + + else if(WDIM == 2) { ld dist; in_underlying([c, d, &dist] { @@ -139,6 +151,7 @@ EX namespace fake { } transmatrix relative_matrix(cell *h2, cell *h1, const hyperpoint& hint) override { + if(arcm::in()) return underlying_map->relative_matrix(h2, h1, hint); if(h1 == h2) return Id; for(int a=0; atype; a++) if(h1->move(a) == h2) @@ -148,6 +161,7 @@ EX namespace fake { } transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override { + if(arcm::in()) return underlying_map->relative_matrix(h2, h1, hint); return relative_matrix(h2->c7, h1->c7, hint); } @@ -191,6 +205,10 @@ EX namespace fake { } } } + + ld spin_angle(cell *c, int d) override { + return underlying_map->spin_angle(c,d); + } }; EX hrmap* new_map() { return new hrmap_fake; } @@ -295,6 +313,7 @@ EX ld around; /** @brief the value of 'around' which makes the tiling Euclidean */ EX ld compute_euclidean() { + if(arcm::in()) return arcm::current.N * 2 / arcm::current.euclidean_angle_sum; if(WDIM == 2) return 4 / (S7-2.) + 2; int middle = get_middle(); @@ -302,6 +321,15 @@ EX ld compute_euclidean() { return M_PI / asin(cos(M_PI/middle) / sin(M_PI/underlying_cgip->face)); } +EX int around_orig() { + if(arcm::in()) + return arcm::current.N; + if(WDIM == 2) + return S3; + return + underlying_cgip->loop; + } + EX void compute_scale() { ld good = compute_euclidean(); @@ -310,7 +338,7 @@ EX void compute_scale() { if(abs(good - around) < 1e-6) good = around; - int s3 = WDIM == 2 ? S3 : underlying_cgip->loop; + int s3 = around_orig(); multiple = false; int mcount = int(around / s3 + .5); @@ -381,6 +409,7 @@ void set_gfake(ld _around) { compute_scale(); check_cgi(); + cgi.require_basics(); ginf[gFake].xcode = no_code; @@ -397,7 +426,7 @@ EX void change_around() { ld range = sightranges[geometry]; if(!fake::in()) { - if(around == (WDIM == 2 ? S3 : cgi.loop)) return; /* do nothing */ + if(around == around_orig()) return; /* do nothing */ set_gfake(around); } diff --git a/geometry.cpp b/geometry.cpp index 4dece42e..574ab944 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -511,7 +511,7 @@ void geometry_information::prepare_basics() { } s3 = S3; - if(fake::in()) s3 = fake::around; + if(fake::in() && !arcm::in()) s3 = fake::around; beta = (S3 >= OINF && !fake::in()) ? 0 : 2*M_PI/s3; @@ -589,10 +589,12 @@ void geometry_information::prepare_basics() { #endif #if CAP_ARCM if(arcm::in()) { - arcm::current.compute_geometry(); - crossf = hcrossf7 * arcm::current.scale(); - hexvdist = arcm::current.scale() * .5; - rhexf = arcm::current.scale() * .5; + auto& ac = arcm::current_or_fake(); + if(fake::in()) ac = arcm::current; + ac.compute_geometry(); + crossf = hcrossf7 * ac.scale(); + hexvdist = ac.scale() * .5; + rhexf = ac.scale() * .5; } #endif #if CAP_BT diff --git a/geometry2.cpp b/geometry2.cpp index 0530d5fe..20efef4b 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -512,7 +512,7 @@ EX hyperpoint get_corner_position(cell *c, int cid, ld cf IS(3)) { #endif #if CAP_ARCM if(arcm::in()) { - auto &ac = arcm::current; + auto &ac = arcm::current_or_fake(); if(PURE) { if(arcm::id_of(c->master) >= ac.N*2) return C0; auto& t = ac.get_triangle(c->master, cid-1); diff --git a/hypgraph.cpp b/hypgraph.cpp index e5dff1f9..7688debc 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -997,7 +997,7 @@ EX ld spherity(const transmatrix& V) { } EX bool confusingGeometry() { - return quotient || elliptic || reg3::ultra_mirror_in(); + return quotient || elliptic || reg3::ultra_mirror_in() || (fake::in() && fake::multiple); } EX ld master_to_c7_angle() { diff --git a/polygons.cpp b/polygons.cpp index 0abf682a..09b3117a 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1083,7 +1083,7 @@ void geometry_information::configure_floorshapes() { if(0); #if CAP_ARCM else if(arcm::in()) - shFullFloor.configure(arcm::current.scale()/2, arcm::current.scale()/2); + shFullFloor.configure(arcm::current_or_fake().scale()/2, arcm::current_or_fake().scale()/2); #endif else shFullFloor.configure(hexvdist, rhexf);