diff --git a/binary-tiling.cpp b/binary-tiling.cpp index 63c71240..e85a270a 100644 --- a/binary-tiling.cpp +++ b/binary-tiling.cpp @@ -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; icmove(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; imove(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 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; diff --git a/cell.cpp b/cell.cpp index e0bcdbe0..f9394fe4 100644 --- a/cell.cpp +++ b/cell.cpp @@ -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 diff --git a/classes.cpp b/classes.cpp index b27c9687..83f7bb61 100644 --- a/classes.cpp +++ b/classes.cpp @@ -1787,7 +1787,8 @@ vector 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 diff --git a/classes.h b/classes.h index 6a7e31be..bcc54749 100644 --- a/classes.h +++ b/classes.h @@ -222,6 +222,7 @@ enum eGeometry { gCell16, gECell16, gCell24, gECell24, gCell600, gECell600, + gHoroTris, gGUARD}; enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; diff --git a/config.cpp b/config.cpp index d039f3c7..5f345656 100644 --- a/config.cpp +++ b/config.cpp @@ -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); diff --git a/hyper.h b/hyper.h index 3d8dc49f..b74ceb0e 100644 --- a/hyper.h +++ b/hyper.h @@ -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)) diff --git a/polygons.cpp b/polygons.cpp index 3be7e8d4..68e30b75 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -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) 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