mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-22 23:17:04 +00:00
the main (heptagon) cellshape now also uses subcellshape; removed dirdist and get_vertices and introduced get_cellshape instead
This commit is contained in:
parent
2d962c324d
commit
6e6d0a7839
31
asonov.cpp
31
asonov.cpp
@ -110,24 +110,27 @@ EX void prepare() {
|
||||
|
||||
EX void prepare_walls() {
|
||||
|
||||
cgi.cellshape.clear();
|
||||
auto& hsh = cgi.heptshape;
|
||||
hsh = unique_ptr<subcellshape>(new subcellshape);
|
||||
auto& cs = hsh->faces;
|
||||
cs.clear();
|
||||
|
||||
auto pt = [&] (int x, int y, int z) { return asonov::tx*x/2 + asonov::ty*y/2 + asonov::tz*z/2 + C0; };
|
||||
|
||||
cgi.cellshape.push_back({pt(-1,-1,+1), pt(00,+1,+1), pt(+1,+1,+1)});
|
||||
cgi.cellshape.push_back({pt(00,-1,+1), pt(+1,+1,+1), pt(+1,-1,+1)});
|
||||
cgi.cellshape.push_back({pt(-1,+1,+1), pt(00,+1,+1), pt(-1,-1,+1)});
|
||||
cgi.cellshape.push_back({pt(-1,-1,+1), pt(+1,+1,+1), pt(00,-1,+1)});
|
||||
cgi.cellshape.push_back({pt(+1,-1,-1), pt(+1,00,-1), pt(+1,+1,-1), pt(+1,+1,+1), pt(+1,-1,+1)});
|
||||
cgi.cellshape.push_back({pt(-1,+1,-1), pt(-1,+1,+1), pt(00,+1,+1), pt(+1,+1,+1), pt(+1,+1,-1)});
|
||||
cgi.cellshape.push_back({pt(-1,-1,-1), pt(-1,00,-1), pt(+1,-1,-1)});
|
||||
cgi.cellshape.push_back({pt(-1,00,-1), pt(-1,+1,-1), pt(+1,-1,-1)});
|
||||
cgi.cellshape.push_back({pt(-1,+1,-1), pt(+1,00,-1), pt(+1,-1,-1)});
|
||||
cgi.cellshape.push_back({pt(-1,+1,-1), pt(+1,+1,-1), pt(+1,00,-1)});
|
||||
cgi.cellshape.push_back({pt(-1,+1,-1), pt(-1,00,-1), pt(-1,-1,-1), pt(-1,-1,+1), pt(-1,+1,+1)});
|
||||
cgi.cellshape.push_back({pt(+1,-1,-1), pt(+1,-1,+1), pt(00,-1,+1), pt(-1,-1,+1), pt(-1,-1,-1)});
|
||||
cs.push_back({pt(-1,-1,+1), pt(00,+1,+1), pt(+1,+1,+1)});
|
||||
cs.push_back({pt(00,-1,+1), pt(+1,+1,+1), pt(+1,-1,+1)});
|
||||
cs.push_back({pt(-1,+1,+1), pt(00,+1,+1), pt(-1,-1,+1)});
|
||||
cs.push_back({pt(-1,-1,+1), pt(+1,+1,+1), pt(00,-1,+1)});
|
||||
cs.push_back({pt(+1,-1,-1), pt(+1,00,-1), pt(+1,+1,-1), pt(+1,+1,+1), pt(+1,-1,+1)});
|
||||
cs.push_back({pt(-1,+1,-1), pt(-1,+1,+1), pt(00,+1,+1), pt(+1,+1,+1), pt(+1,+1,-1)});
|
||||
cs.push_back({pt(-1,-1,-1), pt(-1,00,-1), pt(+1,-1,-1)});
|
||||
cs.push_back({pt(-1,00,-1), pt(-1,+1,-1), pt(+1,-1,-1)});
|
||||
cs.push_back({pt(-1,+1,-1), pt(+1,00,-1), pt(+1,-1,-1)});
|
||||
cs.push_back({pt(-1,+1,-1), pt(+1,+1,-1), pt(+1,00,-1)});
|
||||
cs.push_back({pt(-1,+1,-1), pt(-1,00,-1), pt(-1,-1,-1), pt(-1,-1,+1), pt(-1,+1,+1)});
|
||||
cs.push_back({pt(+1,-1,-1), pt(+1,-1,+1), pt(00,-1,+1), pt(-1,-1,+1), pt(-1,-1,-1)});
|
||||
|
||||
reg3::make_vertices_only();
|
||||
hsh->compute_hept();
|
||||
}
|
||||
|
||||
transmatrix coord_to_matrix(coord c, coord zero) {
|
||||
|
@ -753,7 +753,7 @@ EX bool valid_dir(const vector<char>& ad, int j, cell *c) {
|
||||
if(!bch) return ad[j] == 1;
|
||||
|
||||
if(ad[j] != 2) return false;
|
||||
auto ad1 = currentmap->dirdist(c, j);
|
||||
auto ad1 = currentmap->get_cellshape(c).dirdist[j];
|
||||
int a = 0;
|
||||
for(auto& dd: ad1) if(dd == 1) a++;
|
||||
|
||||
|
@ -472,8 +472,12 @@ EX namespace bt {
|
||||
return gm * where;
|
||||
}
|
||||
|
||||
vector<hyperpoint> get_vertices(cell* c) override {
|
||||
vector<hyperpoint> res;
|
||||
subcellshape& get_cellshape(cell *c) override {
|
||||
if(cgi.heptshape)
|
||||
return *cgi.heptshape;
|
||||
|
||||
cgi.heptshape = (std::unique_ptr<subcellshape>) (new subcellshape);
|
||||
vector<hyperpoint>& res = cgi.heptshape->vertices_only;
|
||||
ld yy = log(2) / 2;
|
||||
auto add = [&] (hyperpoint h) {
|
||||
res.push_back(bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]));
|
||||
@ -512,7 +516,8 @@ EX namespace bt {
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
return res;
|
||||
cgi.heptshape->vertices_only_local = res;
|
||||
return *cgi.heptshape;
|
||||
}
|
||||
|
||||
ld spin_angle(cell *c, int d) override {
|
||||
|
14
cell.cpp
14
cell.cpp
@ -45,7 +45,6 @@ struct hrmap {
|
||||
}
|
||||
virtual void draw_all();
|
||||
virtual void draw_at(cell *at, const shiftmatrix& where);
|
||||
virtual vector<hyperpoint> get_vertices(cell*);
|
||||
|
||||
virtual void virtualRebase(heptagon*& base, transmatrix& at) {
|
||||
printf("virtualRebase called unexpectedly\n");
|
||||
@ -76,13 +75,13 @@ 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<char>& dirdist(cell *c, int i) { throw hr_exception("dirdist called unexpectedly"); }
|
||||
virtual subcellshape& get_cellshape(cell *c) { throw hr_exception("get_cellshape 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<char>& dirdist(cellwalker cw) { return dirdist(cw.at, cw.spin); }
|
||||
/** \brief in 3D honeycombs, returns a vector<bool> v, where v[j] iff faces i and j are adjacent */
|
||||
const vector<char>& dirdist(cellwalker cw) { return get_cellshape(cw.at).dirdist[cw.spin]; }
|
||||
};
|
||||
|
||||
/** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient
|
||||
@ -1287,7 +1286,8 @@ EX vector<cell*> adj_minefield_cells(cell *c) {
|
||||
}
|
||||
else if(adj_memo.count(c)) return adj_memo[c];
|
||||
else {
|
||||
const vector<hyperpoint> vertices = currentmap->get_vertices(c);
|
||||
auto& ss = currentmap->get_cellshape(c);
|
||||
const vector<hyperpoint>& vertices = ss.vertices_only_local;
|
||||
manual_celllister cl;
|
||||
cl.add(c);
|
||||
for(int i=0; i<isize(cl.lst); i++) {
|
||||
@ -1295,7 +1295,9 @@ EX vector<cell*> adj_minefield_cells(cell *c) {
|
||||
bool shares = false;
|
||||
if(c != c1) {
|
||||
transmatrix T = currentmap->relative_matrix(c1->master, c->master, C0);
|
||||
for(hyperpoint h: vertices) for(hyperpoint h2: vertices)
|
||||
auto& ss1 = currentmap->get_cellshape(c1);
|
||||
auto& vertices1 = ss1.vertices_only_local;
|
||||
for(hyperpoint h: vertices) for(hyperpoint h2: vertices1)
|
||||
if(hdist(h, T * h2) < 1e-6) shares = true;
|
||||
if(shares) res.push_back(c1);
|
||||
}
|
||||
|
@ -864,12 +864,14 @@ void celldrawer::draw_grid() {
|
||||
if(!bt::in() && c->move(t) < c) continue;
|
||||
dynamicval<color_t> g(poly_outline, gridcolor(c, c->move(t)));
|
||||
if(fat_edges && reg3::in()) {
|
||||
for(int i=0; i<S7; i++) if(c < c->move(i) || fake::split()) {
|
||||
for(int j=0; j<cgi.face; j++) {
|
||||
int jj = j == cgi.face-1 ? 0 : j+1;
|
||||
int jjj = jj == cgi.face-1 ? 0 : jj+1;
|
||||
hyperpoint a = cgi.cellshape[i][j];
|
||||
hyperpoint b = cgi.cellshape[i][jj];
|
||||
auto& ss = currentmap->get_cellshape(c);
|
||||
for(int i=0; i<c->type; i++) if(c < c->move(i) || fake::split()) {
|
||||
int face = isize(ss.faces[i]);
|
||||
for(int j=0; j<face; j++) {
|
||||
int jj = j == face-1 ? 0 : j+1;
|
||||
int jjj = jj == face-1 ? 0 : jj+1;
|
||||
hyperpoint a = ss.faces[i][j];
|
||||
hyperpoint b = ss.faces[i][jj];
|
||||
if(cgflags & qIDEAL) {
|
||||
ld mm = cgi.ultra_mirror_part;
|
||||
if((cgflags & qULTRA) && !reg3::ultra_mirror_in())
|
||||
@ -879,9 +881,9 @@ void celldrawer::draw_grid() {
|
||||
gridline(V, a, b, gridcolor(c, c->move(t)), prec);
|
||||
|
||||
if(reg3::ultra_mirror_in()) {
|
||||
hyperpoint a = cgi.cellshape[i][j];
|
||||
hyperpoint b = cgi.cellshape[i][jj];
|
||||
hyperpoint d = cgi.cellshape[i][jjj];
|
||||
hyperpoint a = ss.faces[i][j];
|
||||
hyperpoint b = ss.faces[i][jj];
|
||||
hyperpoint d = ss.faces[i][jjj];
|
||||
auto& mm = cgi.ultra_mirror_part;
|
||||
tie(a, d) = make_pair(normalize(lerp(a, b, mm)), normalize(lerp(d, b, mm)));
|
||||
gridline(V, a, d, stdgridcolor, prec);
|
||||
|
@ -250,7 +250,8 @@ int arg::readCommon() {
|
||||
}
|
||||
else if(argis("-face-vertex")) {
|
||||
PHASE(3); start_game();
|
||||
View = cspin(0, 2, M_PI/2) * spintox(cgi.vertices_only[0]);
|
||||
auto &ss = cgi.get_cellshape(cwt.at);
|
||||
View = cspin(0, 2, M_PI/2) * spintox(ss.vertices_only_local[0]);
|
||||
}
|
||||
else if(argis("-face-face")) {
|
||||
PHASE(3); start_game();
|
||||
|
@ -647,7 +647,7 @@ struct hrmap_crystal : hrmap_standard {
|
||||
if(go > 1e-2) continue;
|
||||
|
||||
for(int s=0; s<S7; s++)
|
||||
if(cgi.dirs_adjacent[d][s])
|
||||
if(cgi.heptshape->dirdist[d][s] == 1)
|
||||
for(int t=0; t<S7; t++)
|
||||
if(st1[t] == st[s]) {
|
||||
if(hdist(U * tC0(cgi.adjmoves[t]), tC0(cgi.adjmoves[s])) > gdist + .1)
|
||||
|
32
euclid.cpp
32
euclid.cpp
@ -292,28 +292,8 @@ EX namespace euc {
|
||||
return eumove(d);
|
||||
}
|
||||
|
||||
vector<hyperpoint> get_vertices(cell* c) override {
|
||||
vector<hyperpoint> res;
|
||||
if(S7 < 14)
|
||||
for(ld a: {-.5,.5}) for(ld b: {-.5,.5}) for(ld c: {-.5, .5}) res.push_back(hpxy3(a,b,c));
|
||||
if(S7 == 12) {
|
||||
res.push_back(hpxy3(1,0,0));
|
||||
res.push_back(hpxy3(-1,0,0));
|
||||
res.push_back(hpxy3(0,1,0));
|
||||
res.push_back(hpxy3(0,-1,0));
|
||||
res.push_back(hpxy3(0,0,1));
|
||||
res.push_back(hpxy3(0,0,-1));
|
||||
}
|
||||
if(S7 == 14) {
|
||||
for(ld a: {-1.,-.5,0.,.5,1.})
|
||||
for(ld b: {-1.,-.5,0.,.5,1.})
|
||||
for(ld c: {-1.,-.5,0.,.5,1.})
|
||||
if(a == 0 || b == 0 || c == 0)
|
||||
if(a == .5 || a == -.5 || b == .5 || b == -.5 || c == .5 || c == -.5)
|
||||
if(a == 1 || a == -1 || b == 1 || b == -1 || c == 1 || c == -1)
|
||||
res.push_back(hpxy3(a,b,c));
|
||||
}
|
||||
return res;
|
||||
subcellshape& get_cellshape(cell* c) override {
|
||||
return *cgi.heptshape;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1300,7 +1280,10 @@ EX void generate() {
|
||||
|
||||
auto v = euc::get_shifttable();
|
||||
|
||||
auto& cs = cgi.cellshape;
|
||||
auto& hsh = cgi.heptshape;
|
||||
hsh = unique_ptr<subcellshape>(new subcellshape);
|
||||
|
||||
auto& cs = hsh->faces;
|
||||
|
||||
cgi.loop = 4;
|
||||
cgi.schmid = 3;
|
||||
@ -1365,9 +1348,8 @@ EX void generate() {
|
||||
}
|
||||
}
|
||||
|
||||
reg3::make_vertices_only();
|
||||
hsh->compute_hept();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/** @brief returns true if the current geometry is based on this module
|
||||
|
19
fake.cpp
19
fake.cpp
@ -332,11 +332,11 @@ EX vector<vector<hyperpoint>> befake(const vector<vector<hyperpoint>>& v) {
|
||||
EX ld compute_around(bool setup) {
|
||||
auto &ucgi = *underlying_cgip;
|
||||
|
||||
auto fcs = befake(ucgi.cellshape);
|
||||
auto fcs = befake(ucgi.heptshape->faces);
|
||||
|
||||
if(setup) {
|
||||
cgi.cellshape = fcs;
|
||||
cgi.vertices_only = befake(ucgi.vertices_only);
|
||||
cgi.heptshape->faces = fcs;
|
||||
cgi.heptshape->compute_hept();
|
||||
}
|
||||
|
||||
hyperpoint h = Hypc;
|
||||
@ -394,11 +394,10 @@ EX void generate() {
|
||||
cgi.face = ucgi.face;
|
||||
cgi.schmid = ucgi.schmid;
|
||||
|
||||
for(int a=0; a<16; a++)
|
||||
for(int b=0; b<16; b++) {
|
||||
cgi.dirs_adjacent[a][b] = ucgi.dirs_adjacent[a][b];
|
||||
cgi.next_dir[a][b] = ucgi.next_dir[a][b];
|
||||
}
|
||||
auto& hsh = cgi.heptshape;
|
||||
hsh = unique_ptr<subcellshape>(new subcellshape);
|
||||
|
||||
*hsh = *ucgi.heptshape;
|
||||
|
||||
for(int b=0; b<12; b++)
|
||||
cgi.spins[b] = ucgi.spins[b];
|
||||
@ -487,7 +486,7 @@ EX void compute_scale() {
|
||||
}
|
||||
else if(euclid) scale = 1;
|
||||
else if(have_ideal) {
|
||||
hyperpoint h0 = underlying_cgip->cellshape[0][0];
|
||||
hyperpoint h0 = underlying_cgip->heptshape->faces[0][0];
|
||||
auto s = kleinize(h0);
|
||||
ld d = hypot_d(LDIM, s);
|
||||
scale = 1/d;
|
||||
@ -517,7 +516,7 @@ EX void compute_scale() {
|
||||
|
||||
/* ultra a bit earlier */
|
||||
if(underlying == gRhombic3 || underlying == gBitrunc3) {
|
||||
auto fcs = befake(underlying_cgip->cellshape[0][0]);
|
||||
auto fcs = befake(underlying_cgip->heptshape->faces[0][0]);
|
||||
set_flag(ginf[gFake].flags, qULTRA, material(fcs) < 0);
|
||||
}
|
||||
}
|
||||
|
21
geometry.cpp
21
geometry.cpp
@ -98,7 +98,7 @@ struct gi_extension {
|
||||
virtual ~gi_extension() {}
|
||||
};
|
||||
|
||||
/** for subdivided 3D cells */
|
||||
/** both for 'heptagon' 3D cells and subdivided 3D cells */
|
||||
struct subcellshape {
|
||||
vector<vector<hyperpoint>> faces;
|
||||
vector<vector<hyperpoint>> faces_local;
|
||||
@ -109,6 +109,17 @@ struct subcellshape {
|
||||
hyperpoint cellcenter;
|
||||
transmatrix to_cellcenter;
|
||||
transmatrix from_cellcenter;
|
||||
/** \brief for adjacent directions a,b, next_dir[a][b] is the next direction adjacent to a, in (counter?)clockwise order from b */
|
||||
vector<vector<char>> next_dir;
|
||||
|
||||
/** compute all the properties based on `faces`, for the main heptagon cellshape */
|
||||
void compute_hept();
|
||||
|
||||
/** compute all the properties based on `faces`, for subcells */
|
||||
void compute_sub();
|
||||
|
||||
/** common part of compute_hept and compute_sub */
|
||||
void compute_common();
|
||||
};
|
||||
|
||||
/** basic geometry parameters */
|
||||
@ -143,24 +154,18 @@ struct geometry_information {
|
||||
|
||||
int loop, face, schmid;
|
||||
|
||||
vector<vector<hyperpoint>> cellshape;
|
||||
vector<hyperpoint> vertices_only;
|
||||
|
||||
transmatrix spins[32], adjmoves[32];
|
||||
|
||||
unique_ptr<struct subcellshape> heptshape;
|
||||
vector<struct subcellshape> subshapes;
|
||||
|
||||
ld adjcheck;
|
||||
ld strafedist;
|
||||
vector<vector<char>> dirdist;
|
||||
|
||||
ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part;
|
||||
|
||||
vector<transmatrix> ultra_mirrors;
|
||||
|
||||
/** \brief for adjacent directions a,b, next_dir[a][b] is the next direction adjacent to a, in (counter?)clockwise order from b */
|
||||
int next_dir[32][32];
|
||||
|
||||
vector<pair<string, string> > rels;
|
||||
int xp_order, r_order, rx_order;
|
||||
|
||||
|
@ -734,12 +734,6 @@ EX hyperpoint get_warp_corner(cell *c, int cid) {
|
||||
return ddspin(c,cid,M_PI/S7) * xpush0(cgi.tessf/2);
|
||||
}
|
||||
|
||||
vector<hyperpoint> hrmap::get_vertices(cell* c) {
|
||||
vector<hyperpoint> res;
|
||||
for(int i=0; i<c->type; i++) res.push_back(get_corner_position(c, i, 3));
|
||||
return res;
|
||||
}
|
||||
|
||||
EX map<cell*, map<cell*, vector<transmatrix>>> brm_structure;
|
||||
|
||||
EX void generate_brm(cell *c1) {
|
||||
|
@ -1047,8 +1047,9 @@ void geometry_information::create_wall3d() {
|
||||
}
|
||||
|
||||
if(euc::in() || reg3::in() || asonov::in()) {
|
||||
for(int w=0; w<isize(cgi.cellshape); w++)
|
||||
make_wall(w, cgi.cellshape[w]);
|
||||
auto& faces = cgi.heptshape->faces;
|
||||
for(int w=0; w<isize(faces); w++)
|
||||
make_wall(w, faces[w]);
|
||||
}
|
||||
|
||||
if(geometry == gSol) {
|
||||
|
@ -701,7 +701,7 @@ void enable_raycaster() {
|
||||
"}\n";
|
||||
|
||||
if(hyperbolic && reg3::ultra_mirror_in()) {
|
||||
fmain += "for(int i="+its(S7*2)+"; i<"+its(S7*2+isize(cgi.vertices_only))+"; i++) {\n";
|
||||
fmain += "for(int i="+its(S7*2)+"; i<"+its(S7*2+isize(cgi.heptshape->vertices_only))+"; i++) {\n";
|
||||
fmain += "mat4 uMi = " + getM("i") + ";";
|
||||
fmain +=
|
||||
" mediump float v = ((position - uMi * position)[3] / (uMi * tangent - tangent)[3]);\n"
|
||||
|
220
reg3.cpp
220
reg3.cpp
@ -13,6 +13,65 @@
|
||||
namespace hr {
|
||||
#if MAXMDIM >= 4
|
||||
|
||||
void subcellshape::compute_common() {
|
||||
reg3::make_vertices_only(vertices_only, faces);
|
||||
|
||||
faces_local = faces;
|
||||
for(auto& face: faces_local) for(auto& v: face) v = from_cellcenter * v;
|
||||
|
||||
vertices_only_local = vertices_only;
|
||||
for(auto& v: vertices_only_local) v = from_cellcenter * v;
|
||||
|
||||
int N = isize(faces);
|
||||
|
||||
dirdist.resize(N);
|
||||
for(int i=0; i<N; i++) {
|
||||
auto& da = dirdist[i];
|
||||
da.resize(N, false);
|
||||
set<unsigned> cface;
|
||||
for(auto& v: faces[i]) cface.insert(bucketer(v));
|
||||
for(int j=0; j<N; j++) {
|
||||
int mutual = 0;
|
||||
for(auto& w: faces[j]) if(cface.count(bucketer(w))) mutual++;
|
||||
da[j] = i == j ? 0 : mutual == 2 ? 1 : INFD;
|
||||
}
|
||||
}
|
||||
floyd_warshall(dirdist);
|
||||
|
||||
next_dir.resize(N);
|
||||
for(int a=0; a<N; a++) next_dir[a].resize(N);
|
||||
|
||||
for(int a=0; a<N; a++)
|
||||
for(int b=0; b<N; b++)
|
||||
if(dirdist[a][b] == 1)
|
||||
for(int c=0; c<N; c++)
|
||||
if(dirdist[a][c] == 1 && dirdist[b][c] == 1) {
|
||||
transmatrix t = build_matrix(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b]), tC0(cgi.adjmoves[c]), C0);
|
||||
if(det(t) > 0) next_dir[a][b] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void subcellshape::compute_hept() {
|
||||
cellcenter = C0;
|
||||
to_cellcenter = Id;
|
||||
from_cellcenter = Id;
|
||||
compute_common();
|
||||
}
|
||||
|
||||
void subcellshape::compute_sub() {
|
||||
hyperpoint gres = Hypc;
|
||||
for(auto& face: faces) {
|
||||
hyperpoint res = Hypc;
|
||||
for(auto& vertex: face)
|
||||
res += vertex;
|
||||
face_centers.push_back(normalize(res));
|
||||
gres += res;
|
||||
}
|
||||
cellcenter = normalize(gres);
|
||||
to_cellcenter = rgpushxto0(cellcenter);
|
||||
from_cellcenter = gpushxto0(cellcenter);
|
||||
}
|
||||
|
||||
/** \brief regular three-dimensional tessellations */
|
||||
EX namespace reg3 {
|
||||
|
||||
@ -47,14 +106,15 @@ EX namespace reg3 {
|
||||
|
||||
if(cgflags & qULTRA) {
|
||||
|
||||
for(auto& v: cgi.vertices_only) {
|
||||
for(auto& v: cgi.heptshape->vertices_only) {
|
||||
|
||||
hyperpoint nei;
|
||||
auto& faces = cgi.heptshape->faces;
|
||||
|
||||
for(int i=0; i<isize(cgi.cellshape); i++)
|
||||
for(int j=0; j<isize(cgi.cellshape[i]); j++)
|
||||
if(sqhypot_d(WDIM, cgi.cellshape[i][j]-v) < 1e-6)
|
||||
nei = cgi.cellshape[i][j?j-1:j+1];
|
||||
for(int i=0; i<isize(faces); i++)
|
||||
for(int j=0; j<isize(faces[i]); j++)
|
||||
if(sqhypot_d(WDIM, faces[i][j]-v) < 1e-6)
|
||||
nei = faces[i][j?j-1:j+1];
|
||||
|
||||
transmatrix T = spintox(v);
|
||||
hyperpoint a = T * v;
|
||||
@ -106,10 +166,6 @@ EX namespace reg3 {
|
||||
}
|
||||
}
|
||||
|
||||
EX void make_vertices_only() {
|
||||
make_vertices_only(cgi.vertices_only, cgi.cellshape);
|
||||
}
|
||||
|
||||
EX void generate() {
|
||||
|
||||
if(fake::in()) {
|
||||
@ -117,12 +173,14 @@ EX namespace reg3 {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& hsh = cgi.heptshape;
|
||||
hsh = unique_ptr<subcellshape>(new subcellshape);
|
||||
|
||||
int& loop = cgi.loop;
|
||||
int& face = cgi.face;
|
||||
auto& spins = cgi.spins;
|
||||
auto& cellshape = cgi.cellshape;
|
||||
auto& cellshape = hsh->faces;
|
||||
auto& adjcheck = cgi.adjcheck;
|
||||
auto& dirdist = cgi.dirdist;
|
||||
|
||||
int& mid = cgi.schmid;
|
||||
mid = 3;
|
||||
@ -255,21 +313,6 @@ EX namespace reg3 {
|
||||
|
||||
adjcheck = hdist(tC0(cgi.adjmoves[0]), tC0(cgi.adjmoves[1])) * 1.0001;
|
||||
|
||||
int numedges = 0;
|
||||
dirdist.resize(S7);
|
||||
for(int a=0; a<S7; a++) {
|
||||
dirdist[a].resize(S7);
|
||||
for(int b=0; b<S7; b++) {
|
||||
dirdist[a][b] =
|
||||
a == b ? 0 :
|
||||
hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck ? 1 :
|
||||
INFD;
|
||||
if(dirdist[a][b] == 1) numedges++;
|
||||
}
|
||||
}
|
||||
floyd_warshall(dirdist);
|
||||
DEBB(DF_GEOM, ("numedges = ", numedges));
|
||||
|
||||
if(loop == 4) cgi.strafedist = adjcheck;
|
||||
else cgi.strafedist = hdist(cgi.adjmoves[0] * C0, cgi.adjmoves[1] * C0);
|
||||
|
||||
@ -280,18 +323,9 @@ EX namespace reg3 {
|
||||
for(auto& vv: cellshape) for(auto& v: vv) v = T * v;
|
||||
}
|
||||
|
||||
make_vertices_only();
|
||||
hsh->compute_hept();
|
||||
compute_ultra();
|
||||
|
||||
for(int a=0; a<S7; a++)
|
||||
for(int b=0; b<S7; b++)
|
||||
if(cgi.dirdist[a][b] == 1)
|
||||
for(int c=0; c<S7; c++)
|
||||
if(cgi.dirdist[a][c] == 1 && cgi.dirdist[b][c] == 1) {
|
||||
transmatrix t = build_matrix(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b]), tC0(cgi.adjmoves[c]), C0);
|
||||
if(det(t) > 1e-3) cgi.next_dir[a][b] = c;
|
||||
}
|
||||
|
||||
generate_subcells();
|
||||
}
|
||||
|
||||
@ -299,14 +333,14 @@ EX namespace reg3 {
|
||||
if(S7 != 6) throw hr_exception("generate_plain_subcubes but no cubes");
|
||||
auto& ssh = cgi.subshapes;
|
||||
const int sub = subcube_count;
|
||||
auto vx = abs(cgi.cellshape[0][0][0]);
|
||||
auto vz = abs(cgi.cellshape[0][0][3]);
|
||||
auto vx = abs(cgi.heptshape->faces[0][0][0]);
|
||||
auto vz = abs(cgi.heptshape->faces[0][0][3]);
|
||||
for(int x=1-sub; x<sub; x+=2)
|
||||
for(int y=1-sub; y<sub; y+=2)
|
||||
for(int z=1-sub; z<sub; z+=2) {
|
||||
ssh.emplace_back();
|
||||
auto &ss = ssh.back();
|
||||
ss.faces = cgi.cellshape;
|
||||
ss.faces = cgi.heptshape->faces;
|
||||
for(auto& face: ss.faces) for(auto& v: face) {
|
||||
v[0] += vx * x;
|
||||
v[1] += vx * y;
|
||||
@ -318,7 +352,7 @@ EX namespace reg3 {
|
||||
|
||||
EX void generate_coxeter(flagtype f) {
|
||||
auto& ssh = cgi.subshapes;
|
||||
for(auto& fac: cgi.cellshape) {
|
||||
for(auto& fac: cgi.heptshape->faces) {
|
||||
hyperpoint facectr = Hypc;
|
||||
vector<hyperpoint> ring;
|
||||
hyperpoint last = fac.back();
|
||||
@ -384,8 +418,8 @@ EX namespace reg3 {
|
||||
if(S7 != 6) throw hr_exception("generate_plain_subcubes but no cubes");
|
||||
const int sub = subcube_count;
|
||||
if(1) {
|
||||
auto vx = abs(cgi.cellshape[0][0][0]);
|
||||
auto vz = abs(cgi.cellshape[0][0][3]);
|
||||
auto vx = abs(cgi.heptshape->faces[0][0][0]);
|
||||
auto vz = abs(cgi.heptshape->faces[0][0][3]);
|
||||
auto step = hdist0(tC0(cgi.adjmoves[0]));
|
||||
array<int, 3> co;
|
||||
int s = bch ? 1 : 2;
|
||||
@ -596,7 +630,7 @@ EX namespace reg3 {
|
||||
|
||||
case eVariation::pure: {
|
||||
cgi.subshapes.emplace_back();
|
||||
cgi.subshapes[0].faces = cgi.cellshape;
|
||||
cgi.subshapes[0].faces = cgi.heptshape->faces;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -604,39 +638,7 @@ EX namespace reg3 {
|
||||
throw hr_exception("unknown variation in generate_subcells");
|
||||
}
|
||||
|
||||
for(auto& ss: cgi.subshapes) {
|
||||
make_vertices_only(ss.vertices_only, ss.faces);
|
||||
hyperpoint gres = Hypc;
|
||||
for(auto& face: ss.faces) {
|
||||
hyperpoint res = Hypc;
|
||||
for(auto& vertex: face)
|
||||
res += vertex;
|
||||
ss.face_centers.push_back(normalize(res));
|
||||
gres += res;
|
||||
}
|
||||
ss.cellcenter = normalize(gres);
|
||||
ss.to_cellcenter = rgpushxto0(ss.cellcenter);
|
||||
ss.from_cellcenter = gpushxto0(ss.cellcenter);
|
||||
ss.faces_local = ss.faces;
|
||||
for(auto& face: ss.faces_local) for(auto& v: face) v = ss.from_cellcenter * v;
|
||||
ss.vertices_only_local = ss.vertices_only;
|
||||
for(auto& v: ss.vertices_only_local) v = ss.from_cellcenter * v;
|
||||
|
||||
int N = isize(ss.faces);
|
||||
ss.dirdist.resize(N);
|
||||
for(int i=0; i<N; i++) {
|
||||
auto& da = ss.dirdist[i];
|
||||
da.resize(N, false);
|
||||
set<unsigned> cface;
|
||||
for(auto& v: ss.faces[i]) cface.insert(bucketer(v));
|
||||
for(int j=0; j<N; j++) {
|
||||
int mutual = 0;
|
||||
for(auto& w: ss.faces[j]) if(cface.count(bucketer(w))) mutual++;
|
||||
da[j] = i == j ? 0 : mutual == 2 ? 1 : INFD;
|
||||
}
|
||||
}
|
||||
floyd_warshall(ss.dirdist);
|
||||
}
|
||||
for(auto& ss: cgi.subshapes) ss.compute_sub();
|
||||
|
||||
println(hlog, "subcells generated = ", isize(cgi.subshapes));
|
||||
}
|
||||
@ -680,10 +682,10 @@ EX namespace reg3 {
|
||||
void initialize(int cell_count);
|
||||
vector<cell*>& allcells() override { return acells; }
|
||||
|
||||
vector<hyperpoint> get_vertices(cell* c) override {
|
||||
if(PURE) return cgi.vertices_only;
|
||||
subcellshape& get_cellshape(cell *c) override {
|
||||
if(PURE) return *cgi.heptshape ;
|
||||
int id = local_id.at(c).second;
|
||||
return cgi.subshapes[id].vertices_only_local;
|
||||
return cgi.subshapes[id];
|
||||
}
|
||||
|
||||
transmatrix master_relative(cell *c, bool get_inverse) override {
|
||||
@ -699,11 +701,6 @@ EX namespace reg3 {
|
||||
|
||||
transmatrix ray_iadj(cell *c, int i) override;
|
||||
|
||||
const vector<char>& dirdist(cell *c, int i) override {
|
||||
int id = local_id.at(c).second;
|
||||
return cgi.subshapes[id].dirdist[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]);
|
||||
@ -760,7 +757,7 @@ EX namespace reg3 {
|
||||
va.emplace_back(vertex_adjacency_info{a, Id, {}});
|
||||
|
||||
set<unsigned> buckets;
|
||||
for(auto& v: cgi.vertices_only) buckets.insert(bucketer(v));
|
||||
for(auto& v: cgi.heptshape->vertices_only) buckets.insert(bucketer(v));
|
||||
|
||||
if(cgflags & qIDEAL) {
|
||||
for(int d=0; d<S7; d++) {
|
||||
@ -777,7 +774,7 @@ EX namespace reg3 {
|
||||
if(found) continue;
|
||||
|
||||
bool found_va = false;
|
||||
for(auto& w: cgi.vertices_only)
|
||||
for(auto& w: cgi.heptshape->vertices_only)
|
||||
if(buckets.count(bucketer(T*w)))
|
||||
found_va = true;
|
||||
if(!found_va) continue;
|
||||
@ -1031,8 +1028,9 @@ EX namespace reg3 {
|
||||
void make_plane(cellwalker cw) {
|
||||
if(plane.count(cw)) return;
|
||||
plane.insert(cw);
|
||||
for(int i=0; i<S7; i++)
|
||||
if(cgi.dirdist[i][cw.spin] == 1)
|
||||
auto& ss = get_cellshape(cw.at);
|
||||
for(int i=0; i<cw.at->type; i++)
|
||||
if(ss.dirdist[i][cw.spin] == 1)
|
||||
make_plane(strafe(cw, i));
|
||||
}
|
||||
|
||||
@ -1131,19 +1129,12 @@ EX namespace reg3 {
|
||||
|
||||
void build_reps() {
|
||||
// start_game();
|
||||
for(int a=0; a<12; a++)
|
||||
for(int b=0; b<12; b++)
|
||||
if(cgi.dirdist[a][b] == 1)
|
||||
for(int c=0; c<12; c++)
|
||||
if(cgi.dirdist[a][c] == 1 && cgi.dirdist[b][c] == 1) {
|
||||
transmatrix t = build_matrix(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b]), tC0(cgi.adjmoves[c]), C0);
|
||||
if(det(t) > 0) cgi.next_dir[a][b] = c;
|
||||
}
|
||||
auto& hsh = cgi.heptshape;
|
||||
|
||||
set<coord> boundaries;
|
||||
|
||||
for(int a=0; a<12; a++)
|
||||
for(int b=0; b<12; b++) if(cgi.dirdist[a][b] == 1) {
|
||||
for(int b=0; b<12; b++) if(hsh->dirdist[a][b] == 1) {
|
||||
coord res = crystal::c0;
|
||||
int sa = a, sb = b;
|
||||
do {
|
||||
@ -1152,7 +1143,7 @@ EX namespace reg3 {
|
||||
sa = flip(sa);
|
||||
sb = flip(sb);
|
||||
swap(sa, sb);
|
||||
sb = cgi.next_dir[sa][sb];
|
||||
sb = hsh->next_dir[sa][sb];
|
||||
// sb = next_dirsa][sb];
|
||||
}
|
||||
while(a != sa || b != sb);
|
||||
@ -1518,12 +1509,8 @@ EX namespace reg3 {
|
||||
return T;
|
||||
}
|
||||
|
||||
vector<hyperpoint> get_vertices(cell* c) override {
|
||||
return cgi.vertices_only;
|
||||
}
|
||||
|
||||
const vector<char>& dirdist(cell *c, int i) override {
|
||||
return cgi.dirdist[i];
|
||||
subcellshape& get_cellshape(cell *c) override {
|
||||
return *cgi.heptshape;
|
||||
}
|
||||
|
||||
cellwalker strafe(cellwalker cw, int j) override {
|
||||
@ -1964,10 +1951,10 @@ EX namespace reg3 {
|
||||
return quotient_map->tmatrices_cell[aid][d];
|
||||
}
|
||||
|
||||
vector<hyperpoint> get_vertices(cell* c) override {
|
||||
if(PURE) return cgi.vertices_only;
|
||||
subcellshape& get_cellshape(cell *c) override {
|
||||
if(PURE) return *cgi.heptshape;
|
||||
int aid = cell_id.at(c);
|
||||
return quotient_map->get_vertices(quotient_map->acells[aid]);
|
||||
return quotient_map->get_cellshape(quotient_map->acells[aid]);
|
||||
}
|
||||
|
||||
map<cell*, int> cell_id;
|
||||
@ -2006,12 +1993,6 @@ EX namespace reg3 {
|
||||
return quotient_map->ray_iadj(quotient_map->acells[aid], i);
|
||||
}
|
||||
|
||||
const vector<char>& dirdist(cell *c, int i) override {
|
||||
if(PURE) return cgi.dirdist[i];
|
||||
int aid = cell_id.at(c);
|
||||
return quotient_map->dirdist(quotient_map->acells[aid], i);
|
||||
}
|
||||
|
||||
cellwalker strafe(cellwalker cw, int j) override {
|
||||
|
||||
hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]);
|
||||
@ -2398,7 +2379,8 @@ EX void construct_relations() {
|
||||
formulas.push_back("");
|
||||
|
||||
all.push_back(Id);
|
||||
hyperpoint v = cgi.cellshape[0][0];
|
||||
auto& faces = cgi.heptshape->faces;
|
||||
hyperpoint v = faces[0][0];
|
||||
auto add = [&] (transmatrix T) {
|
||||
for(int i=0; i<isize(all); i++) if(eqmatrix(all[i], T)) return i;
|
||||
int S = isize(all);
|
||||
@ -2406,14 +2388,14 @@ EX void construct_relations() {
|
||||
return S;
|
||||
};
|
||||
|
||||
println(hlog, cgi.cellshape);
|
||||
println(hlog, faces);
|
||||
|
||||
println(hlog, "cellshape = ", isize(cgi.cellshape));
|
||||
println(hlog, "cellshape = ", isize(faces));
|
||||
bool ok = true;
|
||||
int last_i = -1;
|
||||
for(auto& v: cgi.cellshape) for(hyperpoint h: v) {
|
||||
for(auto& v: faces) for(hyperpoint h: v) {
|
||||
int i = 0, j = 0;
|
||||
for(auto& uv: cgi.cellshape) for(hyperpoint u: uv) {
|
||||
for(auto& uv: faces) for(hyperpoint u: uv) {
|
||||
if(hdist(h, cgi.full_X*u) < 5e-2) i++;
|
||||
if(hdist(h, cgi.full_R*u) < 5e-2) j++;
|
||||
}
|
||||
@ -2427,7 +2409,7 @@ EX void construct_relations() {
|
||||
|
||||
auto work = [&] (transmatrix T, int p, char c) {
|
||||
if(hdist0(tC0(T)) > 5) return;
|
||||
for(auto& hv: cgi.cellshape) for(hyperpoint h: hv) if(hdist(T * h, v) < 1e-4) goto ok;
|
||||
for(auto& hv: faces) for(hyperpoint h: hv) if(hdist(T * h, v) < 1e-4) goto ok;
|
||||
return;
|
||||
ok:
|
||||
int id = add(T);
|
||||
|
Loading…
Reference in New Issue
Block a user