diff --git a/barriers.cpp b/barriers.cpp index 80a4c82e..368c57dd 100644 --- a/barriers.cpp +++ b/barriers.cpp @@ -745,13 +745,15 @@ EX void buildCrossroads2(cell *c) { } #if MAXMDIM >= 4 +EX bool bufferzone() { return false; } + EX void extend3D(cell *c) { eLand l1 = c->land; c->barleft = NOWALLSEP_USED; cellwalker cw(c, c->bardir); - if(S3 == 5) { + if(bufferzone()) { cw += wstep; cw += rev; cw.at->bardir = NOBARRIERS; setland(cw.at, laBarrier); @@ -765,9 +767,10 @@ EX void extend3D(cell *c) { cw1.at->bardir = cw1.spin; } - for(int j=0; jadjacent_dirs(cw); + for(int j=0; jstrafe(cw, j); + if(bufferzone()) { bb2 += rev; bb2 += wstep; } if(bb2.at->bardir == NODIR) { bb2.at->bardir = bb2.spin; @@ -788,7 +791,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) { return false; } cellwalker cw(c, forced_dir); - if(S3 == 5) { cw += wstep; cw += rev; } + if(bufferzone()) { cw += wstep; cw += rev; } set listed_cells = { cw.at }; vector to_test { cw }; for(int i=0; impdist < BARLEV) return false; if(bb.cpeek()->mpdist < BARLEV) return false; if(bb.cpeek()->bardir != NODIR) return false; - if(S3 == 5 && (bb+rev).cpeek()->mpdist < BARLEV) return false; - if(S3 == 5 && (bb+rev).cpeek()->bardir != NODIR) return false; + if(bufferzone() && (bb+rev).cpeek()->mpdist < BARLEV) return false; + if(bufferzone() && (bb+rev).cpeek()->bardir != NODIR) return false; if(bb.at->bardir != NODIR) return false; + auto& ad = currentmap->adjacent_dirs(bb); for(int j=0; jcmove(j); - if(cgi.dirs_adjacent[bb.spin][j] && bb.at->move(j)) { - cellwalker bb2 = reg3::strafe(bb, j); + if(bufferzone() && i <= 5) bb.at->cmove(j); + if(ad[j] && bb.at->move(j)) { + cellwalker bb2 = currentmap->strafe(bb, j); if(listed_cells.count(bb2.at)) continue; listed_cells.insert(bb2.at); to_test.push_back(bb2); @@ -812,7 +816,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) { for(int i=0; ibardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; } + if(bufferzone()) { bb.at->bardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; } bb.at->land = c->land; bb.at->bardir = bb.spin; bb.at->barleft = NOWALLSEP; diff --git a/bigstuff.cpp b/bigstuff.cpp index e5347126..7478366e 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -206,10 +206,11 @@ void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) { } #if MAXMDIM >= 4 -EX int hrandom_adjacent(int d) { - vector choices = {d}; - for(int a=0; aadjacent_dirs(cw); + vector choices = {cw.spin}; + for(int a=0; a= 4 // in 3D honeycombs we vary the direction, but never for three successive i's if(WDIM == 3 && firststate == hsOrigin && (i%3)) - bf.spin = hrandom_adjacent(bf.spin); + bf.spin = hrandom_adjacent(bf); #endif } cx[rad] = bf.at; @@ -694,9 +695,12 @@ EX void buildEquidistant(cell *c) { if(cw.at->landparam != c->landparam-1) continue; if(!cw.at->landflags) continue; if(S7 == 6) c->landflags = 1; - else for(int j=0; jmove(j) && cw.at->move(j)->landparam == c->landparam - 2 && !cgi.dirs_adjacent[j][cw.spin]) - if(c->landparam == 2 ? cw.at->move(j)->land != laEndorian : cw.at->move(j)->landparam) - c->landflags = 1; + else { + auto& da = currentmap->adjacent_dirs(cw); + for(int j=0; jmove(j) && cw.at->move(j)->landparam == c->landparam - 2 && !da[j]) + if(c->landparam == 2 ? cw.at->move(j)->land != laEndorian : cw.at->move(j)->landparam) + c->landflags = 1; + } } } else if(c->landparam == 2) { @@ -718,8 +722,11 @@ EX void buildEquidistant(cell *c) { if(cw.at->landparam != c->landparam-1) continue; if(!cw.at->landflags) continue; if(S7 == 6) c->landflags = 1; - else for(int j=0; jmove(j) && cw.at->move(j)->landparam == c->landparam - 2 && !cgi.dirs_adjacent[j][cw.spin] && cw.at->move(j)->landflags) - c->landflags = 1; + else { + auto& da = currentmap->adjacent_dirs(cw); + for(int j=0; jmove(j) && cw.at->move(j)->landparam == c->landparam - 2 && !da[j] && cw.at->move(j)->landflags) + c->landflags = 1; + } } } else { @@ -1485,7 +1492,7 @@ EX bool good_for_wall(cell *c) { } EX bool walls_not_implemented() { - if(WDIM == 3 && !PURE) return true; + // if(WDIM == 3 && !PURE) return true; if(sphere || quotient || nonisotropic || (kite::in() && !bt::in()) || experimental) return true; return WDIM == 3 && (cgflags & qIDEAL); } diff --git a/cell.cpp b/cell.cpp index 027a7715..4f945111 100644 --- a/cell.cpp +++ b/cell.cpp @@ -75,6 +75,14 @@ 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& adjacent_dirs(cell *c, int i) { throw hr_exception("adjacent_dirs 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& adjacent_dirs(cellwalker cw) { return adjacent_dirs(cw.at, cw.spin); } }; /** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient diff --git a/geometry.cpp b/geometry.cpp index 2f94980c..9667a483 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -105,6 +105,7 @@ struct subcellshape { vector vertices_only; vector vertices_only_local; vector face_centers; + vector> dirs_adjacent; hyperpoint cellcenter; transmatrix to_cellcenter; transmatrix from_cellcenter; @@ -151,7 +152,7 @@ struct geometry_information { ld adjcheck; ld strafedist; - bool dirs_adjacent[32][32]; + vector> dirs_adjacent; ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part; diff --git a/reg3.cpp b/reg3.cpp index c22632ab..ddcc2559 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -256,9 +256,13 @@ EX namespace reg3 { adjcheck = hdist(tC0(cgi.adjmoves[0]), tC0(cgi.adjmoves[1])) * 1.0001; int numedges = 0; - for(int a=0; aray_iadj(quotient_map->acells[aid], i); } + + const vector& adjacent_dirs(cell *c, int i) { + if(PURE) return cgi.dirs_adjacent[i]; + int aid = cell_id.at(c); + return quotient_map->adjacent_dirs(quotient_map->acells[aid], i); + } + + cellwalker strafe(cellwalker cw, int j) override { + + hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]); + cw.at->cmove(j); + transmatrix T = currentmap->adj(cw.at, j); + cellwalker res1; + for(int i=0; ic.spin(j)) + if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01) + res1 = cellwalker(cw.at->cmove(j), i); + + int aid = PURE ? cw.at->master->fieldval : cell_id.at(cw.at); + auto res = quotient_map->strafe(cellwalker(quotient_map->acells[aid], cw.spin), j); + cellwalker res2 = cellwalker(cw.at->cmove(j), res.spin); + + if(PURE && res1 != res2) println(hlog, "h3: ", res1, " vs ", res2); + return res2; + } }; struct hrmap_h3_rule_alt : hrmap { @@ -2267,16 +2320,6 @@ int dist_alt(cell *c) { // as possible to cw.spin. Assume that j and cw.spin are adjacent #if MAXMDIM >= 4 -EX cellwalker strafe(cellwalker cw, int j) { - hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]); - cw.at->cmove(j); - transmatrix T = currentmap->adj(cw.at, j); - for(int i=0; ic.spin(j)) - if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01) - return cellwalker(cw.at->cmove(j), i); - throw hr_exception("incorrect strafe"); - } - EX int matrix_order(const transmatrix A) { transmatrix T = A; int res = 1;