3D:: cube tiling

This commit is contained in:
? 2019-02-24 22:12:32 +01:00 committed by Zeno Rogue
parent e8fa30de4c
commit 7110be2032
13 changed files with 161 additions and 14 deletions

View File

@ -1236,6 +1236,7 @@ void initcells() {
else if(archimedean) currentmap = arcm::new_map();
#endif
else if(fulltorus) currentmap = new hrmap_torus;
else if(euclid && DIM == 3) currentmap = space::new_map();
else if(euclid) currentmap = new hrmap_euclidean;
else if(sphere) currentmap = new hrmap_spherical;
else if(quotient) currentmap = new quotientspace::hrmap_quotient;
@ -1871,6 +1872,9 @@ int celldistance(cell *c1, cell *c2) {
if(binarytiling && DIM == 3)
return binary::celldistance3(c1, c2);
if(euclid && DIM == 3)
return space::celldistance(c1, c2);
return hyperbolic_celldistance(c1, c2);
}

View File

@ -1765,7 +1765,8 @@ vector<geometryinfo> ginf = {
{"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated},
{"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ, gcHyperbolic, 0x28000, {{5, 3}}, eVariation::pure},
{"{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, 3, 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},
};
// remember to match the following mask when specifying codes for extra geometries: 0x78600

View File

@ -214,7 +214,7 @@ 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,
gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling,
gGUARD};
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };

View File

@ -31,6 +31,7 @@
#include "heptagon.cpp"
#include "binary-tiling.cpp"
#include "archimedean.cpp"
#include "space.cpp"
#include "crystal.cpp"
#include "language.cpp"
#include "cell.cpp"

View File

@ -371,7 +371,7 @@ void ge_land_selection() {
vector<eGeometry> tilinglist = {
gTinySphere, gSmallSphere, gSphere, gEuclid, gNormal, gOctagon,
gOctahedron, gEuclidSquare, g45, g46, g47,
gArchimedean, gBinaryTiling, gBinary3
gArchimedean, gBinaryTiling, gBinary3, gCubeTiling
};
vector<eGeometry> quotientlist = {

View File

@ -92,6 +92,9 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
#if CAP_BT
if(binarytiling) return binary::relative_matrix(c2->master, c1->master);
#endif
#if MAXDIM == 4
if(euclid && DIM == 3) return space::relative_matrix(c2->master, c1->master);
#endif
#if CAP_ARCM
if(archimedean) return arcm::relative_matrix(c2->master, c1->master);
#endif

View File

@ -4598,9 +4598,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
const int darkval[9] = {0,1,1,0,3,3,4,4,0};
int d = (asciicol & 0xF0F0F0) >> 3;
for(int a=0; a<9; a++)
for(int a=0; a<c->type; a++)
if(c->move(a) && !isWall(c->move(a))) {
if(a < 4) {
if(a < 4 && hyperbolic) {
if(celldistAlt(c) >= celldistAlt(viewctr.at->c7)) continue;
dynamicval<color_t> p (poly_outline, 0);
queuepoly(V, shBinaryWall[a], darkena(asciicol - d * darkval[a], 0, 0xFF));
@ -5709,6 +5709,10 @@ void drawthemap() {
else if(archimedean)
arcm::draw();
#endif
#if MAXDIM == 4
else if(euclid && DIM == 3)
space::draw();
#endif
else
drawStandard();
drawWormSegments();

View File

@ -231,6 +231,10 @@ heptagon *createStep(heptagon *h, int d) {
if(!h->move(d) && binarytiling && DIM == 3)
return binary::createStep3(h, d);
#endif
#if MAXDIM == 4
if(!h->move(d) && euclid && DIM == 3)
return space::createStep(h, d);
#endif
#if CAP_ARCM
if(!h->move(d) && archimedean) {
arcm::create_adjacent(h, d);

10
hyper.h
View File

@ -192,7 +192,7 @@ typedef complex<ld> cld;
#if MAXDIM == 3
#define DIM 2
#else
#define DIM (geometry == gBinary3 ? 3 : 2)
#define DIM ((geometry == gBinary3 || geometry == gCubeTiling) ? 3 : 2)
#endif
#define MDIM (DIM+1)
@ -4238,6 +4238,14 @@ namespace binary {
}
#endif
#if MAXDIM == 4
namespace space {
heptagon *createStep(heptagon *parent, int d);
hrmap* new_map();
void draw();
}
#endif
namespace arcm {
#if CAP_ARCM

View File

@ -1107,9 +1107,9 @@ void optimizeview() {
if(0) ;
#if CAP_BT || CAP_ARCM
else if(binarytiling || archimedean) {
turn = -1, best = View[DIM][DIM];
#if CAP_BT || CAP_ARCM || MAXDIM == 4
else if(binarytiling || archimedean || (euclid && DIM == 3)) {
turn = -1, best = hdist0(tC0(View));
for(int i=0; i<viewctr.at->c7->type; i++) {
int i1 = i * DUALMUL;
heptagon *h2 = createStep(viewctr.at, i1);
@ -1117,11 +1117,14 @@ void optimizeview() {
#if CAP_BT
if(binarytiling) T = binary::relative_matrix(h2, viewctr.at);
#endif
#if MAXDIM == 4
if(euclid && DIM == 3) T = space::relative_matrix(h2, viewctr.at);
#endif
#if CAP_ARCM
if(archimedean) T = arcm::relative_matrix(h2, viewctr.at);
#endif
hyperpoint H = View * tC0(T);
ld quality = euclid ? hdist0(H) : H[DIM];
ld quality = hdist0(H);
if(quality < best) best = quality, turn = i1, TB = T;
}
if(turn >= 0) {
@ -1590,8 +1593,8 @@ bool do_draw(cell *c) {
bool do_draw(cell *c, const transmatrix& T) {
if(DIM == 3) {
if(hyperbolic && V[DIM][DIM] > btrange_cosh) return false;
if(euclid && hypot_d(tC0(T), 3)) return false;
if(hyperbolic && T[DIM][DIM] > binary::btrange_cosh) return false;
if(euclid && hypot_d(tC0(T), 3) > 10) return false;
setdist(c, 7, c);
return true;
}

View File

@ -2436,7 +2436,7 @@ void buildpolys() {
bshape(shDragonNostril, PPR::ONTENTACLE_EYES, scalefactor, 241);
bshape(shDragonHead, PPR::ONTENTACLE, scalefactor, 242);
if(DIM == 3) {
if(DIM == 3 && binarytiling) {
make_wall(shBinaryWall[0], 0,0,-1, -1,0,-1, 0,-1,-1, 2);
make_wall(shBinaryWall[1], 0,0,-1, +1,0,-1, 0,-1,-1, 2);
make_wall(shBinaryWall[2], 0,0,-1, -1,0,-1, 0,+1,-1, 2);
@ -2448,6 +2448,22 @@ void buildpolys() {
make_wall(shBinaryWall[8], 1,1,+1, -1,1,+1, 1,-1,+1, 0);
}
if(DIM == 3 && euclid) {
for(int w=0; w<6; w++) {
bshape(shBinaryWall[w], PPR::WALL);
for(int a=0; a<=4; a++) {
int t[3];
t[0] = (w&1) ? -1 : 1;
t[1] = among(a, 0, 3, 4) ? -1 : 1;
t[2] = among(a, 2, 3) ? -1 : 1;
int x = w/2;
int y = (x+2)%3;
int z = (y+2)%3;
hpcpush(hpxy3(t[x]/2., t[y]/2., t[z]/2.));
}
}
}
ld krsc = 1;
if(sphere) krsc *= 1.4;
if(S7 ==8) krsc *= 1.3;

103
space.cpp Normal file
View File

@ -0,0 +1,103 @@
// Hyperbolic Rogue -- euclidean 3D geometry
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
namespace hr {
#if DIM == 3
namespace space {
typedef long long coord;
struct hrmap_cube : hrmap {
map<coord, heptagon*> spacemap;
map<heptagon*, coord> ispacemap;
hrmap_cube() {
getOrigin();
}
heptagon *getOrigin() {
return get_at(0);
}
heptagon *get_at(coord at) {
if(spacemap.count(at))
return spacemap[at];
else {
auto h = tailored_alloc<heptagon> (6);
h->c7 = newCell(6, h);
h->distance = 0;
h->cdata = NULL;
spacemap[at] = h;
ispacemap[h] = at;
return h;
}
}
heptagon *build(heptagon *parent, int d, coord at) {
auto h = get_at(at);
h->c.connect(d^1, parent, d, false);
return h;
}
heptagon *createStep(heptagon *parent, int d) {
int at = ispacemap[parent];
coord shifttable[6] = { +1, -1, +1000, -1000, +1000000, -1000000 };
return build(parent, d, at + shifttable[d]);
}
};
hrmap_cube* cubemap() {
return ((hrmap_cube*) currentmap);
}
hrmap* new_map() {
return new hrmap_cube;
}
heptagon *createStep(heptagon *parent, int d) {
return cubemap()->createStep(parent, d);
}
int getcoord(coord x, int a) {
for(int k=0; k<a; k++) { x -= getcoord(x, 0); x /= 1000; }
x %= 1000;
if(x>500) x -= 1000;
if(x<-500) x += 500;
return x;
}
void draw() {
dq::visited.clear();
dq::enqueue(viewctr.at, cview());
while(!dq::drawqueue.empty()) {
auto& p = dq::drawqueue.front();
heptagon *h = get<0>(p);
transmatrix V = get<1>(p);
dynamicval<ld> 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>>1, (i&1) ? -1 : 1));
}
}
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
auto cm = cubemap();
coord a = cm->ispacemap[h2] - cm->ispacemap[h1];
return eupush3(getcoord(a, 0), getcoord(a, 1), getcoord(a, 2));
}
int celldistance(cell *c1, cell *c2) {
auto cm = cubemap();
coord a = cm->ispacemap[c1->master] - cm->ispacemap[c2->master];
return getcoord(a, 0) + getcoord(a, 1) + getcoord(a, 2);
}
}
#endif
}

View File

@ -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)) variation = eVariation::pure;
if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling)) variation = eVariation::pure;
#endif
need_reset_geometry = true;