diff --git a/classes.cpp b/classes.cpp index f7b9197b..8e40c091 100644 --- a/classes.cpp +++ b/classes.cpp @@ -722,7 +722,8 @@ enum eGeometry { gBinary4, gSol, gKiteDart2, gKiteDart3, gNil, gProduct, gRotSpace, gTernary, gNIH, gSolN, gInfOrder, gSpace336, gSpace344, gCrystal344, - gArnoldCat, gArbitrary, gInfOrder4, + gArnoldCat, gArbitrary, gInfOrder4, gCrystal534, + gSpace535, gSpace536, gGUARD}; enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSolNIH, gcNil, gcProduct, gcSL2 }; @@ -888,6 +889,9 @@ EX vector ginf = { {"cat", "cat", "Arnold's cat mapping torus", "cat", 12, 3, qBINARY | qSOL | qsBQ | qOPTQ, giSolNIH, 0x52200, {{6, 4}}, eVariation::pure}, {"file", "none", "load from file", "file", 7, 3, qEXPERIMENTAL, giEuclid2, 0, {{7, 5}}, eVariation::pure}, {"{4,oo}", "none", "{4,∞} (infinite squares)", "oox4", 4, OINF, qIDEAL, giHyperb2, 0x49400, {{5, 5}}, eVariation::pure}, + {"{5,3,4}","Crystal", "6D crystal in H3", "Cryst6" , 12, 4, qANYQ | qCRYSTAL, giHyperb3, 0x52000, {{7, 3}}, eVariation::pure}, + {"{5,3,5}","none", "{5,3,5} hyperbolic honeycomb", "535", 12, 5, 0, giHyperb3, 0x31400, {{7, 2}}, eVariation::pure}, + {"{5,3,6}","none", "{5,3,6} hyperbolic honeycomb", "536", 12, 6, qIDEAL, giHyperb3, 0x31400, {{7, 2}}, eVariation::pure}, }; // bits: 9, 10, 15, 16, (reserved for later) 17, 18 diff --git a/crystal.cpp b/crystal.cpp index 113dc8fe..35193c42 100644 --- a/crystal.cpp +++ b/crystal.cpp @@ -361,20 +361,99 @@ int fiftyrule(coord c) { bool is_bi(crystal_structure& cs, coord co); #if MAXMDIM >= 4 -typedef array shifttable; +typedef array shifttable; + +array ctable[64] = { + {0, 1, 2, 3, 4, 5, }, + {6, 1, 5, 4, 3, 2, }, + {0, 7, 5, 4, 3, 2, }, + {6, 7, 2, 3, 4, 5, }, + {0, 1, 5, 4, 3, 8, }, + {6, 1, 8, 3, 4, 5, }, + {0, 7, 8, 3, 4, 5, }, + {6, 7, 5, 4, 3, 8, }, + {0, 1, 5, 4, 9, 2, }, + {6, 1, 2, 9, 4, 5, }, + {0, 7, 2, 9, 4, 5, }, + {6, 7, 5, 4, 9, 2, }, + {0, 1, 8, 9, 4, 5, }, + {6, 1, 5, 4, 9, 8, }, + {0, 7, 5, 4, 9, 8, }, + {6, 7, 8, 9, 4, 5, }, + {0, 1, 5, 10, 3, 2, }, + {6, 1, 2, 3, 10, 5, }, + {0, 7, 2, 3, 10, 5, }, + {6, 7, 5, 10, 3, 2, }, + {0, 1, 8, 3, 10, 5, }, + {6, 1, 5, 10, 3, 8, }, + {0, 7, 5, 10, 3, 8, }, + {6, 7, 8, 3, 10, 5, }, + {0, 1, 2, 9, 10, 5, }, + {6, 1, 5, 10, 9, 2, }, + {0, 7, 5, 10, 9, 2, }, + {6, 7, 2, 9, 10, 5, }, + {0, 1, 5, 10, 9, 8, }, + {6, 1, 8, 9, 10, 5, }, + {0, 7, 8, 9, 10, 5, }, + {6, 7, 5, 10, 9, 8, }, + {0, 1, 11, 4, 3, 2, }, + {6, 1, 2, 3, 4, 11, }, + {0, 7, 2, 3, 4, 11, }, + {6, 7, 11, 4, 3, 2, }, + {0, 1, 8, 3, 4, 11, }, + {6, 1, 11, 4, 3, 8, }, + {0, 7, 11, 4, 3, 8, }, + {6, 7, 8, 3, 4, 11, }, + {0, 1, 2, 9, 4, 11, }, + {6, 1, 11, 4, 9, 2, }, + {0, 7, 11, 4, 9, 2, }, + {6, 7, 2, 9, 4, 11, }, + {0, 1, 11, 4, 9, 8, }, + {6, 1, 8, 9, 4, 11, }, + {0, 7, 8, 9, 4, 11, }, + {6, 7, 11, 4, 9, 8, }, + {0, 1, 2, 3, 10, 11, }, + {6, 1, 11, 10, 3, 2, }, + {0, 7, 11, 10, 3, 2, }, + {6, 7, 2, 3, 10, 11, }, + {0, 1, 11, 10, 3, 8, }, + {6, 1, 8, 3, 10, 11, }, + {0, 7, 8, 3, 10, 11, }, + {6, 7, 11, 10, 3, 8, }, + {0, 1, 11, 10, 9, 2, }, + {6, 1, 2, 9, 10, 11, }, + {0, 7, 2, 9, 10, 11, }, + {6, 7, 11, 10, 9, 2, }, + {0, 1, 8, 9, 10, 11, }, + {6, 1, 11, 10, 9, 8, }, + {0, 7, 11, 10, 9, 8, }, + {6, 7, 8, 9, 10, 11, }, + }; shifttable get_canonical(coord co) { shifttable res; - for(int i=0; i<4; i++) { - res[i] = c0; - res[i][i] = 2; - res[i+4] = c0; - res[i+4][i] = -2; + if(S7 == 12) { + int eid = 0; + for(int a=0; a<6; a++) if(co[a] & 2) eid += (1<=6) ? -2 : 2; + res[6+i][c % 6] = (c>=6) ? 2 : -2; + } + } + else { + for(int i=0; i<4; i++) { + res[i] = c0; + res[i][i] = 2; + res[i+4] = c0; + res[i+4][i] = -2; + } + for(int a=0; a<4; a++) if(co[a] & 2) swap(res[a], res[a+4]); + int bts = 0; + for(int a=0; a<4; a++) if(co[a] & 2) bts++; + if(bts & 1) swap(res[2], res[3]), swap(res[6], res[7]); } - for(int a=0; a<4; a++) if(co[a] & 2) swap(res[a], res[a+4]); - int bts = 0; - for(int a=0; a<4; a++) if(co[a] & 2) bts++; - if(bts & 1) swap(res[2], res[3]), swap(res[6], res[7]); return res; } #endif @@ -407,7 +486,7 @@ struct hrmap_crystal : hrmap_standard { hrmap_crystal() { #if MAXMDIM >= 4 - if(crystal3()) reg3::generate(), cs.dim = 4; else + if(crystal3()) reg3::generate(), cs.dim = S7 / 2; else #endif cs.build(); @@ -483,9 +562,9 @@ struct hrmap_crystal : hrmap_standard { auto h1 = get_heptagon_at(co1, S7); auto st1 = get_canonical(co1); - for(int d1=0; d1<8; d1++) if(st1[d1] == st[d]) - h->c.connect(d, h1, d1 ^ 4, false); - + for(int d1=0; d1c.connect(d, h1, (d1+S7/2) % S7, false); + return h1; } #endif @@ -526,8 +605,8 @@ struct hrmap_crystal : hrmap_standard { transmatrix adj(heptagon *h, int d) override { auto co = hcoords[h]; int id = 0; - for(int a=0; a<4; a++) id = (2*id) + ((co[a]>>1) & 1); - id = 8*id + d; + for(int a=0; a>1) & 1); + id = S7*id + d; if(adjs.count(id)) return adjs[id]; transmatrix T = reg3::adjmoves[d]; reg3::generate_cellrotations(); @@ -536,13 +615,20 @@ struct hrmap_crystal : hrmap_standard { auto st1 = get_canonical(co1); int qty = 0; transmatrix res; + ld gdist = S7 == 12 ? hdist0(tC0(reg3::adjmoves[0])) : reg3::strafedist; + for(auto& cr: cgi.cellrotations) { + transmatrix U = T * cr.first; - for(int s=0; s<8; s++) + + ld go = hdist0(U * tC0(reg3::adjmoves[h->c.spin(d)])); + if(go > 1e-2) continue; + + for(int s=0; s reg3::strafedist + .1) + if(hdist(U * tC0(reg3::adjmoves[t]), tC0(reg3::adjmoves[s])) > gdist + .1) goto wrong; } res = U; diff --git a/pattern2.cpp b/pattern2.cpp index 9529aebc..7e7f2b3f 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -394,6 +394,7 @@ EX int fieldval_uniq(cell *c) { } else if(bt::in() || arcm::in() || nil || S3 >= OINF || (cgflags & qIDEAL)) return 0; else if(&currfp == &fp_invalid) return 0; + else if(geometry == gSpace535) return 0; else if(WDIM == 3) return c->master->fieldval; else if(ctof(c) || NONSTDVAR) return c->master->fieldval/S7; else { diff --git a/reg3.cpp b/reg3.cpp index 99fd222c..055f8c42 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -636,7 +636,7 @@ EX namespace reg3 { quotient_map = new hrmap_from_crystal; h.zebraval = quotient_map->allh[0]->zebraval; } - if(hyperbolic && !(cgflags & qIDEAL)) { + if(hyperbolic && !(cgflags & qIDEAL) && geometry != gSpace535) { quotient_map = new hrmap_field3; h.zebraval = quotient_map->allh[0]->zebraval; } @@ -945,7 +945,7 @@ EX bool pseudohept(cell *c) { return c->master->distance & 1; if(geometry == gField534) return hr::celldistance(c, currentmap->gamestart()) & 1; - if(geometry == gCrystal344) + if(geometry == gCrystal344 || geometry == gCrystal534) return false; if(hyperbolic) { heptagon *h = m->reg_gmatrix[c->master].first;