mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
3D:: 120-cell
This commit is contained in:
parent
1fcf58e17a
commit
33d4854c14
1
cell.cpp
1
cell.cpp
@ -232,6 +232,7 @@ void initcells() {
|
|||||||
else if(fulltorus) currentmap = new hrmap_torus;
|
else if(fulltorus) currentmap = new hrmap_torus;
|
||||||
else if(euclid && DIM == 3) currentmap = euclid3::new_map();
|
else if(euclid && DIM == 3) currentmap = euclid3::new_map();
|
||||||
else if(euclid) currentmap = new hrmap_euclidean;
|
else if(euclid) currentmap = new hrmap_euclidean;
|
||||||
|
else if(sphere && DIM == 3) currentmap = new sphere3::hrmap_spherical3;
|
||||||
else if(sphere) currentmap = new hrmap_spherical;
|
else if(sphere) currentmap = new hrmap_spherical;
|
||||||
else if(quotient) currentmap = new quotientspace::hrmap_quotient;
|
else if(quotient) currentmap = new quotientspace::hrmap_quotient;
|
||||||
else currentmap = new hrmap_hyperbolic;
|
else currentmap = new hrmap_hyperbolic;
|
||||||
|
@ -1767,6 +1767,7 @@ vector<geometryinfo> ginf = {
|
|||||||
{"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, gcSphere, 0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
{"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, gcSphere, 0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
||||||
{"bin3", "none", "3D binary tiling", "binary3", 9, 4, 0, gcHyperbolic, 0, {{7, 3}}, eVariation::pure},
|
{"bin3", "none", "3D binary tiling", "binary3", 9, 4, 0, gcHyperbolic, 0, {{7, 3}}, eVariation::pure},
|
||||||
{"cube", "none", "3D cube tiling", "cube", 6, 4, 0, gcEuclid, 0, {{7, 5}}, eVariation::pure},
|
{"cube", "none", "3D cube tiling", "cube", 6, 4, 0, gcEuclid, 0, {{7, 5}}, eVariation::pure},
|
||||||
|
{"120c", "none", "120-cell", "120c", 12, 4, qsSMALLB, gcSphere, 0, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
||||||
};
|
};
|
||||||
|
|
||||||
// remember to match the following mask when specifying codes for extra geometries: 0x78600
|
// remember to match the following mask when specifying codes for extra geometries: 0x78600
|
||||||
|
@ -214,7 +214,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
|
|||||||
enum eGeometry {
|
enum eGeometry {
|
||||||
gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
|
gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
|
||||||
gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,
|
gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,
|
||||||
gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling,
|
gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling, gCell120,
|
||||||
gGUARD};
|
gGUARD};
|
||||||
|
|
||||||
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };
|
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };
|
||||||
|
@ -94,6 +94,7 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
|
|||||||
#endif
|
#endif
|
||||||
#if MAXDIM == 4
|
#if MAXDIM == 4
|
||||||
if(euclid && DIM == 3) return euclid3::relative_matrix(c2->master, c1->master);
|
if(euclid && DIM == 3) return euclid3::relative_matrix(c2->master, c1->master);
|
||||||
|
if(sphere && DIM == 3) return sphere3::relative_matrix(c2->master, c1->master);
|
||||||
#endif
|
#endif
|
||||||
#if CAP_ARCM
|
#if CAP_ARCM
|
||||||
if(archimedean) return arcm::relative_matrix(c2->master, c1->master);
|
if(archimedean) return arcm::relative_matrix(c2->master, c1->master);
|
||||||
|
@ -4595,9 +4595,12 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
|
|
||||||
if(DIM == 3) {
|
if(DIM == 3) {
|
||||||
if(isWall(c)) {
|
if(isWall(c)) {
|
||||||
|
const int darkval_h[9] = {0,2,2,0,6,6,8,8,0};
|
||||||
|
const int darkval_s[12] = {0,1,2,3,0,1,2,3,0,1,2,3};
|
||||||
|
const int darkval_e[6] = {0,0,4,4,6,6};
|
||||||
|
const int *darkval = sphere ? darkval_s : hyperbolic ? darkval_h : darkval_e;
|
||||||
|
int d = (asciicol & 0xF0F0F0) >> 4;
|
||||||
|
|
||||||
const int darkval[9] = {0,1,1,0,3,3,4,4,0};
|
|
||||||
int d = (asciicol & 0xF0F0F0) >> 3;
|
|
||||||
for(int a=0; a<c->type; a++)
|
for(int a=0; a<c->type; a++)
|
||||||
if(c->move(a) && !isWall(c->move(a))) {
|
if(c->move(a) && !isWall(c->move(a))) {
|
||||||
if(a < 4 && hyperbolic) {
|
if(a < 4 && hyperbolic) {
|
||||||
@ -5712,6 +5715,8 @@ void drawthemap() {
|
|||||||
#if MAXDIM == 4
|
#if MAXDIM == 4
|
||||||
else if(euclid && DIM == 3)
|
else if(euclid && DIM == 3)
|
||||||
euclid3::draw();
|
euclid3::draw();
|
||||||
|
else if(sphere && DIM == 3)
|
||||||
|
sphere3::draw();
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
drawStandard();
|
drawStandard();
|
||||||
|
2
hyper.h
2
hyper.h
@ -192,7 +192,7 @@ typedef complex<ld> cld;
|
|||||||
#if MAXDIM == 3
|
#if MAXDIM == 3
|
||||||
#define DIM 2
|
#define DIM 2
|
||||||
#else
|
#else
|
||||||
#define DIM ((geometry == gBinary3 || geometry == gCubeTiling) ? 3 : 2)
|
#define DIM ((geometry == gBinary3 || geometry == gCubeTiling || geometry == gCell120) ? 3 : 2)
|
||||||
#endif
|
#endif
|
||||||
#define MDIM (DIM+1)
|
#define MDIM (DIM+1)
|
||||||
|
|
||||||
|
@ -731,6 +731,7 @@ transmatrix applyspin(const heptspin& hs, const transmatrix& V) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool invis_point(const hyperpoint h) {
|
bool invis_point(const hyperpoint h) {
|
||||||
|
if(DIM == 2 || sphere) return false;
|
||||||
return h[2] < 0;
|
return h[2] < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
polygons.cpp
10
polygons.cpp
@ -1615,7 +1615,7 @@ hpcshape
|
|||||||
|
|
||||||
shAsymmetric,
|
shAsymmetric,
|
||||||
|
|
||||||
shBinaryWall[9],
|
shBinaryWall[12],
|
||||||
|
|
||||||
shDodeca;
|
shDodeca;
|
||||||
#endif
|
#endif
|
||||||
@ -2464,6 +2464,14 @@ void buildpolys() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(DIM == 3 && sphere) {
|
||||||
|
for(int w=0; w<12; w++) {
|
||||||
|
bshape(shBinaryWall[w], PPR::WALL);
|
||||||
|
for(int a=0; a<=5; a++)
|
||||||
|
hpcpush(sphere3::dodefaces[w*5+a%5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ld krsc = 1;
|
ld krsc = 1;
|
||||||
if(sphere) krsc *= 1.4;
|
if(sphere) krsc *= 1.4;
|
||||||
if(S7 ==8) krsc *= 1.3;
|
if(S7 ==8) krsc *= 1.3;
|
||||||
|
192
sphere.cpp
192
sphere.cpp
@ -164,4 +164,196 @@ heptagon *getDodecahedron(int i) {
|
|||||||
return s->dodecahedron[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;
|
||||||
|
|
||||||
|
hyperpoint zero4;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
vertices120.clear();
|
||||||
|
|
||||||
|
/// 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 = {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 = {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]);
|
||||||
|
|
||||||
|
adj0.clear();
|
||||||
|
for(int i=0; i<120; i++) if(inedge[0][i]) adj0.push_back(i);
|
||||||
|
|
||||||
|
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[0] + 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hrmap_spherical3 : hrmap {
|
||||||
|
heptagon* cells[120];
|
||||||
|
|
||||||
|
hrmap_spherical3() {
|
||||||
|
gen600();
|
||||||
|
for(int i=0; i<120; i++) {
|
||||||
|
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++) {
|
||||||
|
for(int k=0; k<12; k++) {
|
||||||
|
hyperpoint which = vmatrix120[i] * inverse(vmatrix120[0]) * vertices120[adj0[k]];
|
||||||
|
for(int s=0; s<120; s++) if(hdist(which, vertices120[s]) < 1e-6) {
|
||||||
|
cells[i]->move(k) = cells[s];
|
||||||
|
println(hlog, i,".",k, " -> ", s, " ; ", js[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<120; i++)
|
||||||
|
for(int k=0; k<12; k++)
|
||||||
|
for(int l=0; l<12; l++)
|
||||||
|
if(cells[i]->move(k)->move(l) == cells[i])
|
||||||
|
cells[i]->c.setspin(k, l, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
heptagon *getOrigin() { return cells[0]; }
|
||||||
|
|
||||||
|
~hrmap_spherical3() {
|
||||||
|
for(int i=0; i<120; i++) tailored_delete(cells[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
auto m = (hrmap_spherical3*) currentmap;
|
||||||
|
|
||||||
|
int old = viewctr.at->zebraval;
|
||||||
|
|
||||||
|
for(int i=0; i<120; i++)
|
||||||
|
drawcell(m->cells[i]->c7, View * vmatrix120[0] * inverse(vmatrix120[old]) * vmatrix120[i] * inverse(vmatrix120[0]), 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
|
return vmatrix120[0] * inverse(vmatrix120[h1->zebraval]) * vmatrix120[h2->zebraval] * inverse(vmatrix120[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1194,7 +1194,7 @@ void set_geometry(eGeometry target) {
|
|||||||
if(DUAL && geometry != gArchimedean)
|
if(DUAL && geometry != gArchimedean)
|
||||||
variation = ginf[geometry].default_variation;
|
variation = ginf[geometry].default_variation;
|
||||||
#if CAP_BT
|
#if CAP_BT
|
||||||
if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling)) variation = eVariation::pure;
|
if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling, gCell120)) variation = eVariation::pure;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
need_reset_geometry = true;
|
need_reset_geometry = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user