reg3:: strafe and dirs_adjacent with subcubes -- Great Wall generation works

This commit is contained in:
Zeno Rogue 2021-07-11 11:48:33 +02:00
parent 5f54bf2888
commit 0e0e4d0212
5 changed files with 100 additions and 37 deletions

View File

@ -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; j<S7; j++) if(cgi.dirs_adjacent[cw.spin][j]) {
cellwalker bb2 = reg3::strafe(cw, j);
if(S3 == 5) { bb2 += rev; bb2 += wstep; }
auto& ad = currentmap->adjacent_dirs(cw);
for(int j=0; j<S7; j++) if(ad[j]) {
cellwalker bb2 = currentmap->strafe(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<cell*> listed_cells = { cw.at };
vector<cellwalker> to_test { cw };
for(int i=0; i<isize(to_test); i++) {
@ -796,13 +799,14 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) {
if(bb.at->mpdist < 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; j<S7; j++) {
if(S3 == 5 && i <= 5) bb.at->cmove(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; i<isize(to_test); i++) {
auto bb = to_test[i];
if(S3 == 5) { bb.at->bardir = 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;

View File

@ -206,10 +206,11 @@ void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) {
}
#if MAXMDIM >= 4
EX int hrandom_adjacent(int d) {
vector<int> choices = {d};
for(int a=0; a<S7; a++) if(cgi.dirs_adjacent[d][a]) choices.push_back(a);
return hrand_elt(choices, d);
EX int hrandom_adjacent(cellwalker cw) {
auto& da = currentmap->adjacent_dirs(cw);
vector<int> choices = {cw.spin};
for(int a=0; a<S7; a++) if(da[a]) choices.push_back(a);
return hrand_elt(choices, cw.spin);
}
#endif
@ -271,7 +272,7 @@ EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special
#if MAXMDIM >= 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; j<S7; j++) if(cw.at->move(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; j<S7; j++) if(cw.at->move(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; j<S7; j++) if(cw.at->move(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; j<S7; j++) if(cw.at->move(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);
}

View File

@ -75,6 +75,14 @@ struct hrmap {
}
return currentmap->iadj(c, i);
}
/** \brief in 3D honeycombs, returns a vector<bool> v, where v[j] iff faces i and j are adjacent */
virtual const vector<bool>& 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<bool>& adjacent_dirs(cellwalker cw) { return adjacent_dirs(cw.at, cw.spin); }
};
/** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient

View File

@ -105,6 +105,7 @@ struct subcellshape {
vector<hyperpoint> vertices_only;
vector<hyperpoint> vertices_only_local;
vector<hyperpoint> face_centers;
vector<vector<bool>> 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<vector<bool>> dirs_adjacent;
ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part;

View File

@ -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; a<S7; a++) for(int b=0; b<S7; b++) {
dirs_adjacent[a][b] = a != b && hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck;
if(dirs_adjacent[a][b]) numedges++;
dirs_adjacent.resize(S7);
for(int a=0; a<S7; a++) {
dirs_adjacent[a].resize(S7);
for(int b=0; b<S7; b++) {
dirs_adjacent[a][b] = a != b && hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck;
if(dirs_adjacent[a][b]) numedges++;
}
}
DEBB(DF_GEOM, ("numedges = ", numedges));
@ -688,6 +692,16 @@ EX namespace reg3 {
int shvid(cell *c) { return local_id.at(c).second; }
virtual transmatrix ray_iadj(cell *c, int i) override;
const vector<bool>& adjacent_dirs(cell *c, int i) {
int id = local_id.at(c).second;
return cgi.subshapes[id].dirs_adjacent[i];
}
cellwalker strafe(cellwalker cw, int j) override {
int id = local_id.at(cw.at).first;
return cellwalker(cw.at->cmove(j), strafe_data[id][j][cw.spin]);
}
};
struct hrmap_quotient3 : hrmap_closed3 { };
@ -987,7 +1001,7 @@ EX namespace reg3 {
plane.insert(cw);
for(int i=0; i<S7; i++)
if(cgi.dirs_adjacent[i][cw.spin])
make_plane(reg3::strafe(cw, i));
make_plane(strafe(cw, i));
}
@ -1475,6 +1489,21 @@ EX namespace reg3 {
vector<hyperpoint> get_vertices(cell* c) override {
return cgi.vertices_only;
}
const vector<bool>& adjacent_dirs(cell *c, int i) {
return cgi.dirs_adjacent[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);
for(int i=0; i<S7; i++) if(i != cw.at->c.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");
}
};
struct hrmap_sphere3 : hrmap_closed3 {
@ -1940,6 +1969,30 @@ EX namespace reg3 {
int aid = cell_id.at(c);
return quotient_map->ray_iadj(quotient_map->acells[aid], i);
}
const vector<bool>& 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; i<S7; i++) if(i != cw.at->c.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; i<S7; i++) if(i != cw.at->c.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;