mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
binary tiling in 3D works
This commit is contained in:
parent
e73d2f2f22
commit
96e4ff6c9d
@ -3,6 +3,8 @@ namespace hr {
|
||||
|
||||
namespace binary {
|
||||
#if CAP_BT
|
||||
|
||||
#if DIM == 2
|
||||
enum bindir {
|
||||
bd_right = 0,
|
||||
bd_up_right = 1,
|
||||
@ -13,16 +15,20 @@ namespace binary {
|
||||
bd_down_left = 5, /* for cells of degree 7 */
|
||||
bd_down_right = 6 /* for cells of degree 7 */
|
||||
};
|
||||
#endif
|
||||
|
||||
int type_of(heptagon *h) {
|
||||
return h->c7->type;
|
||||
}
|
||||
|
||||
|
||||
#if DIM == 2
|
||||
// 0 - central, -1 - left, +1 - right
|
||||
int mapside(heptagon *h) {
|
||||
return h->zebraval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DIM == 2
|
||||
#if DEBUG_BINARY_TILING
|
||||
map<heptagon*, long long> xcode;
|
||||
map<long long, heptagon*> rxcode;
|
||||
@ -40,6 +46,7 @@ namespace binary {
|
||||
breakhere();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void breakhere() {
|
||||
exit(1);
|
||||
@ -76,7 +83,12 @@ namespace binary {
|
||||
return h1;
|
||||
}
|
||||
|
||||
#if DIM == 2
|
||||
heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
|
||||
#else
|
||||
heptagon *build(heptagon *parent, int d, int d1, int delta) {
|
||||
int t = 9; const int side = 0;
|
||||
#endif
|
||||
auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1);
|
||||
h->distance = parent->distance + delta;
|
||||
h->c7 = newCell(t, h);
|
||||
@ -93,6 +105,7 @@ namespace binary {
|
||||
return h;
|
||||
}
|
||||
|
||||
#if DIM == 2
|
||||
heptagon *createStep(heptagon *parent, int d) {
|
||||
auto h = parent;
|
||||
switch(d) {
|
||||
@ -146,10 +159,120 @@ namespace binary {
|
||||
breakhere();
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
heptagon *createStep(heptagon *parent, int d) {
|
||||
auto h = parent;
|
||||
switch(d) {
|
||||
case 0: case 1:
|
||||
case 2: case 3:
|
||||
return build(parent, d, 8, 1);
|
||||
case 8:
|
||||
return build(parent, 8, hrand(4), -1);
|
||||
case 4:
|
||||
parent->cmove(8);
|
||||
if(parent->c.spin(8) & 1)
|
||||
return path(h, 4, 5, {8, parent->c.spin(8) ^ 1});
|
||||
else
|
||||
return path(h, 4, 5, {8, 4, parent->c.spin(8) ^ 1});
|
||||
case 5:
|
||||
parent->cmove(8);
|
||||
if(!(parent->c.spin(8) & 1))
|
||||
return path(h, 5, 4, {8, parent->c.spin(8) ^ 1});
|
||||
else
|
||||
return path(h, 5, 4, {8, 5, parent->c.spin(8) ^ 1});
|
||||
case 6:
|
||||
parent->cmove(8);
|
||||
if(parent->c.spin(8) & 2)
|
||||
return path(h, 6, 7, {8, parent->c.spin(8) ^ 2});
|
||||
else
|
||||
return path(h, 6, 7, {8, 6, parent->c.spin(8) ^ 2});
|
||||
case 7:
|
||||
parent->cmove(8);
|
||||
if(!(parent->c.spin(8) & 2))
|
||||
return path(h, 7, 6, {8, parent->c.spin(8) ^ 2});
|
||||
else
|
||||
return path(h, 7, 6, {8, 7, parent->c.spin(8) ^ 2});
|
||||
}
|
||||
printf("error: case not handled in binary tiling\n");
|
||||
breakhere();
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
transmatrix tmatrix(heptagon *h, int dir) {
|
||||
switch(dir) {
|
||||
case 0:
|
||||
return xpush(-log(2)) * parabolic(-1, -1);
|
||||
case 1:
|
||||
return xpush(-log(2)) * parabolic(1, -1);
|
||||
case 2:
|
||||
return xpush(-log(2)) * parabolic(-1, 1);
|
||||
case 3:
|
||||
return xpush(-log(2)) * parabolic(1, 1);
|
||||
case 4:
|
||||
return parabolic(-2, 0);
|
||||
case 5:
|
||||
return parabolic(+2, 0);
|
||||
case 6:
|
||||
return parabolic(0, -2);
|
||||
case 7:
|
||||
return parabolic(0, +2);
|
||||
case 8:
|
||||
h->cmove(8);
|
||||
return inverse(tmatrix(h->move(8), h->c.spin(8)));
|
||||
}
|
||||
printf("error: case not handled in binary tiling tmatrix\n");
|
||||
breakhere();
|
||||
return Id;
|
||||
}
|
||||
|
||||
#if DIM == 3
|
||||
|
||||
void queuecube(const transmatrix& V, ld size, color_t linecolor, color_t facecolor) {
|
||||
ld yy = log(2) / 2;
|
||||
const int STEP=3;
|
||||
const ld MUL = 1. / STEP;
|
||||
auto at = [&] (ld x, ld y, ld z) { curvepoint(V * parabolic(size*x, size*y) * xpush(size*yy*z) * C0); };
|
||||
for(int a:{-1,1}) {
|
||||
for(ld t=-STEP; t<STEP; t++) at(a, 1,t*MUL);
|
||||
for(ld t=-STEP; t<STEP; t++) at(a, -t*MUL,1);
|
||||
for(ld t=-STEP; t<STEP; t++) at(a, -1,-t*MUL);
|
||||
for(ld t=-STEP; t<STEP; t++) at(a, t*MUL,-1);
|
||||
at(a, 1,-1);
|
||||
queuecurve(linecolor, facecolor, PPR::LINE);
|
||||
|
||||
for(ld t=-STEP; t<STEP; t++) at(1,t*MUL,a);
|
||||
for(ld t=-STEP; t<STEP; t++) at(-t*MUL,1,a);
|
||||
for(ld t=-STEP; t<STEP; t++) at(-1,-t*MUL,a);
|
||||
for(ld t=-STEP; t<STEP; t++) at(t*MUL,-1,a);
|
||||
at(1,-1,a);
|
||||
queuecurve(linecolor, facecolor, PPR::LINE);
|
||||
|
||||
for(ld t=-STEP; t<STEP; t++) at(1,a,t*MUL);
|
||||
for(ld t=-STEP; t<STEP; t++) at(-t*MUL,a,1);
|
||||
for(ld t=-STEP; t<STEP; t++) at(-1,a,-t*MUL);
|
||||
for(ld t=-STEP; t<STEP; t++) at(t*MUL,a,-1);
|
||||
at(1,a,-1);
|
||||
queuecurve(linecolor, facecolor, PPR::LINE);
|
||||
}
|
||||
/*for(int a:{-1,1}) for(int b:{-1,1}) for(int c:{-1,1}) {
|
||||
at(0,0,0); at(a,b,c); queuecurve(linecolor, facecolor, PPR::LINE);
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DIM==2
|
||||
transmatrix parabolic(ld u) {
|
||||
return parabolic1(u * vid.binary_width / log(2) / 2);
|
||||
}
|
||||
#else
|
||||
transmatrix parabolic(ld y, ld z) {
|
||||
ld co = vid.binary_width / log(2) / 2;
|
||||
return parabolic1(y * co, z * co);
|
||||
}
|
||||
#endif
|
||||
|
||||
ld btrange = 20;
|
||||
|
||||
void draw() {
|
||||
dq::visited.clear();
|
||||
@ -163,22 +286,33 @@ namespace binary {
|
||||
bandfixer bf(V);
|
||||
dq::drawqueue.pop();
|
||||
|
||||
|
||||
cell *c = h->c7;
|
||||
#if DIM==2
|
||||
if(!do_draw(c, V)) continue;
|
||||
#endif
|
||||
#if DIM==3
|
||||
if(V[DIM][DIM] > btrange) continue;
|
||||
setdist(c, 7, c);
|
||||
#endif
|
||||
drawcell(c, V, 0, false);
|
||||
|
||||
#if DIM==2
|
||||
dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
|
||||
dq::enqueue(h->move(bd_right), V * parabolic(1));
|
||||
dq::enqueue(h->move(bd_left), V * parabolic(-1));
|
||||
if(c->type == 6)
|
||||
dq::enqueue(h->move(bd_down), V * xpush(log(2)));
|
||||
// down_left
|
||||
if(c->type == 7) {
|
||||
dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2)));
|
||||
dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2)));
|
||||
}
|
||||
#else
|
||||
for(int i=0; i<9; i++)
|
||||
dq::enqueue(h->move(i), V * tmatrix(h, i));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
||||
@ -186,20 +320,28 @@ namespace binary {
|
||||
transmatrix gm = Id, where = Id;
|
||||
while(h1 != h2) {
|
||||
if(h1->distance <= h2->distance) {
|
||||
#if DIM==2
|
||||
if(type_of(h2) == 6)
|
||||
h2 = hr::createStep(h2, bd_down), where = xpush(-log(2)) * where;
|
||||
else if(mapside(h2) == 1)
|
||||
h2 = hr::createStep(h2, bd_left), where = parabolic(+1) * where;
|
||||
else if(mapside(h2) == -1)
|
||||
h2 = hr::createStep(h2, bd_right), where = parabolic(-1) * where;
|
||||
#else
|
||||
h2 = hr::createStep(h2, 8), where = inverse(tmatrix(h2, 8)) * where;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#if DIM==2
|
||||
if(type_of(h1) == 6)
|
||||
h1 = hr::createStep(h1, bd_down), gm = gm * xpush(log(2));
|
||||
else if(mapside(h1) == 1)
|
||||
h1 = hr::createStep(h1, bd_left), gm = gm * parabolic(-1);
|
||||
else if(mapside(h1) == -1)
|
||||
h1 = hr::createStep(h1, bd_right), gm = gm * parabolic(+1);
|
||||
#else
|
||||
h1 = hr::createStep(h1, 8), where = where * tmatrix(h1, 8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return gm * where;
|
||||
@ -212,9 +354,24 @@ auto bt_config = addHook(hooks_args, 0, [] () {
|
||||
shift_arg_formula(vid.binary_width, delayed_geo_reset);
|
||||
return 0;
|
||||
}
|
||||
else if(argis("-btrange")) {
|
||||
shift_arg_formula(btrange);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int celldistance(cell *c1, cell *c2) {
|
||||
int steps = 0;
|
||||
while(c1 != c2) {
|
||||
int d1 = celldistAlt(c1), d2 = celldistAlt(c2);
|
||||
if(d1 >= d2) c1 = c1->cmove(8), steps++;
|
||||
if(d2 >= d1) c2 = c2->cmove(8), steps++;
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
7
cell.cpp
7
cell.cpp
@ -73,7 +73,7 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
|
||||
binary::rxcode[1<<16] = &h;
|
||||
#endif
|
||||
h.zebraval = 0,
|
||||
h.c7 = newCell(6, origin);
|
||||
h.c7 = newCell(DIM == 3 ? 9 : 6, origin);
|
||||
}
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
@ -1867,7 +1867,10 @@ int celldistance(cell *c1, cell *c2) {
|
||||
|
||||
return 64;
|
||||
}
|
||||
|
||||
|
||||
#if DIM == 3
|
||||
if(binarytiling) return binary::celldistance(c1, c2);
|
||||
#endif
|
||||
return hyperbolic_celldistance(c1, c2);
|
||||
}
|
||||
|
||||
|
@ -1757,7 +1757,11 @@ vector<geometryinfo> ginf = {
|
||||
{"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, gcHyperbolic, 0x18200, {{6, 4}}, eVariation::bitruncated},
|
||||
{"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, gcHyperbolic, 0x18400, {{6, 4}}, eVariation::bitruncated},
|
||||
{"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, gcHyperbolic, 0x18600, {{7, 5}}, eVariation::bitruncated},
|
||||
{"binary","none", "variant of the binary tiling", "binary", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure},
|
||||
#if DIM == 2
|
||||
{"binary","none", "variant of the binary tiling", "binary", 7, 3, 0,gcHyperbolic, 0, {{7, 5}}, eVariation::pure},
|
||||
#else
|
||||
{"binary","none", "variant of the binary tiling", "binary", 9, 3, 0,gcHyperbolic, 0, {{7, 3}}, eVariation::pure},
|
||||
#endif
|
||||
{"Arch", "none", "Archimedean", "A", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure},
|
||||
{"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, gcHyperbolic, 0x20000, {{7, 5}}, eVariation::bitruncated},
|
||||
{"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, gcHyperbolic, 0x20200, {{6, 4}}, eVariation::bitruncated},
|
||||
|
@ -436,8 +436,8 @@ hyperpoint randomPointIn(int t) {
|
||||
}
|
||||
|
||||
#if CAP_BT
|
||||
hyperpoint get_horopoint(ld y, ld x) {
|
||||
return xpush(-y) * binary::parabolic(x) * C0;
|
||||
hyperpoint get_horopoint(ld y, ld x DC(,ld z)) {
|
||||
return xpush(-y) * binary::parabolic(x,z) * C0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -453,6 +453,7 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
|
||||
#endif
|
||||
#if CAP_BT
|
||||
if(binarytiling) {
|
||||
#if DIM == 2
|
||||
ld yx = log(2) / 2;
|
||||
ld yy = yx;
|
||||
ld xx = 1 / sqrt(2)/2;
|
||||
@ -465,6 +466,10 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
|
||||
vertices[5] = get_horopoint(-yy, -xx);
|
||||
vertices[6] = get_horopoint(-yy, 0);
|
||||
return mid_at_actual(vertices[cid], 3/cf);
|
||||
#else
|
||||
println(hlog, "get_corner_position called");
|
||||
return C0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if CAP_ARCM
|
||||
@ -538,6 +543,7 @@ hyperpoint nearcorner(cell *c, int i) {
|
||||
#endif
|
||||
#if CAP_BT
|
||||
if(binarytiling) {
|
||||
#if DIM == 2
|
||||
ld yx = log(2) / 2;
|
||||
ld yy = yx;
|
||||
// ld xx = 1 / sqrt(2)/2;
|
||||
@ -553,6 +559,10 @@ hyperpoint nearcorner(cell *c, int i) {
|
||||
else
|
||||
neis[5] = get_horopoint(-yy*2, 0);
|
||||
return neis[i];
|
||||
#else
|
||||
println(hlog, "nearcorner called");
|
||||
return Hypc;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
double d = cellgfxdist(c, i);
|
||||
|
10
graph.cpp
10
graph.cpp
@ -5078,7 +5078,11 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
#if CAP_QUEUE
|
||||
if(error) {
|
||||
queuechr(V, 1, ch, darkenedby(asciicol, darken), 2);
|
||||
if(ch == '#')
|
||||
binary::queuecube(V, 1, 0xFF, darkena(asciicol, 0, 0xFF));
|
||||
else if(ch == '.') ;
|
||||
else
|
||||
queuechr(V, 1, ch, darkenedby(asciicol, darken), 2);
|
||||
}
|
||||
|
||||
if(vid.grid) {
|
||||
@ -5100,6 +5104,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
if(0);
|
||||
#if CAP_BT
|
||||
else if(binarytiling) {
|
||||
#if DIM == 2
|
||||
ld yx = log(2) / 2;
|
||||
ld yy = yx;
|
||||
ld xx = 1 / sqrt(2)/2;
|
||||
@ -5113,6 +5118,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
horizontal(yy, 2*xx, xx, 4, binary::bd_up_right);
|
||||
horizontal(yy, xx, -xx, 8, binary::bd_up);
|
||||
horizontal(yy, -xx, -2*xx, 4, binary::bd_up_left);
|
||||
#else
|
||||
binary::queuecube(V, 1, 0xC0C0C080, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
else if(isWarped(c) && has_nice_dual()) {
|
||||
|
@ -4,8 +4,14 @@
|
||||
|
||||
namespace hr {
|
||||
|
||||
#if DIM == 3
|
||||
eGeometry geometry = gBinaryTiling;
|
||||
eVariation variation = eVariation::pure;
|
||||
#else
|
||||
eGeometry geometry;
|
||||
eVariation variation;
|
||||
#endif
|
||||
|
||||
|
||||
// hyperbolic points and matrices
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user