diff --git a/fieldpattern.cpp b/fieldpattern.cpp index 98431e4f..ecf47fa7 100644 --- a/fieldpattern.cpp +++ b/fieldpattern.cpp @@ -23,6 +23,7 @@ struct primeinfo { struct fgeomextra { eGeometry base; vector primes; + vector dualval; int current_prime_id; fgeomextra(eGeometry b, int i) : base(b), current_prime_id(i) {} }; @@ -69,7 +70,7 @@ EX int btspin(int id, int d) { #if HDR struct fpattern { - int Prime, wsquare, Field; + int Prime, wsquare, Field, dual; // we perform our computations in the field Z_Prime[w] where w^2 equals wsquare // (or simply Z_Prime for wsquare == 0) @@ -278,6 +279,8 @@ struct fpattern { void findsubpath(); + vector generate_isometries(); + bool check_order(matrix M, int req); }; #endif @@ -291,6 +294,35 @@ bool fpattern::check_order(matrix M, int req) { return P == Id; } +vector fpattern::generate_isometries() { + matrix T = Id; + int low = wsquare ? 1-Prime : 0; + vector res; + + auto colprod = [&] (int a, int b) { + return add(add(mul(T[0][a], T[0][b]), mul(T[1][a], T[1][b])), mul(T[2][a], T[2][b])); + }; + + for(T[0][0]=low; T[0][0]3) break; Field = pw==1? Prime : Prime*Prime; @@ -314,6 +347,20 @@ int fpattern::solve() { } } else wsquare = 0; + if(dual == 2) { + if(Field <= 10) { + vector all_isometries = generate_isometries(); + for(auto& X: all_isometries) + if(check_order(X, rotations)) + for(auto& Y: all_isometries) + if(check_order(Y, 2) && check_order(mmul(X, Y), S3)) { + R = X; P = Y; + return 0; + } + } + continue; + } + #ifdef EASY std::vector sqrts(Prime, 0); for(int k=1-Prime; k fgeomextras = { - fgeomextra(gNormal, 3), + fgeomextra(gNormal, 4), fgeomextra(gOctagon, 1), - fgeomextra(g45, 0), - fgeomextra(g46, 3), - fgeomextra(g47, 0), + fgeomextra(g45, 1), + fgeomextra(g46, 5), + fgeomextra(g47, 1), /* fgeomextra(gSphere, 0), fgeomextra(gSmallSphere, 0), -> does not find the prime fgeomextra(gEuclid, 0), @@ -824,6 +875,7 @@ EX void nextPrime(fgeomextra& ex) { fp.build(); int cells = fp.matrices.size() / S7; ex.primes.emplace_back(primeinfo{nextprime, cells, (bool) fp.wsquare}); + ex.dualval.emplace_back(fp.dual); break; } nextprime++; @@ -831,8 +883,12 @@ EX void nextPrime(fgeomextra& ex) { } EX void nextPrimes(fgeomextra& ex) { - while(isize(ex.primes) < 4) + while(true) { + int nodual = 0; + for(int a: ex.dualval) if(!a) nodual++; + if(nodual >= 4) break; nextPrime(ex); + } } EX void enableFieldChange() { diff --git a/geom-exp.cpp b/geom-exp.cpp index 1caa583e..02d99b9a 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -48,9 +48,10 @@ void showQuotientConfig() { dialog::addBoolItem(ginf[g.base].tiling_name, g.base == gxcur.base, 'a'+i); } nextPrimes(gxcur); + string stars[3] = {"", "*", "**"}; for(int i=0; i