From cb8e34204fcde935bfcff675fbff1b280c7ca795 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 1 Mar 2019 18:53:20 +0100 Subject: [PATCH] two more Euclidean honeycombs; also split buildpolys into subfunctions --- classes.cpp | 2 + classes.h | 3 +- config.cpp | 2 + euclid.cpp | 89 ++++++++++++-- geom-exp.cpp | 2 +- graph.cpp | 8 +- hyper.h | 2 +- polygons.cpp | 326 ++++++++++++++++++++++++++++++--------------------- system.cpp | 2 +- 9 files changed, 284 insertions(+), 152 deletions(-) diff --git a/classes.cpp b/classes.cpp index 411c21d8..f6f36d73 100644 --- a/classes.cpp +++ b/classes.cpp @@ -1774,6 +1774,8 @@ vector ginf = { {"cube", "none", "3D cube tiling", "cube", 6, 4, 0, gcEuclid, 0x30200, {{7, 5}}, eVariation::pure}, {"120c", "none", "120-cell", "120c", 12, 4, qsSMALLB, gcSphere, 0x30400, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, {"e120c", "elliptic", "120-cell (elliptic space)", "e120c", 12, 4, qsSMALLBE, gcSphere, 0x30600, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, + {"rhombic","none", "rhombic dodecahedral honeycomb", "rhombic", 12, 4, 0, gcEuclid, 0x31000, {{7, 5}}, eVariation::pure}, + {"bitrunc","none", "bitruncated cubic honeycomb", "bitrunc", 14, 3, 0, gcEuclid, 0x31200, {{7, 5}}, eVariation::pure}, }; // bits: 9, 10, 15, 16, (reserved for later) 17, 18 diff --git a/classes.h b/classes.h index 24430db5..d54e8841 100644 --- a/classes.h +++ b/classes.h @@ -214,7 +214,8 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle enum eGeometry { gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic, gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean, - gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling, gCell120, gECell120, + gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, + gBinary3, gCubeTiling, gCell120, gECell120, gRhombic3, gBitrunc3, gGUARD}; enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; diff --git a/config.cpp b/config.cpp index 8638d492..afa4a385 100644 --- a/config.cpp +++ b/config.cpp @@ -366,6 +366,8 @@ void initConfig() { addsaver(sightranges[gCubeTiling], "sight-cubes", 7); addsaver(sightranges[gCell120], "sight-120cell", 2 * M_PI); addsaver(sightranges[gECell120], "sight-120cell-elliptic", M_PI); + addsaver(sightranges[gRhombic3], "sight-rhombic", 5.5); + addsaver(sightranges[gBitrunc3], "sight-bitrunc", 4.5); addsaver(smooth_scrolling, "smooth-scrolling", false); addsaver(mouseaim_sensitivity, "mouseaim_sensitivity", 0.01); diff --git a/euclid.cpp b/euclid.cpp index 40b78814..ee6f1fef 100644 --- a/euclid.cpp +++ b/euclid.cpp @@ -475,10 +475,47 @@ namespace euclid3 { int getcoord(coord x, int a); + vector get_shifttable() { + static const coord D0 = 1; + static const coord D1 = COORDMAX; + static const coord D2 = COORDMAX * COORDMAX; + vector shifttable; + vector tmatrix; + switch(geometry) { + case gCubeTiling: + shifttable = { +D0, +D1, +D2 }; + break; + + case gRhombic3: + shifttable = { D0+D1, D0+D2, D1+D2, D1-D2, D0-D2, D0-D1 }; + break; + + case gBitrunc3: + shifttable = { 2*D0, 2*D1, 2*D2, D0+D1+D2, D0+D1-D2, D0-D1-D2, D0-D1+D2 }; + break; + + default: + printf("euclid3::get_shifttable() called in geometry that is not euclid3"); + exit(1); + } + + // reverse everything + int s = isize(shifttable); + for(int i=0; i shifttable; + vector tmatrix; map spacemap; map ispacemap; hrmap_euclid3() { + shifttable = get_shifttable(); + tmatrix.resize(S7); + for(int i=0; i (6); - h->c7 = newCell(6, h); + auto h = tailored_alloc (S7); + h->c7 = newCell(S7, h); h->distance = 0; h->cdata = NULL; - h->zebraval = gmod(getcoord(at, 0) + getcoord(at, 1) * 2 + getcoord(at, 2) * 4, 5); + if(S7 != 14) + h->zebraval = gmod(getcoord(at, 0) + getcoord(at, 1) * 2 + getcoord(at, 2) * 4, 5); + else + h->zebraval = getcoord(at, 0) & 1; spacemap[at] = h; ispacemap[h] = at; return h; @@ -502,14 +542,12 @@ namespace euclid3 { heptagon *build(heptagon *parent, int d, coord at) { auto h = get_at(at); - h->c.connect((d+3)%6, parent, d, false); + h->c.connect((d+S7/2)%S7, parent, d, false); return h; } heptagon *createStep(heptagon *parent, int d) { - coord at = ispacemap[parent]; - const coord shifttable[6] = { +1, +COORDMAX, +COORDMAX*COORDMAX, -1, -COORDMAX, -COORDMAX*COORDMAX }; - return build(parent, d, at + shifttable[d]); + return build(parent, d, ispacemap[parent] + shifttable[d]); } }; @@ -541,27 +579,30 @@ namespace euclid3 { int dist_alt(cell *c) { coord co = cubemap()->ispacemap[c->master]; - return getcoord(co, 2); + if(S7 == 6) return getcoord(co, 2); + else if(S7 == 12) return (getcoord(co, 0) + getcoord(co, 1) + getcoord(co, 2)) / 2; + else return getcoord(co, 2)/2; } void draw() { dq::visited.clear(); dq::enqueue(viewctr.at, cview()); + auto cm = cubemap(); while(!dq::drawqueue.empty()) { auto& p = dq::drawqueue.front(); heptagon *h = get<0>(p); - transmatrix V = get<1>(p); + transmatrix V = get<1>(p); dynamicval b(band_shift, get<2>(p)); bandfixer bf(V); dq::drawqueue.pop(); - + cell *c = h->c7; if(!do_draw(c, V)) continue; drawcell(c, V, 0, false); - for(int i=0; i<6; i++) - dq::enqueue(h->move(i), V * cpush(i%3, (i>=3) ? -1 : 1)); + for(int i=0; imove(i), V * cm->tmatrix[i]); } } @@ -574,7 +615,29 @@ namespace euclid3 { int celldistance(cell *c1, cell *c2) { auto cm = cubemap(); coord a = cm->ispacemap[c1->master] - cm->ispacemap[c2->master]; - return abs(getcoord(a, 0)) + abs(getcoord(a, 1)) + abs(getcoord(a, 2)); + if(S7 == 6) + return abs(getcoord(a, 0)) + abs(getcoord(a, 1)) + abs(getcoord(a, 2)); + else { + vector ar = { getcoord(a,0), getcoord(a,1), getcoord(a,2) }; + for(int i=0; i<3; i++) ar[i] = abs(ar[i]); + sort(ar.begin(), ar.end()); + int dist = 0; + if(S7 == 12) { + int d = ar[1] - ar[0]; ar[1] -= d; ar[2] -= d; + dist += d; + int m = min((ar[2] - ar[0]) / 2, ar[0]); + dist += 2 * d; + ar[0] -= m; ar[1] -= m; ar[2] -= m; + if(ar[0]) + dist += (ar[0] + ar[1] + ar[2]) / 2; + else + dist += ar[2]; + } + else { + dist = ar[0] + (ar[1] - ar[0]) / 2 + (ar[2] - ar[0]) / 2; + } + return dist; + } } } diff --git a/geom-exp.cpp b/geom-exp.cpp index 3997a464..35933182 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -383,7 +383,7 @@ vector quotientlist = { }; vector list3d = { - gBinary3, gCubeTiling, gCell120, gECell120 + gBinary3, gCubeTiling, gRhombic3, gBitrunc3, gCell120, gECell120 }; void ge_select_tiling(const vector& lst) { diff --git a/graph.cpp b/graph.cpp index d9fafa32..384c0d9c 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3842,9 +3842,13 @@ bool isWall3(cell *c, color_t& wcol) { int get_darkval(int d) { const int darkval_h[9] = {0,2,2,0,6,6,8,8,0}; const int darkval_s[12] = {0,1,2,3,4,5,0,1,2,3,4,5}; - const int darkval_e[6] = {0,4,6,0,4,6}; + const int darkval_e6[6] = {0,4,6,0,4,6}; + const int darkval_e12[12] = {0,4,6,0,4,6,0,4,6,0,4,6}; + const int darkval_e14[14] = {0,0,0,4,6,4,6,0,0,0,6,4,6,4}; if(sphere) return darkval_s[d]; - if(euclid) return darkval_e[d]; + if(euclid && S7 == 6) return darkval_e6[d]; + if(euclid && S7 == 12) return darkval_e12[d]; + if(euclid && S7 == 14) return darkval_e14[d]; return darkval_h[d]; } diff --git a/hyper.h b/hyper.h index a1e6290a..0d037774 100644 --- a/hyper.h +++ b/hyper.h @@ -185,7 +185,7 @@ typedef complex cld; #if MAXMDIM == 3 #define DIM 2 #else -#define DIM ((geometry == gBinary3 || geometry == gCubeTiling || geometry == gCell120 || geometry == gECell120) ? 3 : 2) +#define DIM ((geometry >= gBinary3) ? 3 : 2) #endif #define MDIM (DIM+1) diff --git a/polygons.cpp b/polygons.cpp index 6f09ffa5..7cc23b1b 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1945,85 +1945,7 @@ ld dlow_table[SIDEPARS], dhi_table[SIDEPARS]; #define SHADMUL (S3==4 ? 1.05 : 1.3) -#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) { - hyperpoint h0 = point3(x0,y0,z0); - hyperpoint h1 = point3(x1,y1,z1); - hyperpoint h2 = point3(x2,y2,z2); - using namespace hyperpoint_vec; - hyperpoint h3 = h1 + h2 - h0; - bshape(sh, PPR::WALL); - ld yy = log(2) / 2; - const int STEP=10; - auto at = [&] (hyperpoint h) { - hyperpoint res = binary::parabolic3(h[0], h[1]) * xpush0(yy*h[2]); - hpcpush(res); - }; - if(flags == 2) { - last->flags |= POLY_TRIANGLES; - for(int y=0; ys]); } - // hand-drawn shapes + bshape(shSwitchDisk, PPR::FLOOR); for(int i=0; i<=S84; i+=S3) hpcpush(ddi(i, .06) * C0); + } + +#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) { + hyperpoint h0 = point3(x0,y0,z0); + hyperpoint h1 = point3(x1,y1,z1); + hyperpoint h2 = point3(x2,y2,z2); + using namespace hyperpoint_vec; + hyperpoint h3 = h1 + h2 - h0; + bshape(sh, PPR::WALL); + ld yy = log(2) / 2; + const int STEP=10; + auto at = [&] (hyperpoint h) { + hyperpoint res = binary::parabolic3(h[0], h[1]) * xpush0(yy*h[2]); + hpcpush(res); + }; + if(flags == 2) { + last->flags |= POLY_TRIANGLES; + for(int y=0; y=3) ? -1 : 1; + t[1] = among(a, 0, 3, 4) ? -1 : 1; + t[2] = among(a, 2, 3) ? -1 : 1; + int x = w%3; + int y = (x+2)%3; + int z = (y+2)%3; + hpcpush(hpxy3(t[x]/2., t[y]/2., t[z]/2.)); + } + } + } + + if(DIM == 3 && euclid && S7 == 12) { + using namespace hyperpoint_vec; + auto v = euclid3::get_shifttable(); + for(int w=0; w<12; w++) { + vector valid; + for(int c=0; c<3; c++) if(euclid3::getcoord(v[w], c)) valid.push_back(c); + int third = 3 - valid[1] - valid[0]; + bshape(shWall3D[w], PPR::WALL); + hyperpoint v0 = cpush0(valid[0], euclid3::getcoord(v[w], valid[0]) > 0 ? 1 : -1); + hyperpoint v1 = cpush0(valid[1], euclid3::getcoord(v[w], valid[1]) > 0 ? 1 : -1); + hpcpush(v0); + hpcpush(v0/2 + v1/2 + cpush0(third, .5) - C0); + hpcpush(v1); + hpcpush(v0/2 + v1/2 + cpush0(third, -.5) - C0); + hpcpush(v0); + } + } + + if(DIM == 3 && euclid && S7 == 14) { + using namespace hyperpoint_vec; + auto v = euclid3::get_shifttable(); + for(int w=0; w<14; w++) { + bshape(shWall3D[w], PPR::WALL); + if(w%7 < 3) { + int z = w>=7?-1:1; + hpcpush(cpush0(w%7, z) + cpush0((w%7+1)%3, 1/2.) - C0); + hpcpush(cpush0(w%7, z) + cpush0((w%7+2)%3, 1/2.) - C0); + hpcpush(cpush0(w%7, z) + cpush0((w%7+1)%3,-1/2.) - C0); + hpcpush(cpush0(w%7, z) + cpush0((w%7+2)%3,-1/2.) - C0); + hpcpush(cpush0(w%7, z) + cpush0((w%7+1)%3, 1/2.) - C0); + } + else { + ld x = euclid3::getcoord(v[w], 0), y = euclid3::getcoord(v[w], 1), z = euclid3::getcoord(v[w], 2); + hpcpush(hpxy3(x, y/2, 0)); + hpcpush(hpxy3(x/2, y, 0)); + hpcpush(hpxy3(0, y, z/2)); + hpcpush(hpxy3(0, y/2, z)); + hpcpush(hpxy3(x/2, 0, z)); + hpcpush(hpxy3(x, 0, z/2)); + hpcpush(hpxy3(x, y/2, 0)); + } + } + } + + if(DIM == 3 && sphere) { + sphere3::gen600(); + for(int w=0; w<12; w++) { + bshape(shWall3D[w], PPR::WALL); + for(int a=0; a<=5; a++) + hpcpush(sphere3::dodefaces[w*5+a%5]); + } + } + + if(DIM == 3) { + shMiniWall3D.resize(isize(shWall3D)); + for(int i=0; iflags |= POLY_TRIANGLES; + } + } + } +#endif + +void configure_floorshapes() { if(0); #if CAP_ARCM else if(archimedean) @@ -2418,7 +2487,50 @@ void buildpolys() { shMFloor3.prio = PPR::FLOOR_DRAGON; shMFloor4.prio = PPR::FLOOR_DRAGON; for(int i=0; i<3; i++) shRedRockFloor[i].scale = .9 - .1 * i; - generate_floorshapes(); + generate_floorshapes(); + } + +void buildpolys() { + + symmetriesAt.clear(); + allshapes.clear(); + geom3::compute(); + #if CAP_GP + gp::clear_plainshapes(); + #endif + DEBB(DF_INIT, (debugfile,"buildpolys\n")); + + if(DIM == 3) { + if(sphere) SD3 = 3, SD7 = 5; + else SD3 = SD7 = 4; + } + else { + SD3 = S3; + SD7 = S7; + } + SD6 = SD3 * 2; + S42 = SD7 * SD6; + S12 = SD6 * 2; + S14 = SD7 * 2; + S21 = SD7 * SD3; + S28 = SD7 * 4; + S36 = SD6 * 6; + S84 = S42 * 2; + + // printf("crossf = %f euclid = %d sphere = %d\n", float(crossf), euclid, sphere); + hpc.clear(); + + make_sidewalls(); + + procedural_shapes(); + + #if MAXMDIM >= 4 + create_wall3d(); + #endif + + configure_floorshapes(); + + // hand-drawn shapes bshape(shHalfFloor[0], PPR::FLOOR, scalefactor, 329); bshape(shHalfFloor[1], PPR::FLOOR, scalefactor, 327); @@ -2449,8 +2561,6 @@ void buildpolys() { bshape(shSemiFeatherFloor[0], PPR::FLOOR, scalefactor, 48); bshape(shSemiFeatherFloor[1], PPR::FLOOR, scalefactor, 49); - bshape(shSwitchDisk, PPR::FLOOR); for(int i=0; i<=S84; i+=S3) hpcpush(ddi(i, .06) * C0); - bshape(shZebra[0], PPR::FLOOR, scalefactor, 162); bshape(shZebra[1], PPR::FLOOR, scalefactor, 163); bshape(shZebra[2], PPR::FLOOR, scalefactor, 164); @@ -2521,56 +2631,6 @@ void buildpolys() { bshape(shDragonNostril, PPR::ONTENTACLE_EYES, scalefactor, 241); bshape(shDragonHead, PPR::ONTENTACLE, scalefactor, 242); - if(DIM == 3 && binarytiling) { - shWall3D.resize(9); - 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); - make_wall(shWall3D[3], 0,0,-1, +1,0,-1, 0,+1,-1, 2); - make_wall(shWall3D[4], -1,-1,-1, -1,1,-1, -1,-1,+1, 1); - make_wall(shWall3D[5], +1,-1,-1, +1,1,-1, +1,-1,+1, 1); - make_wall(shWall3D[6], -1,-1,-1, 1,-1,-1, -1,-1,+1, 1); - 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 && euclid) { - shWall3D.resize(6); - for(int w=0; w<6; w++) { - bshape(shWall3D[w], PPR::WALL); - for(int a=0; a<=4; a++) { - int t[3]; - t[0] = (w>=3) ? -1 : 1; - t[1] = among(a, 0, 3, 4) ? -1 : 1; - t[2] = among(a, 2, 3) ? -1 : 1; - int x = w%3; - int y = (x+2)%3; - int z = (y+2)%3; - hpcpush(hpxy3(t[x]/2., t[y]/2., t[z]/2.)); - } - } - } - - if(DIM == 3 && sphere) { - shWall3D.resize(12); - for(int w=0; w<12; w++) { - bshape(shWall3D[w], PPR::WALL); - for(int a=0; a<=5; a++) - hpcpush(sphere3::dodefaces[w*5+a%5]); - } - } - - if(DIM == 3) { - shMiniWall3D.resize(isize(shWall3D)); - for(int i=0; iflags |= POLY_TRIANGLES; - } - } - ld krsc = 1; if(sphere) krsc *= 1.4; if(S7 ==8) krsc *= 1.3; diff --git a/system.cpp b/system.cpp index 75199b9d..43f63f3e 100644 --- a/system.cpp +++ b/system.cpp @@ -1194,7 +1194,7 @@ void set_geometry(eGeometry target) { if(DUAL && geometry != gArchimedean) variation = ginf[geometry].default_variation; #if CAP_BT - if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling, gCell120, gECell120)) variation = eVariation::pure; + if(geometry == gBinaryTiling || DIM == 3) variation = eVariation::pure; #endif need_reset_geometry = true;