mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-09-07 04:47:56 +00:00
3d:: all the regular honeycombs
This commit is contained in:
267
sphere.cpp
267
sphere.cpp
@@ -164,271 +164,4 @@ heptagon *getDodecahedron(int i) {
|
||||
return s->dodecahedron[i];
|
||||
}
|
||||
|
||||
namespace sphere3 {
|
||||
|
||||
vector<hyperpoint> vertices120;
|
||||
array<transmatrix, 120> vmatrix120;
|
||||
vector<int> adj0;
|
||||
array<array<int, 4>, 120> js;
|
||||
array<hyperpoint, 60> dodefaces;
|
||||
|
||||
int opposite[120];
|
||||
|
||||
hyperpoint zero4;
|
||||
|
||||
int root;
|
||||
|
||||
ld norm(hyperpoint a, hyperpoint b) {
|
||||
ld res = 0;
|
||||
for(int i=0; i<4; i++) res += pow(a[i]-b[i], 2);
|
||||
return res;
|
||||
}
|
||||
|
||||
void gen600() {
|
||||
dynamicval<eGeometry> gp(geometry, gCell120);
|
||||
vertices120.clear();
|
||||
root = 23;
|
||||
|
||||
/// coordinates taken from Wikipedia
|
||||
|
||||
for(int a=0; a<16; a++) {
|
||||
hyperpoint v = zero4;
|
||||
for(int i=0; i<4; i++) v[i] = ((a >> i) & 1) ? .5 : -.5;
|
||||
vertices120.push_back(v);
|
||||
}
|
||||
|
||||
for(int i=0; i<4; i++) for(int q: {-1, 1}) {
|
||||
hyperpoint v = zero4;
|
||||
v[i]=q;
|
||||
vertices120.push_back(v);
|
||||
}
|
||||
|
||||
ld phi = (1 + sqrt(5)) / 2;
|
||||
|
||||
array<ld, 4> coo = make_array<ld>(1, phi, 1/phi, 0);
|
||||
|
||||
// all permutations
|
||||
array<int, 4> tab;
|
||||
for(int i=0; i<4; i++) tab[i] = i;
|
||||
|
||||
do {
|
||||
|
||||
// check the permutation's sign
|
||||
auto tabs = tab;
|
||||
int inv = 0;
|
||||
|
||||
for(int i=0; i<4; i++) while(tabs[i] != i) {
|
||||
swap(tabs[i], tabs[tabs[i]]);
|
||||
inv++;
|
||||
}
|
||||
|
||||
if(inv&1) goto again;
|
||||
|
||||
// 8 vertices for each permutation
|
||||
|
||||
for(int sg=0; sg<8; sg++) {
|
||||
hyperpoint v;
|
||||
for(int i=0; i<4; i++)
|
||||
v[i] = (((sg >> tab[i])&1) ? 1 : -1) * coo[tab[i]]/2;
|
||||
vertices120.push_back(v);
|
||||
}
|
||||
|
||||
again: ;
|
||||
}
|
||||
while(std::next_permutation(tab.begin(), tab.end()));
|
||||
|
||||
if(isize(vertices120) != 120) {
|
||||
printf("error: wrong number of vertices\n");
|
||||
exit(1);
|
||||
}
|
||||
// we add edges between vertices which are close to each other
|
||||
// ((specifically in distance 1/phi/phi)
|
||||
|
||||
bool inedge[120][120];
|
||||
|
||||
for(int i=0; i<120; i++)
|
||||
for(int j=0; j<120; j++) {
|
||||
ld d = hdist(vertices120[i], vertices120[j]);
|
||||
inedge[i][j] = (i != j) && d < sqrt(.4);
|
||||
}
|
||||
|
||||
vector<hyperpoint> cellvertices;
|
||||
|
||||
for(int i=0; i<120; i++)
|
||||
for(int j=0; j<120; j++) if(inedge[i][j])
|
||||
for(int k=0; k<120; k++) if(inedge[i][k] && inedge[k][j])
|
||||
for(int l=0; l<120; l++) if(inedge[i][l] && inedge[j][l] && inedge[k][l]) {
|
||||
array<int, 4> ijkl = make_array(i, j, k, l);
|
||||
transmatrix T;
|
||||
for(int z=0; z<4; z++) set_column(T, z, vertices120[ijkl[z]]);
|
||||
if(det(T) > 0) js[i] = ijkl;
|
||||
}
|
||||
|
||||
/* transmatrix src;
|
||||
for(int z=0; z<4; z++) set_column(src, z, vertices120[js[0][z]]); */
|
||||
|
||||
for(int i=0; i<120; i++)
|
||||
for(int z=0; z<4; z++) set_column(vmatrix120[i], z, vertices120[js[i][z]]);
|
||||
|
||||
for(int i=0; i<120; i++) {
|
||||
println(hlog, i, ": ", js[i], " -> ", vmatrix120[i]);
|
||||
println(hlog, vmatrix120[i] * hyperpoint(1,0,0,0), " should be ", vertices120[i]);
|
||||
}
|
||||
|
||||
adj0.clear();
|
||||
for(int i=0; i<120; i++) if(inedge[root][i]) adj0.push_back(i);
|
||||
|
||||
using namespace hyperpoint_vec;
|
||||
for(int i=0; i<6; i++) for(int j=i+1; j<12; j++) if(zero_d(3, vertices120[adj0[i]] + vertices120[adj0[j]]))
|
||||
swap(adj0[j], adj0[i+6]);
|
||||
|
||||
for(int i=0; i<120; i++) for(int j=0; j<120; j++)
|
||||
if(hdist(vertices120[i], vertices120[j]) > 3)
|
||||
opposite[i] = j;
|
||||
|
||||
using namespace hyperpoint_vec;
|
||||
|
||||
int id = 0;
|
||||
for(int i=0; i<12; i++) {
|
||||
int ot = adj0[i];
|
||||
|
||||
vector<int> pentagon;
|
||||
for(int j: adj0) if(inedge[ot][j]) pentagon.push_back(j);
|
||||
println(hlog, i, ": ", pentagon);
|
||||
|
||||
int illegal = -1;
|
||||
int at = pentagon[0];
|
||||
for(int d=0; d<5; d++) {
|
||||
for(int s: pentagon) if(inedge[at][s] && s != illegal) {
|
||||
hyperpoint m = vertices120[root] + vertices120[ot] + vertices120[at] + vertices120[s];
|
||||
m = mid(m, m);
|
||||
println(hlog, id, ": ", m);
|
||||
dodefaces[id++] = m;
|
||||
illegal = at;
|
||||
at = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("id = %d\n", id);
|
||||
}
|
||||
|
||||
bool goodside(int i) {
|
||||
if(!elliptic) return true;
|
||||
hyperpoint& h = vertices120[i];
|
||||
for(int k=3; k>=0; k--) {
|
||||
if(h[k] > 1e-3) return true;
|
||||
if(h[k] < -1e-3) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct hrmap_spherical3 : hrmap {
|
||||
heptagon* cells[120];
|
||||
|
||||
hrmap_spherical3() {
|
||||
gen600();
|
||||
for(int i=0; i<120; i++) {
|
||||
if(!goodside(i)) {
|
||||
cells[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
cells[i] = tailored_alloc<heptagon> (12);
|
||||
heptagon& h = *(cells[i]);
|
||||
h.s = hsOrigin;
|
||||
h.emeraldval = i;
|
||||
h.zebraval = i;
|
||||
h.fiftyval = i;
|
||||
h.rval0 = h.rval1 = 0;
|
||||
h.alt = NULL;
|
||||
h.cdata = NULL;
|
||||
h.c.fullclear();
|
||||
h.fieldval = i;
|
||||
h.c7 = newCell(12, &h);
|
||||
}
|
||||
|
||||
for(int i=0; i<120; i++) if(cells[i]) {
|
||||
for(int k=0; k<12; k++) {
|
||||
hyperpoint which = vmatrix120[i] * inverse(vmatrix120[root]) * vertices120[adj0[k]];
|
||||
for(int s=0; s<120; s++) if(hdist(which, vertices120[s]) < 1e-6) {
|
||||
int s1 = s;
|
||||
if(!cells[s1]) continue;
|
||||
cells[i]->move(k) = cells[s1];
|
||||
println(hlog, i,".",k, " -> ", s1, " ; ", js[i], " distance = ", hdist(vertices120[i], vertices120[s]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<120; i++)
|
||||
for(int k=0; k<12; k++)
|
||||
for(int l=0; l<12; l++)
|
||||
if(cells[i] && cells[i]->move(k)->move(l) == cells[i])
|
||||
cells[i]->c.setspin(k, l, false);
|
||||
}
|
||||
|
||||
heptagon *getOrigin() { return cells[root]; }
|
||||
|
||||
~hrmap_spherical3() {
|
||||
for(int i=0; i<120; i++) if(cells[i]) tailored_delete(cells[i]);
|
||||
}
|
||||
};
|
||||
|
||||
transmatrix gmatr(heptagon *h) {
|
||||
return vmatrix120[h->zebraval] * inverse(vmatrix120[root]);
|
||||
}
|
||||
|
||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||
return inverse(gmatr(h1)) * gmatr(h2);
|
||||
}
|
||||
|
||||
bool pseudohept(cell *c) {
|
||||
return c->master->zebraval < 16;
|
||||
}
|
||||
|
||||
void draw() {
|
||||
sphereflip = Id;
|
||||
auto m = (hrmap_spherical3*) currentmap;
|
||||
|
||||
for(int i=0; i<120; i++) if(m->cells[i])
|
||||
drawcell(m->cells[i]->c7, View * relative_matrix(m->cells[i], viewctr.at), 0, false);
|
||||
}
|
||||
|
||||
void makewax(int x) {
|
||||
int waxcenter = 63;
|
||||
auto m = (hrmap_spherical3*) currentmap;
|
||||
for(int i=0; i<120; i++) if(m->cells[i]) m->cells[i]->c7->wall = waNone;
|
||||
m->cells[waxcenter]->c7->wall = waDune;
|
||||
int cols[16] = {0x202020, 0x2020A0, 0x20A020, 0x20A0A0, 0xA02020, 0xA020A0, 0xA0A020, 0xA0A0A0,
|
||||
0x606060, 0x6060FF, 0x60FF60, 0x60FFFF, 0xFF6060, 0xFF60FF, 0xFFFF60, 0xFFFFFF };
|
||||
if(x) for(int i=0; i<12; i++) {
|
||||
m->cells[waxcenter]->c7->move(i)->wall = waWaxWall;
|
||||
m->cells[waxcenter]->c7->move(i)->landparam = cols[i];
|
||||
}
|
||||
}
|
||||
|
||||
#if CAP_COMMANDLINE
|
||||
int readArgs() {
|
||||
using namespace arg;
|
||||
|
||||
if(argis("-wax1")) {
|
||||
PHASE(3);
|
||||
start_game();
|
||||
makewax(1);
|
||||
}
|
||||
else if(argis("-wax0")) {
|
||||
PHASE(3);
|
||||
start_game();
|
||||
makewax(0);
|
||||
}
|
||||
else return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto hook =
|
||||
addHook(hooks_args, 100, readArgs);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user