3d:: HoroTris geometry

This commit is contained in:
Zeno Rogue 2019-03-06 16:31:10 +01:00
parent 9efa497b66
commit 105de56857
7 changed files with 88 additions and 33 deletions

View File

@ -100,7 +100,7 @@ namespace binary {
int side = 0;
if(d < 4) side = (parent->zebraval * 2 + d) % 5;
if(d == 8) side = ((parent->zebraval-d1) * 3) % 5;
return build(parent, d, d1, 9, side, delta);
return build(parent, d, d1, S7, side, delta);
}
#endif
@ -161,6 +161,7 @@ namespace binary {
#if MAXMDIM==4
heptagon *createStep3(heptagon *parent, int d) {
auto h = parent;
if(geometry == gBinary3)
switch(d) {
case 0: case 1:
case 2: case 3:
@ -192,6 +193,18 @@ namespace binary {
else
return path(h, 7, 6, {8, 7, parent->c.spin(8) ^ 2});
}
if(geometry == gHoroTris) switch(d) {
case 0: case 1: case 2: case 3:
return build3(parent, d, 7, 1);
case 7:
return build3(parent, 7, hrand(3), -1);
case 4: case 5: case 6:
parent->cmove(7);
int s = parent->c.spin(7);
if(s == 0) return path(h, d, d, {7, d-3});
else if(s == d-3) return path(h, d, d, {7, 0});
else return path(h, d, d, {7, d, 9-d-s});
}
printf("error: case not handled in binary tiling\n");
breakhere();
return NULL;
@ -202,31 +215,43 @@ namespace binary {
transmatrix inverse_tmatrix[8];
void build_tmatrix() {
direct_tmatrix[0] = xpush(-log(2)) * parabolic3(-1, -1);
direct_tmatrix[1] = xpush(-log(2)) * parabolic3(1, -1);
direct_tmatrix[2] = xpush(-log(2)) * parabolic3(-1, 1);
direct_tmatrix[3] = xpush(-log(2)) * parabolic3(1, 1);
direct_tmatrix[4] = parabolic3(-2, 0);
direct_tmatrix[5] = parabolic3(+2, 0);
direct_tmatrix[6] = parabolic3(0, -2);
direct_tmatrix[7] = parabolic3(0, +2);
for(int i=0; i<8; i++)
if(geometry == gBinary3) {
direct_tmatrix[0] = xpush(-log(2)) * parabolic3(-1, -1);
direct_tmatrix[1] = xpush(-log(2)) * parabolic3(1, -1);
direct_tmatrix[2] = xpush(-log(2)) * parabolic3(-1, 1);
direct_tmatrix[3] = xpush(-log(2)) * parabolic3(1, 1);
direct_tmatrix[4] = parabolic3(-2, 0);
direct_tmatrix[5] = parabolic3(+2, 0);
direct_tmatrix[6] = parabolic3(0, -2);
direct_tmatrix[7] = parabolic3(0, +2);
}
if(geometry == gHoroTris) {
ld r3 = sqrt(3);
direct_tmatrix[0] = xpush(-log(2)) * cspin(1,2, M_PI);
direct_tmatrix[1] = parabolic3(0, +r3/3) * xpush(-log(2));
direct_tmatrix[2] = parabolic3(-0.5, -r3/6) * xpush(-log(2));
direct_tmatrix[3] = parabolic3(+0.5, -r3/6) * xpush(-log(2));
direct_tmatrix[4] = parabolic3(0, -r3*2/3) * cspin(1,2, M_PI);
direct_tmatrix[5] = parabolic3(1, r3/3) * cspin(1,2,M_PI);
direct_tmatrix[6] = parabolic3(-1, r3/3) * cspin(1,2,M_PI);
}
for(int i=0; i<S7-1; i++)
inverse_tmatrix[i] = inverse(direct_tmatrix[i]);
}
const transmatrix& tmatrix(heptagon *h, int dir) {
if(dir == 8) {
h->cmove(8);
return inverse_tmatrix[h->c.spin(8)];
if(dir == S7-1) {
h->cmove(S7-1);
return inverse_tmatrix[h->c.spin(S7-1)];
}
else
return direct_tmatrix[dir];
}
const transmatrix& itmatrix(heptagon *h, int dir) {
if(dir == 8) {
h->cmove(8);
return h->cmove(8), direct_tmatrix[h->c.spin(8)];
if(dir == S7-1) {
h->cmove(S7-1);
return h->cmove(S7-1), direct_tmatrix[h->c.spin(S7-1)];
}
else
return inverse_tmatrix[dir];
@ -316,7 +341,7 @@ namespace binary {
}
}
else {
for(int i=0; i<9; i++)
for(int i=0; i<S7; i++)
dq::enqueue(h->move(i), V * tmatrix(h, i));
}
}
@ -329,7 +354,7 @@ namespace binary {
while(h1 != h2) {
if(h1->distance <= h2->distance) {
if(DIM == 3)
where = itmatrix(h2, 8) * where, h2 = hr::createStep(h2, 8);
where = itmatrix(h2, S7-1) * where, h2 = hr::createStep(h2, S7-1);
else {
if(type_of(h2) == 6)
h2 = hr::createStep(h2, bd_down), where = xpush(-log(2)) * where;
@ -341,7 +366,7 @@ namespace binary {
}
else {
if(DIM == 3)
gm = gm * tmatrix(h1, 8), h1 = hr::createStep(h1, 8);
gm = gm * tmatrix(h1, S7-1), h1 = hr::createStep(h1, S7-1);
else {
if(type_of(h1) == 6)
h1 = hr::createStep(h1, bd_down), gm = gm * xpush(log(2));
@ -377,14 +402,14 @@ int celldistance3(heptagon *c1, heptagon *c2) {
int steps = 0;
int d1 = c1->distance;
int d2 = c2->distance;
while(d1 > d2) c1 = c1->cmove(8), steps++, d1--;
while(d2 > d1) c2 = c2->cmove(8), steps++, d2--;
while(d1 > d2) c1 = c1->cmove(S7-1), steps++, d1--;
while(d2 > d1) c2 = c2->cmove(S7-1), steps++, d2--;
vector<int> dx, dy;
while(c1 != c2) {
dx.push_back((c1->c.spin(8) & 1) - (c2->c.spin(8) & 1));
dy.push_back((c1->c.spin(8) >> 1) - (c2->c.spin(8) >> 1));
c1 = c1->cmove(8);
c2 = c2->cmove(8);
dx.push_back((c1->c.spin(S7-1) & 1) - (c2->c.spin(S7-1) & 1));
dy.push_back((c1->c.spin(S7-1) >> 1) - (c2->c.spin(S7-1) >> 1));
c1 = c1->cmove(S7-1);
c2 = c2->cmove(S7-1);
steps += 2;
}
int xsteps = steps, sx = 0, sy = 0;

View File

@ -73,7 +73,7 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
binary::rxcode[1<<16] = &h;
#endif
h.zebraval = 0,
h.c7 = newCell(DIM == 3 ? 9 : 6, origin);
h.c7 = newCell(DIM == 3 ? S7 : 6, origin);
}
#endif
#if CAP_IRR

View File

@ -1787,7 +1787,8 @@ vector<geometryinfo> ginf = {
{"{3,4,3}","elliptic","{3,4,3} 24-cell (elliptic)", "e343", 8, 3, qsSMALLBE, gcSphere, 0x39600, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,5}","none", "{3,3,5} 600-cell", "335", 4, 3, qsSMALLB, gcSphere, 0x30800, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,5}","elliptic","{3,3,5} 600-cell (elliptic)", "e335", 4, 3, qsSMALLBE, gcSphere, 0x31800, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
};
{"h{3,6}", "none", "{3,6} on horospheres", "h{3,6}", 8, 3, 0, gcHyperbolic, 0x40000, {{7, 3}}, eVariation::pure},
};
// bits: 9, 10, 15, 16, (reserved for later) 17, 18

View File

@ -222,6 +222,7 @@ enum eGeometry {
gCell16, gECell16,
gCell24, gECell24,
gCell600, gECell600,
gHoroTris,
gGUARD};
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };

View File

@ -380,6 +380,7 @@ void initConfig() {
addsaver(sightranges[gECell24], "sight-24cell-elliptic", M_PI);
addsaver(sightranges[gCell600], "sight-600cell", 2 * M_PI);
addsaver(sightranges[gECell600], "sight-600cell-elliptic", M_PI);
addsaver(sightranges[gHoroTris], "sight-horotris", 3);
addsaver(smooth_scrolling, "smooth-scrolling", false);
addsaver(mouseaim_sensitivity, "mouseaim_sensitivity", 0.01);

View File

@ -94,7 +94,7 @@ void addMessage(string s, char spamtype = 0);
#define weirdhyperbolic ((S7 > 7 || S3 > 3 || !STDVAR || binarytiling || archimedean) && hyperbolic)
#define stdhyperbolic (S7 == 7 && S3 == 3 && STDVAR && !binarytiling && !archimedean)
#define binarytiling (geometry == gBinaryTiling || geometry == gBinary3)
#define binarytiling (geometry == gBinaryTiling || geometry == gBinary3 || geometry == gHoroTris)
#define archimedean (geometry == gArchimedean)
#define eubinary (euclid || binarytiling || geometry == gCrystal || (DIM == 3 && hyperbolic))

View File

@ -2308,7 +2308,12 @@ void procedural_shapes() {
}
#if CAP_BT && MAXMDIM >= 4
void make_wall(hpcshape& sh, int x0, int y0, int z0, int x1, int y1, int z1, int x2, int y2, int z2, int flags) {
// Make a wall for horocycle-based honeycombs
// flags:
// 1 = first edge should be doubled
// 2 = use POLY_TRIANGLES
// 4 = this is is a triangular face; otherwise, the face is rectangular, and x1+x2-x0 is the fourth vertex
void make_wall(hpcshape& sh, ld x0, ld y0, ld z0, ld x1, ld y1, ld z1, ld x2, ld y2, ld z2, int flags) {
hyperpoint h0 = point3(x0,y0,z0);
hyperpoint h1 = point3(x1,y1,z1);
hyperpoint h2 = point3(x2,y2,z2);
@ -2321,15 +2326,17 @@ void make_wall(hpcshape& sh, int x0, int y0, int z0, int x1, int y1, int z1, int
hyperpoint res = binary::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
hpcpush(res);
};
if(flags == 2) {
if(flags & 2) {
last->flags |= POLY_TRIANGLES;
for(int y=0; y<STEP; y++)
for(int x=0; x<STEP; x++) {
int x1 = x + 1;
int y1 = y + 1;
if((flags & 4) && x+y >= STEP) continue;
at((h0 * (STEP-x -y ) + h1 * x + h2 * y ) / STEP);
at((h0 * (STEP-x1-y ) + h1 * x1 + h2 * y ) / STEP);
at((h0 * (STEP-x -y1) + h1 * x + h2 * y1) / STEP);
if((flags & 4) && x+y >= STEP-1) continue;
at((h0 * (STEP-x1-y ) + h1 * x1 + h2 * y ) / STEP);
at((h0 * (STEP-x -y1) + h1 * x + h2 * y1) / STEP);
at((h0 * (STEP-x1-y1) + h1 * x1 + h2 * y1) / STEP);
@ -2338,8 +2345,13 @@ void make_wall(hpcshape& sh, int x0, int y0, int z0, int x1, int y1, int z1, int
else {
int STP2 = ((flags == 1) ? 2 : 1) * STEP;
for(int t=0; t<STP2; t++) at((h0 * (STP2-t) + h1 * t) / STP2);
for(int t=0; t<STEP; t++) at((h1 * (STEP-t) + h3 * t) / STEP);
for(int t=0; t<STEP; t++) at((h3 * (STEP-t) + h2 * t) / STEP);
if(flags&4) {
for(int t=0; t<STEP; t++) at((h1 * (STEP-t) + h2 * t) / STEP);
}
else {
for(int t=0; t<STEP; t++) at((h1 * (STEP-t) + h3 * t) / STEP);
for(int t=0; t<STEP; t++) at((h3 * (STEP-t) + h2 * t) / STEP);
}
for(int t=0; t<STEP; t++) at((h2 * (STEP-t) + h0 * t) / STEP);
at(h0);
}
@ -2347,7 +2359,7 @@ void make_wall(hpcshape& sh, int x0, int y0, int z0, int x1, int y1, int z1, int
void create_wall3d() {
shWall3D.resize(S7);
if(DIM == 3 && binarytiling) {
if(DIM == 3 && binarytiling && geometry == gBinary3) {
make_wall(shWall3D[0], 0,0,-1, -1,0,-1, 0,-1,-1, 2);
make_wall(shWall3D[1], 0,0,-1, +1,0,-1, 0,-1,-1, 2);
make_wall(shWall3D[2], 0,0,-1, -1,0,-1, 0,+1,-1, 2);
@ -2358,6 +2370,21 @@ void create_wall3d() {
make_wall(shWall3D[7], -1,+1,-1, 1,+1,-1, -1,+1,+1, 1);
make_wall(shWall3D[8], 1,1,+1, -1,1,+1, 1,-1,+1, 0);
}
if(DIM == 3 && binarytiling && geometry == gHoroTris) {
ld r = sqrt(3)/6;
ld r1 = r;
ld r2 = r * 2;
ld r4 = r * 4;
make_wall(shWall3D[0], 0,-r2,-1, +.5, r1,-1,-.5, r1,-1, 2|4);
make_wall(shWall3D[1], 0, r4,-1, +.5, r1,-1,-.5, r1,-1, 2|4);
make_wall(shWall3D[2], 0,-r2,-1, -1,-r2,-1,-.5, r1,-1, 2|4);
make_wall(shWall3D[3], 0,-r2,-1, +.5, r1,-1, +1,-r2,-1, 2|4);
make_wall(shWall3D[4],-1,-r2,-1, 1,-r2,-1, -1,-r2, 1, 1);
make_wall(shWall3D[5], 1,-r2,-1, 0, r4,-1, 1,-r2, 1, 1);
make_wall(shWall3D[6],-1,-r2,-1, 0, r4,-1, -1,-r2, 1, 1);
make_wall(shWall3D[7], 1,-r2, 1, 0, r4, 1, -1,-r2, 1, 4);
}
if(DIM == 3 && euclid && S7 == 6) {
for(int w=0; w<6; w++) {