1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 09:00:34 +00:00

binary tiling

This commit is contained in:
Zeno Rogue 2018-08-09 19:28:53 +02:00
parent ebe57688ad
commit 4f3cc3783a
21 changed files with 531 additions and 103 deletions

View File

@ -30,7 +30,7 @@ int getAnthraxData(cell *c, bool b) {
}
int roundTableRadius(cell *c) {
if(euclid) return 28;
if(eubinary) return 28;
if(tactic::on) return getAnthraxData(c, true);
return c->master->alt->alt->emeraldval & GRAIL_RADIUS_MASK;
}
@ -74,7 +74,7 @@ const int NOCOMPASS = 1000000;
int compassDist(cell *c) {
if(sphere || quotient) return 0;
if(euclid || c->master->alt) return celldistAlt(c);
if(eubinary || c->master->alt) return celldistAlt(c);
if(isHaunted(c->land) || c->land == laGraveyard) return getHauntedDepth(c);
return NOCOMPASS;
}
@ -84,7 +84,7 @@ cell *findcompass(cell *c) {
if(d == NOCOMPASS) return NULL;
while(inscreenrange(c)) {
if(!euclid && !sphere && !quotient)
if(!eubinary && !sphere && !quotient)
generateAlts(c->master);
forCellEx(c2, c) if(compassDist(c2) < d) {
c = c2;
@ -99,7 +99,7 @@ cell *findcompass(cell *c) {
}
bool grailWasFound(cell *c) {
if(euclid || quotient || sphere) return items[itHolyGrail];
if(eubinary || quotient || sphere) return items[itHolyGrail];
return c->master->alt->alt->emeraldval & GRAIL_FOUND;
}
@ -249,7 +249,7 @@ void beCIsland(cell *c) {
}
void generateTreasureIsland(cell *c) {
if(!euclid) generateAlts(c->master);
if(!eubinary) generateAlts(c->master);
if(isOnCIsland(c)) return;
bool src = hrand(100) < 10;
@ -261,21 +261,21 @@ void generateTreasureIsland(cell *c) {
int qc = 0, qlo, qhi;
for(int i=0; i<c->type; i++) {
cell *c2 = createMov(c, i);
if(!euclid) generateAlts(c2->master);
if((euclid || (c->master->alt && c2->master->alt)) && celldistAlt(c2) < celldistAlt(c)) {
if(!eubinary) generateAlts(c2->master);
if((eubinary || (c->master->alt && c2->master->alt)) && celldistAlt(c2) < celldistAlt(c)) {
ctab[qc++] = c2;
qlo = i; qhi = i;
while(true && qc < MAX_EDGE) {
qlo--;
c2 = createMovR(c, qlo);
if(!euclid && !c2->master->alt) break;
if(!eubinary && !c2->master->alt) break;
if(celldistAlt(c2) >= celldistAlt(c)) break;
ctab[qc++] = c2;
}
while(true && qc < MAX_EDGE) {
qhi++;
c2 = createMovR(c, qhi);
if(!euclid && !c2->master->alt) break;
if(!eubinary && !c2->master->alt) break;
if(celldistAlt(c2) >= celldistAlt(c)) break;
ctab[qc++] = c2;
}
@ -295,7 +295,7 @@ void generateTreasureIsland(cell *c) {
if(c->wall != waCTree && hrand(100) < 15)
c->wall = (c->wall == waCIsland ? waCIsland2 : waCIsland);
}
if(src && c2->wall == waCTree && (euclid||c->master->alt) && celldistAlt(c) <= -10) {
if(src && c2->wall == waCTree && (eubinary||c->master->alt) && celldistAlt(c) <= -10) {
bool end = true;
for(int i=0; i<qc; i++) {
generateTreasureIsland(ctab[i]);
@ -976,8 +976,7 @@ int wallchance(cell *c, bool deepOcean) {
bool horo_ok() {
// do the horocycles work in the current geometry?
// (they work in ALL hyperbolic geometries currently!)
return hyperbolic;
return hyperbolic && !binarytiling;
}
bool gp_wall_test() {
@ -1084,7 +1083,7 @@ void buildBigStuff(cell *c, cell *from) {
buildBarrier4(c, bd, 0, getNewLand(c->land), c->land); */
}
if((!chaosmode) && bearsCamelot(c->land) && is_master(c) &&
if((!chaosmode) && bearsCamelot(c->land) && is_master(c) && !binarytiling &&
(quickfind(laCamelot) || peace::on || (hrand(I2000) < 200 && horo_ok() &&
items[itEmerald] >= U5 && !tactic::on))) {
int rtr = newRoundTableRadius();
@ -1177,7 +1176,7 @@ void buildCamelotWall(cell *c) {
c->wall = waCamelot;
for(int i=0; i<c->type; i++) {
cell *c2 = createMov(c, i);
if(c2->wall == waNone && (euclid || (c2->master->alt && c->master->alt)) && celldistAlt(c2) > celldistAlt(c) && c2->monst == moNone)
if(c2->wall == waNone && (eubinary || (c2->master->alt && c->master->alt)) && celldistAlt(c2) > celldistAlt(c) && c2->monst == moNone)
c2->wall = waCamelotMoat;
}
}
@ -1186,13 +1185,13 @@ void moreBigStuff(cell *c) {
if(quotient) return;
if(c->land == laPalace && !euclid && c->master->alt) {
if(c->land == laPalace && !eubinary && c->master->alt) {
int d = celldistAlt(c);
if(d <= PRADIUS1) generateAlts(c->master);
}
if(c->land == laStorms)
if(!euclid && !quotient && !sphere) {
if(!eubinary && !quotient && !sphere) {
if(c->master->alt && c->master->alt->distance <= 2) {
generateAlts(c->master);
preventbarriers(c);
@ -1210,15 +1209,15 @@ void moreBigStuff(cell *c) {
}
if((bearsCamelot(c->land) && !euclid && !quotient) || c->land == laCamelot)
if(euclid || c->master->alt) {
if(eubinary || binarytiling || c->master->alt) if(!(binarytiling && specialland != laCamelot)) {
int d = celldistAltRelative(c);
if(tactic::on || (d <= 14 && roundTableRadius(c) > 20)) {
if(!euclid) generateAlts(c->master);
if(!eubinary) generateAlts(c->master);
preventbarriers(c);
if(d == 10) {
if(weirdhyperbolic ? hrand(100) < 50 : pseudohept(c)) buildCamelotWall(c);
else {
if(!euclid) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
if(!eubinary) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
int q = 0;
if(weirdhyperbolic) {
for(int t=0; t<c->type; t++) createMov(c, t);
@ -1261,7 +1260,7 @@ void moreBigStuff(cell *c) {
// roughly as many knights as table cells
if(hrand(nonbitrunc ? 2618 : 1720) < 1000)
c->monst = moKnight;
if(!euclid) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
if(!eubinary) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
for(int i=0; i<c->type; i++)
if(c->mov[i] && celldistAltRelative(c->mov[i]) < d)
c->mondir = (i+3) % 6;
@ -1271,7 +1270,7 @@ void moreBigStuff(cell *c) {
if(d == 5 && tactic::on)
c->item = itGreenStone;
if(d <= 10) c->land = laCamelot;
if(d > 10 && !euclid && !tactic::on) {
if(d > 10 && !eubinary && !tactic::on) {
setland(c, eLand(c->master->alt->alt->fiftyval));
if(c->land == laNone) printf("Camelot\n"); // NONEDEBUG
}
@ -1284,9 +1283,9 @@ void moreBigStuff(cell *c) {
c->wall = waColumn;
}
else if((c->land == laRlyeh && !euclid) || c->land == laTemple) {
if(euclid || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
if(!euclid && !chaosmode) generateAlts(c->master);
else if((c->land == laRlyeh && !euclid) || c->land == laTemple) if(!(binarytiling && specialland != laTemple)) {
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
if(!eubinary && !chaosmode) generateAlts(c->master);
preventbarriers(c);
int d = celldistAlt(c);
if(d <= 0) {
@ -1299,7 +1298,7 @@ void moreBigStuff(cell *c) {
else if(pseudohept(c))
c->wall = waColumn;
else {
if(!euclid) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
if(!eubinary) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
int q = 0;
for(int t=0; t<c->type; t++) {
createMov(c, t);
@ -1311,22 +1310,22 @@ void moreBigStuff(cell *c) {
}
}
if((c->land == laOvergrown && !euclid) || c->land == laClearing) {
if(euclid || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
if(!euclid) generateAlts(c->master);
if((c->land == laOvergrown && !euclid) || c->land == laClearing) if(!(binarytiling && specialland != laClearing)) {
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
if(!eubinary) generateAlts(c->master);
preventbarriers(c);
int d = celldistAlt(c);
if(d <= 0) {
c->land = laClearing, c->wall = waNone; // , c->monst = moNone, c->item = itNone;
}
else if(d == 1 && !tactic::on && !euclid)
else if(d == 1 && !tactic::on && !eubinary)
c->wall = waSmallTree, c->monst = moNone, c->item = itNone;
}
}
if((c->land == laJungle && !euclid) || c->land == laMountain) {
if(euclid || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
if(!euclid) generateAlts(c->master);
if((c->land == laJungle && !euclid) || c->land == laMountain) if(!(binarytiling && specialland != laMountain)) {
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
if(!eubinary) generateAlts(c->master);
preventbarriers(c);
int d = celldistAlt(c);
if(d <= 0 || (firstland == laMountain && tactic::on)) {
@ -1335,14 +1334,14 @@ void moreBigStuff(cell *c) {
}
}
if(c->land == laOcean || c->land == laWhirlpool) {
if(c->land == laOcean || c->land == laWhirlpool) if(!(binarytiling && specialland != laWhirlpool)) {
bool fullwhirlpool = false;
if(tactic::on && specialland == laWhirlpool)
fullwhirlpool = true;
if(yendor::on && yendor::clev().l == laWhirlpool)
fullwhirlpool = true;
if(euclid || (c->master->alt && (fullwhirlpool || c->master->alt->distance <= 2))) {
if(!euclid) generateAlts(c->master);
if(eubinary || (c->master->alt && (fullwhirlpool || c->master->alt->distance <= 2))) {
if(!eubinary) generateAlts(c->master);
preventbarriers(c);
int dd = celldistAlt(c);
if(dd <= 0 || fullwhirlpool) {

207
binary-tiling.cpp Normal file
View File

@ -0,0 +1,207 @@
namespace hr {
namespace binary {
enum bindir {
bd_right = 0,
bd_up_right = 1,
bd_up = 2,
bd_up_left = 3,
bd_left = 4,
bd_down = 5, /* for cells of degree 6 */
bd_down_left = 5, /* for cells of degree 7 */
bd_down_right = 6 /* for cells of degree 7 */
};
int typeof(heptagon *h) {
return h->c7->type;
}
// 0 - central, -1 - left, +1 - right
int mapside(heptagon *h) {
return h->zebraval;
}
#if DEBUG_BINARY_TILING
map<heptagon*, long long> xcode;
map<long long, heptagon*> rxcode;
long long expected_xcode(heptagon *h, int d) {
auto r =xcode[h];
if(d == 0) return r + 1;
if(d == 1) return 2*r + 1;
if(d == 2) return 2*r;
if(d == 3) return 2*r - 1;
if(d == 4) return r-1;
if(d == 5 && typeof(h) == 6) return r / 2;
if(d == 5 && typeof(h) == 7) return (r-1) / 2;
if(d == 6 && typeof(h) == 7) return (r+1) / 2;
breakhere();
}
#endif
void breakhere() {
exit(1);
}
heptagon *path(heptagon *h, int d, int d1, std::initializer_list<int> p) {
static int rec = 0;
rec++; if(rec>100) exit(1);
// printf("{generating path from %p (%d/%d) dir %d:", h, typeof(h), mapside(h), d);
heptagon *h1 = h;
for(int d0: p) {
// printf(" [%d]", d0);
h1 = hr::createStep(h1, d0);
// printf(" %p", h1);
}
#if DEBUG_BINARY_TILING
if(xcode[h1] != expected_xcode(h, d)) {
printf("expected_xcode mismatch\n");
breakhere();
}
#endif
// printf("}\n");
if(h->move[d] && h->move[d] != h1) {
printf("already connected to something else (1)\n");
breakhere();
}
if(h1->move[d1] && h1->move[d1] != h) {
printf("already connected to something else (2)\n");
breakhere();
}
connectHeptagons(h, d, h1, d1);
rec--;
return h1;
}
heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
auto h = buildHeptagon(parent, d, hsOrigin, d1);
h->distance = parent->distance + delta;
h->c7 = newCell(t, h);
h->cdata = NULL;
h->zebraval = side;
#if DEBUG_BINARY_TILING
xcode[h] = expected_xcode(parent, d);
if(rxcode.count(xcode[h])) {
printf("xcode clash\n");
breakhere();
}
rxcode[xcode[h]] = h;
#endif
return h;
}
heptagon *createStep(heptagon *parent, int d) {
auto h = parent;
switch(d) {
case bd_right: {
if(mapside(h) > 0 && typeof(h) == 7)
return path(h, d, bd_left, {bd_left, bd_down, bd_right, bd_up});
else if(mapside(h) >= 0)
return build(parent, bd_right, bd_left, typeof(parent) ^ 1, 1, 0);
else if(typeof(h) == 6)
return path(h, d, bd_left, {bd_down, bd_right, bd_up, bd_left});
else
return path(h, d, bd_left, {bd_down_right, bd_up});
}
case bd_left: {
if(mapside(h) < 0 && typeof(h) == 7)
return path(h, d, bd_right, {bd_right, bd_down, bd_left, bd_up});
else if(mapside(h) <= 0)
return build(parent, bd_left, bd_right, typeof(parent) ^ 1, -1, 0);
else if(typeof(h) == 6)
return path(h, d, bd_right, {bd_down, bd_left, bd_up, bd_right});
else
return path(h, d, bd_right, {bd_down_left, bd_up});
}
case bd_up_right: {
return path(h, d, bd_down_left, {bd_up, bd_right});
}
case bd_up_left: {
return path(h, d, bd_down_right, {bd_up, bd_left});
}
case bd_up:
return build(parent, bd_up, bd_down, 6, mapside(parent), 1);
default:
/* bd_down */
if(typeof(h) == 6) {
if(mapside(h) == 0)
return build(parent, bd_down, bd_up, 6, 0, -1);
else if(mapside(h) == 1)
return path(h, d, bd_up, {bd_left, bd_left, bd_down, bd_right});
else if(mapside(h) == -1)
return path(h, d, bd_up, {bd_right, bd_right, bd_down, bd_left});
}
/* bd_down_left */
else if(d == bd_down_left) {
return path(h, d, bd_up_right, {bd_left, bd_down});
}
else if(d == bd_down_right) {
return path(h, d, bd_up_left, {bd_right, bd_down});
}
}
printf("error: case not handled in binary tiling\n");
breakhere();
return NULL;
}
transmatrix parabolic(ld u) {
u = u / log(2);
return transmatrix {{{-u*u/8+1, u/2, u*u/8}, {-u/2, 1, u/2}, {-u*u/8, u/2, u*u/8+1}}};
}
void draw_rec(cell *c, int dirs, const transmatrix& V) {
if(!dodrawcell(c)) return;
drawcell(c, V, 0, false);
// 1: up
if(dirs & 1)
draw_rec(createMov(c, bd_up), 7, V * xpush(-log(2)));
// right
if(dirs & 2)
draw_rec(createMov(c, bd_right), 2, V * parabolic(1));
// left
if(dirs & 4)
draw_rec(createMov(c, bd_left), 4, V * parabolic(-1));
// down
if((dirs & 8) && c->type == 6)
draw_rec(createMov(c, bd_down), dirs & 62, V * xpush(log(2)));
// down_left
if((dirs & 16) && c->type == 7)
draw_rec(createMov(c, bd_down_left), dirs & 28, V * parabolic(-1) * xpush(log(2)));
// down_right
if((dirs & 32) && c->type == 7)
draw_rec(createMov(c, bd_down_right), dirs & 42, V * parabolic(1) * xpush(log(2)));
}
void draw() {
draw_rec(viewctr.h->c7, 63, cview());
}
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
transmatrix gm = Id, where = Id;
while(h1 != h2) {
if(h1->distance <= h2->distance) {
if(typeof(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 {
if(typeof(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);
}
}
return gm * where;
}
}
}

View File

@ -73,7 +73,17 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
h.alt = NULL;
h.distance = 0;
isnonbitrunc = nonbitrunc;
if(irr::on)
if(binarytiling) {
#if DEBUG_BINARY_TILING
binary::xcode.clear();
binary::rxcode.clear();
binary::xcode[&h] = (1 << 16);
binary::rxcode[1<<16] = &h;
#endif
h.zebraval = 0,
h.c7 = newCell(6, origin);
}
else if(irr::on)
irr::link_start(origin);
else
h.c7 = newCell(S7, origin);
@ -972,7 +982,7 @@ void clearHexes(heptagon *at) {
at->cdata = NULL;
}
if(irr::on) irr::clear_links(at);
else if(at->c7) subcell(at->c7, clearcell);
else if(at->c7 && !binarytiling) subcell(at->c7, clearcell);
}
void unlink_cdata(heptagon *h) {
@ -1003,7 +1013,9 @@ void clearfrom(heptagon *at) {
at->cdata = NULL;
}
}
for(int i=0; i<S7; i++) if(at->move[i]) {
int edges = S7;
if(binarytiling) edges = at->c7->type;
for(int i=0; i<edges; i++) if(at->move[i]) {
if(at->move[i]->alt != &deletion_marker)
q.push(at->move[i]);
unlink_cdata(at->move[i]);
@ -1109,6 +1121,7 @@ int celldistAlt(cell *c) {
tie(x,y) = vec_to_pair(decodeId(c->master));
return euclidAlt(x, y);
}
if(binarytiling) return celldist(c) + (specialland == laCamelot && !tactic::on? 30 : 0);
if(sphere || quotient) {
return celldist(c) - 3;
}
@ -1458,8 +1471,8 @@ int heptdistance(heptagon *h1, heptagon *h2) {
if(h1 == h2) return d;
for(int i=0; i<S7; i++) if(h1->move[i] == h2) return d + 1;
int d1 = h1->distance, d2 = h2->distance;
if(d1 >= d2) d++, h1 = h1->move[0];
if(d2 > d1) d++, h2 = h2->move[0];
if(d1 >= d2) d++, h1 = createStep(h1, binarytiling ? 5 : 0);
if(d2 > d1) d++, h2 = createStep(h2, binarytiling ? 5 : 0);
}
}

View File

@ -1680,6 +1680,7 @@ geometryinfo ginf[gGUARD] = {
{"Bolza Surface", "Bolza", 8, 3, qSMALL | qDOCKS, gcHyperbolic, 0x18200, {{6, 4}}},
{"Bolza Surface x2", "Bolza2", 8, 3, qSMALL | qDOCKS, gcHyperbolic, 0x18400, {{6, 4}}},
{"minimal quotient", "minimal", 7, 3, qSMALL | qNONOR, gcHyperbolic, 0x18600, {{7, 5}}},
{"binary tiling", "binary", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}}
};
}

View File

@ -198,7 +198,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,
gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling,
gGUARD};
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };

View File

@ -29,6 +29,7 @@
#include "patterns.cpp"
#include "fieldpattern.cpp"
#include "heptagon.cpp"
#include "binary-tiling.cpp"
#include "language.cpp"
#include "cell.cpp"
#include "goldberg.cpp"

View File

@ -926,7 +926,7 @@ namespace whirlpool {
// next == -1 -> prev
cell *get(cell *c, int next) {
int i = 0;
if(!euclid && !c->master->alt) return NULL;
if(!eubinary && !c->master->alt) return NULL;
int d = celldistAlt(c);
int d2;
while(true) {
@ -949,7 +949,7 @@ namespace whirlpool {
cell *at = whirlline[isize(whirlline)-1];
cell *prev = whirlline[isize(whirlline)-2];
for(int i=0; i<at->type; i++)
if(at->mov[i] && (euclid || at->mov[i]->master->alt) && celldistAlt(at->mov[i]) == d && at->mov[i] != prev) {
if(at->mov[i] && (eubinary || at->mov[i]->master->alt) && celldistAlt(at->mov[i]) == d && at->mov[i] != prev) {
if(at->mov[i] == whirlline[0]) return; // loops in weird geometries?
if(at->mov[i] == whirlline[isize(whirlline)/2]) return; // even weirder geometry?
whirlline.push_back(at->mov[i]);
@ -968,7 +968,7 @@ namespace whirlpool {
else if(hrand(5000) < 500)
wto->wall = waBoat;
if(wto->wall == waBoat && (euclid || wto->master->alt)) {
if(wto->wall == waBoat && (eubinary || wto->master->alt)) {
int d = celldistAlt(wto);
if(yendor::on) d -= 200;
// 250 : hard
@ -1016,7 +1016,7 @@ namespace whirlpool {
void moveAt(cell *c, manual_celllister& cl) {
if(c->land != laWhirlpool) return;
if(cl.listed(c)) return;
if(!(euclid || c->master->alt)) return;
if(!(eubinary || c->master->alt)) return;
cell *c2 = get(c, 1);
if(!c2) return;
int d = celldistAlt(c);

View File

@ -199,8 +199,63 @@ void bshape2(hpcshape& sh, int p, int shapeid, matrixlist& m) {
hpcpush(hpc[last->s]);
}
hyperpoint get_horopoint(ld y, ld x) {
return xpush(-y) * binary::parabolic(x) * C0;
}
void horopoint(ld y, ld x) {
hpcpush(get_horopoint(y, x));
}
void horopoint(ld y, ld x, cell &fc, int c) {
hpcpush(iddspin(&fc, c) * get_horopoint(y, x));
}
void horoline(ld y, ld x1, ld x2) {
for(int a=0; a<=16; a++)
horopoint(y, x1 + (x2-x1) * a / 16.);
}
void horoline(ld y, ld x1, ld x2, cell &fc, int c) {
for(int a=0; a<=16; a++)
horopoint(y, x1 + (x2-x1) * a / 16., fc, c);
}
void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
if(binarytiling) {
bshape(fsh.b[id], fsh.prio);
ld yx = size * log(2) / 2;
ld yy = yx;
ld xx = size / sqrt(2)/2;
horoline(-yx, -xx, xx); horoline(yx, xx*2, -xx*2); horopoint(-yx, -xx);
bshape(fsh.shadow[id], fsh.prio);
horoline(-yx*SHADMUL, -xx*SHADMUL, xx*SHADMUL); horoline(yx*SHADMUL, xx*SHADMUL*2, -xx*SHADMUL*2); horopoint(-yx*SHADMUL, -xx*SHADMUL);
cell fc;
fc.type = 6+id;
for(int k=0; k<SIDEPARS; k++) {
for(int i=0; i<fc.type; i++) fsh.gpside[k][i].resize(2);
bshape(fsh.gpside[k][0][id], PPR_LAKEWALL); horopoint(-yy, xx, fc, 0); horopoint(yy, 2*xx, fc, 0); chasmifyPoly(dlow_table[k], dhi_table[k], k);
bshape(fsh.gpside[k][1][id], PPR_LAKEWALL); horoline(yy, 2*xx, xx, fc, 1); chasmifyPoly(dlow_table[k], dhi_table[k], k);
bshape(fsh.gpside[k][2][id], PPR_LAKEWALL); horoline(yy, xx, -xx, fc, 2); chasmifyPoly(dlow_table[k], dhi_table[k], k);
bshape(fsh.gpside[k][3][id], PPR_LAKEWALL); horoline(yy, -xx, -2*xx, fc, 3); chasmifyPoly(dlow_table[k], dhi_table[k], k);
bshape(fsh.gpside[k][4][id], PPR_LAKEWALL); horopoint(yy, -2*xx, fc, 4); horopoint(-yy, -xx, fc, 4); chasmifyPoly(dlow_table[k], dhi_table[k], k);
if(id == 0) {
bshape(fsh.gpside[k][5][id], PPR_LAKEWALL); horoline(-yy, -xx, xx, fc, 5); chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
else {
bshape(fsh.gpside[k][5][id], PPR_LAKEWALL); horoline(-yy, -xx, 0, fc, 5); chasmifyPoly(dlow_table[k], dhi_table[k], k);
bshape(fsh.gpside[k][6][id], PPR_LAKEWALL); horoline(-yy, -0, xx, fc, 6); chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
}
return;
}
bshape(fsh.b[id], fsh.prio);
for(int t=0; t<=sides; t++)
hpcpush(ddi(t*S84 / sides + shift, size) * C0);
@ -271,7 +326,59 @@ void generate_floorshapes() {
auto& fsh = *pfsh;
generate_matrices_scale(fsh.scale, fsh.noftype);
fsh.b.resize(2);
if(nonbitrunc && geosupport_graveyard() < 2 && fsh.shapeid2) {
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
auto& m = hept_matrices;
for(int id=0; id<2; id++) {
int cor = 6 + id;
hyperpoint vertices[7];
vertices[0] = get_horopoint(-yy, xx);
vertices[1] = get_horopoint(yy, 2*xx);
vertices[2] = get_horopoint(yy, xx);
vertices[3] = get_horopoint(yy, -xx);
vertices[4] = get_horopoint(yy, -2*xx);
vertices[5] = get_horopoint(-yy, -xx);
if(id) vertices[6] = get_horopoint(-yy, 0);
hyperpoint neis[7];
neis[0] = get_horopoint(0, 1);
neis[1] = get_horopoint(yy*2, 1);
neis[2] = get_horopoint(yy*2, 0);
neis[3] = get_horopoint(yy*2, -1);
neis[4] = get_horopoint(0, -1);
if(id)
neis[5] = get_horopoint(-yy*2, -.5),
neis[6] = get_horopoint(-yy*2, +.5);
else
neis[5] = get_horopoint(-yy*2, 0);
int sid = fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1;
int i = 0;
for(int d=0; d<m.o.sym; d++) {
hyperpoint center = hpxy(0,0);
for(int c=0; c<cor; c++) {
hyperpoint nlcorner = vertices[(d+c+1) % cor];
hyperpoint nrcorner = vertices[(d+c+2) % cor];
hyperpoint nfar = neis[(d+c+1) % cor];
hyperpoint nlfar = nfar;
hyperpoint nrfar = nfar;
m.v[i].second[c] = build_matrix(center, nlcorner, nrcorner);
m.v[i+1].second[c] = build_matrix(nfar, nlcorner, nrcorner);
m.v[i+2].second[c] = build_matrix(nfar, nlcorner, nlfar);
m.v[i+3].second[c] = build_matrix(nfar, nrcorner, nrfar);
}
i += 4;
}
if(i != isize(m.v)) printf("warning: i=%d sm=%d\n", i, isize(m.v));
m.n.sym = cor;
bshape2(fsh.b[id], fsh.prio, sid, hept_matrices);
}
}
else if(nonbitrunc && geosupport_graveyard() < 2 && fsh.shapeid2) {
bshape2(fsh.b[0], fsh.prio, fsh.shapeid2, hept_matrices);
bshape2(fsh.b[1], fsh.prio, fsh.shapeid2, hept_matrices);
}
@ -694,6 +801,8 @@ void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, i
}
else if(geosupport_threecolor() == 2)
queuepolyat(V, shv[pseudohept(c)], col, prio);
else if(binarytiling)
queuepolyat(V, shv[c->type-6], col, prio);
else
queuepolyat(V, shv[ctof(c)], col, prio);
}

View File

@ -413,7 +413,7 @@ bool thruVine(cell *c, cell *c2) {
bool againstCurrent(cell *w, cell *from) {
if(from->land != laWhirlpool) return false;
if(againstWind(from, w)) return false; // wind is stronger than current
if(!euclid && (!from->master->alt || !w->master->alt)) return false;
if(!eubinary && (!from->master->alt || !w->master->alt)) return false;
int dfrom = celldistAlt(from);
int dw = celldistAlt(w);
if(dw < dfrom) return false;
@ -2176,7 +2176,7 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
c->item = itOrbWater;
if(m == moPirate && isOnCIsland(c) && c->item == itNone && (
euclid ||
eubinary ||
(c->master->alt && celldistAlt(c) <= 2-getDistLimit()) ||
isHaunted(c->land))) {
bool toomany = false;
@ -6740,7 +6740,7 @@ bool collectItem(cell *c2, bool telekinesis) {
items[itOrbSpeed] += v;
items[itHolyGrail]++;
addMessage(XLAT("Congratulations! You have found the Holy Grail!"));
if(!euclid) c2->master->alt->emeraldval |= GRAIL_FOUND;
if(!eubinary) c2->master->alt->emeraldval |= GRAIL_FOUND;
achievement_collection(c2->item, pg, gold());
}
else if(c2->item == itKey) {

View File

@ -285,9 +285,11 @@ void showEuclideanMenu() {
dialog::addBreak(50);
if(ts == 6 && tv == 3)
dialog::addSelItem(XLAT("variations"), XLAT("does not matter"), 't');
dialog::addSelItem(XLAT("variations"), XLAT("does not matter"), 'v');
else if(binarytiling)
dialog::addSelItem(XLAT("variations"), XLAT("not implemented"), 'v');
else {
dialog::addBoolItem(XLAT("variations"), nonbitrunc, 't');
dialog::addBoolItem(XLAT("variations"), nonbitrunc, 'v');
dialog::lastItem().value = gp::operation_name();
}
@ -389,8 +391,8 @@ void showEuclideanMenu() {
}
else if(uni == 'u')
showquotients = !showquotients;
else if(uni == 't') {
if(euclid6) ;
else if(uni == 'v') {
if(euclid6 || binarytiling) ;
else // if(S3 == 3)
gp::configure();
/* else {

View File

@ -162,6 +162,7 @@ int ctof(cell *c) {
if(nonbitrunc && !gp::on) return 1;
// if(euclid) return 0;
if(!c) return 1;
if(binarytiling) return c->type == 7;
return ishept(c) ? 1 : 0;
// c->type == 6 ? 0 : 1;
}
@ -241,6 +242,12 @@ int displaydir(cell *c, int d) {
auto& p = vs.jpoints[vs.neid[d]];
return -int(atan2(p[1], p[0]) * S84 / 2 / M_PI + MODFIXER + .5);
}
else if(binarytiling) {
if(d == NODIR) return 0;
if(d == c->type-1) d++;
int dirs[8] = {0, 11, 21, 31, 42, 53, 63, 73};
return -21-dirs[d];
}
else if(euclid)
return - d * S84 / c->type;
else
@ -248,6 +255,7 @@ int displaydir(cell *c, int d) {
}
double hexshiftat(cell *c) {
if(binarytiling) return 0;
if(ctof(c) && S7==6 && S3 == 4 && !nonbitrunc) return hexshift + 2*M_PI/S7;
if(ctof(c) && (S7==8 || S7 == 4) && S3 == 3 && !nonbitrunc) return hexshift + 2*M_PI/S7;
if(hexshift && ctof(c)) return hexshift;
@ -2642,7 +2650,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
else if(c->land == laAlchemist)
fcol = 0x900090;
else if(c->land == laWhirlpool)
fcol = 0x0000C0 + int(32 * sin(ticks / 200. + ((euclid||c->master->alt) ? celldistAlt(c) : 0)*1.5));
fcol = 0x0000C0 + int(32 * sin(ticks / 200. + ((eubinary||c->master->alt) ? celldistAlt(c) : 0)*1.5));
else if(c->land == laLivefjord)
fcol = 0x000080;
else if(isWarped(c->land))
@ -2788,7 +2796,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
else if(c->wall == waBigTree) wcol = 0x0080C0;
break;
case laTemple: {
int d = showoff ? 0 : (euclid||c->master->alt) ? celldistAlt(c) : 99;
int d = showoff ? 0 : (eubinary||c->master->alt) ? celldistAlt(c) : 99;
if(chaosmode)
fcol = 0x405090;
else if(d % TEMPLE_EACH == 0)
@ -3182,7 +3190,7 @@ bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, int col) {
transmatrix V2 = V * ddspin(c, i);
if(gp::on || irr::on) {
if(gp::on || irr::on || binarytiling) {
draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio);
return false;
}
@ -4779,7 +4787,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
double spd = 1;
bool rev = false;
if(isGravityLand(cwt.c->land)) {
if(binarytiling && conformal::do_rotate >= 2) {
if(!straightDownSeek || c->master->distance < straightDownSeek->master->distance) {
usethis = true;
spd = 1;
}
}
else if(isGravityLand(cwt.c->land)) {
if(cwt.c->land == laDungeon) rev = true;
if(conformal::do_rotate >= 1)
if(!straightDownSeek || edgeDepth(c) < edgeDepth(straightDownSeek)) {
@ -4788,7 +4803,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
}
if(c->master->alt && cwt.c->master->alt &&
else if(c->master->alt && cwt.c->master->alt &&
(cwt.c->land == laMountain ||
(conformal::do_rotate >= 2 &&
(cwt.c->land == laTemple || cwt.c->land == laWhirlpool ||
@ -4803,7 +4818,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
}
if(conformal::do_rotate >= 2 && cwt.c->land == laOcean && cwt.c->landparam < 25) {
else if(conformal::do_rotate >= 2 && cwt.c->land == laOcean && cwt.c->landparam < 25) {
if(!straightDownSeek || coastval(c, laOcean) < coastval(straightDownSeek, laOcean)) {
usethis = true;
spd = cwt.c->landparam / 10;
@ -5209,6 +5224,8 @@ void drawthemap() {
profile_start(1);
if(euclid)
drawEuclidean();
else if(binarytiling)
binary::draw();
else
drawrec(viewctr, hsOrigin, cview());
drawWormSegments();

View File

@ -74,6 +74,7 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix
h->spintable = 0;
h->move[pard] = parent; tsetspin(h->spintable, pard, d);
parent->move[d] = h; tsetspin(parent->spintable, d, pard);
if(binarytiling) return h;
if(parent->c7) {
if(irr::on)
irr::link_next(parent, d);
@ -238,7 +239,9 @@ heptspin& operator += (heptspin& h, wstep_t) { h = h + wstep; return h; }
heptagon *createStep(heptagon *h, int d) {
d = fixrot(d);
if(!h->move[0] && h->s != hsOrigin) {
if(!h->move[d] && binarytiling)
return binary::createStep(h, d);
if(!h->move[0] && h->s != hsOrigin && !binarytiling) {
// cheating:
int pard=0;
if(S3 == 3)

17
hyper.h
View File

@ -82,10 +82,13 @@ void addMessage(string s, char spamtype = 0);
#define ALPHA (M_PI*2/S7)
#define S7 ginf[geometry].sides
#define S3 ginf[geometry].vertex
#define hyperbolic_37 (S7 == 7 && S3 == 3)
#define hyperbolic_not37 ((S7 > 7 || S3 > 3) && hyperbolic)
#define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on || irr::on) && hyperbolic)
#define stdhyperbolic (S7 == 7 && S3 == 3 && !gp::on)
#define hyperbolic_37 (S7 == 7 && S3 == 3 && !binarytiling)
#define hyperbolic_not37 ((S7 > 7 || S3 > 3 || binarytiling) && hyperbolic)
#define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on || irr::on || binarytiling) && hyperbolic)
#define stdhyperbolic (S7 == 7 && S3 == 3 && !gp::on && !irr::on && !binarytiling)
#define binarytiling (geometry == gBinaryTiling)
#define eubinary (euclid || binarytiling)
#define cgclass (ginf[geometry].cclass)
#define euclid (cgclass == gcEuclid)
@ -3755,4 +3758,10 @@ bool saved_tortoise_on(cell *c);
#define PRING(i) for(double i=0; i<=S84+1e-6; i+= pow(.5, vid.linequality))
#define REVPRING(i) for(double i=S84; i>=-1e-6; i-=pow(.5, vid.linequality))
void horopoint(ld y, ld x);
namespace binary {
heptagon *createStep(heptagon *parent, int d);
}
}

View File

@ -800,18 +800,36 @@ void optimizeview() {
transmatrix TB = Id;
for(int i=-1; i<S7; i++) {
ld trot = -i * M_PI * 2 / (S7+.0);
transmatrix T = i < 0 ? Id : spin(trot) * xpush(tessf) * pispin;
hyperpoint H = View * tC0(T);
if(H[2] < best) best = H[2], turn = i, TB = T;
if(binarytiling) {
turn = -1, best = View[2][2];
for(int i=0; i<viewctr.h->c7->type; i++) {
heptagon *h2 = createStep(viewctr.h, i);
transmatrix T = binary::relative_matrix(h2, viewctr.h);
hyperpoint H = View * tC0(T);
if(H[2] < best) best = H[2], turn = i, TB = T;
}
if(turn >= 0) {
View = View * TB;
fixmatrix(View);
viewctr.h = createStep(viewctr.h, turn);
}
}
if(turn >= 0) {
View = View * TB;
fixmatrix(View);
viewctr = viewctr + turn + wstep;
else {
for(int i=-1; i<S7; i++) {
ld trot = -i * M_PI * 2 / (S7+.0);
transmatrix T = i < 0 ? Id : spin(trot) * xpush(tessf) * pispin;
hyperpoint H = View * tC0(T);
if(H[2] < best) best = H[2], turn = i, TB = T;
}
if(turn >= 0) {
View = View * TB;
fixmatrix(View);
viewctr = viewctr + turn + wstep;
}
}
}

View File

@ -352,9 +352,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
if(hrand(5000) < 20*PRIZEMUL && c->wall != waOpenGate)
placePrizeOrb(c);
if(c->wall == waNone) buildPrizeMirror(c, 250);
if(c->land == laPalace && (euclid || c->master->alt) && celldistAlt(c) <= 150 && !(havewhat&HF_MOUSE) && !princess::generating &&
if(c->land == laPalace && (eubinary || c->master->alt) && celldistAlt(c) <= 150 && !(havewhat&HF_MOUSE) && !princess::generating &&
princess::getPrisonInfo(c) &&
(euclid || (princess::getPrisonInfo(c)->bestdist < 6 && princess::getPrisonInfo(c)->princess))) {
(eubinary || (princess::getPrisonInfo(c)->bestdist < 6 && princess::getPrisonInfo(c)->princess))) {
c->monst = moMouse;
if(!princess::squeaked) {
addMessage(XLAT("You hear a distant squeak!"));
@ -1329,7 +1329,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
// depth!
int d =
chaosmode ? -15 * items[itGrimoire]:
(euclid || c->master->alt) ? celldistAlt(c) : 10;
(eubinary || c->master->alt) ? celldistAlt(c) : 10;
// remember: d is negative
if(chaosmode ? hrand(100) < 25 : d % TEMPLE_EACH == 0) {
if(hrand(5000) < 20 - 2*d && !c->monst && !peace::on)
@ -1469,9 +1469,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
case laCaribbean:
if(d == 9) {
if(!euclid) {
if(!eubinary) {
if(c->master->alt && c->master->alt->distance <= 2) {
if(!euclid) generateAlts(c->master);
if(!eubinary) generateAlts(c->master);
preventbarriers(c);
int d = celldistAlt(c);
if(d <= 0)
@ -1490,11 +1490,11 @@ void giantLandSwitch(cell *c, int d, cell *from) {
c->wall = waSea;
}
}
if(d == 8 && !euclid) {
if(d == 8 && !eubinary) {
int mindist = 9;
for(int i=0; i<c->type; i++) {
cell *c2 = c->mov[i];
if((euclid || c2->master->alt) && celldistAlt(c2) < mindist)
if((eubinary || c2->master->alt) && celldistAlt(c2) < mindist)
mindist = celldistAlt(c2);
}
if(mindist == 0) beCIsland(c);
@ -2372,7 +2372,7 @@ void setdist(cell *c, int d, cell *from) {
// this fixes the following problem:
// http://steamcommunity.com/app/342610/discussions/0/1470840994970724215/
if(!generatingEquidistant && from && d >= 7 && c->land) {
if(!generatingEquidistant && from && d >= 7 && c->land && !binarytiling) {
int cdi = celldist(c);
if(celldist(from) > cdi) {
forCellCM(c2, c) if(celldist(c2) < cdi) {

View File

@ -343,6 +343,7 @@ int fieldval_uniq(cell *c) {
auto p = cell_to_pair(c);
return gmod(p.first * torusconfig::dx + p.second * torusconfig::dy, torusconfig::qty);
}
else if(binarytiling) return 0;
if(ctof(c) || gp::on || irr::on) return c->master->fieldval/S7;
else {
int z = 0;
@ -734,7 +735,7 @@ namespace patterns {
void val_warped(cell *c, patterninfo& si) {
int u = ishept(c)?1:0;
if(S3 != 3 || S7 != 7) {
if(S3 != 3 || S7 != 7 || gp::on || irr::on) {
si.id = u;
si.dir = 1;
return;
@ -872,6 +873,12 @@ namespace patterns {
si.dir = 0; si.reflect = false; si.id = ctof(c);
si.symmetries = c->type;
if(binarytiling) {
if(pat == PAT_SINGLETYPE) si.id = 0;
si.dir = 2;
return si;
}
if(pat == PAT_SINGLETYPE) {
si.id = 0; si.symmetries = 1;
if(sub & SPF_TWOCOL) si.id = c->type & 1;
@ -1160,6 +1167,7 @@ int pattern_threecolor(cell *c) {
// which roughly corresponds to the heptagons in the normal tiling
bool pseudohept(cell *c) {
if(irr::on) return irr::pseudohept(c);
if(binarytiling) return c->type & c->master->distance & 1;
if(gp::on && gp_threecolor() == 2)
return gp::pseudohept_val(c) == 0;
if(gp::on && gp_threecolor() == 1 && (S7&1) && (S3 == 3))
@ -2010,7 +2018,7 @@ namespace linepatterns {
case patTree:
if(is_master(c)) {
cell *c2 = c->master->move[0]->c7;
cell *c2 = c->master->move[binarytiling ? 5 : 0]->c7;
if(gmatrix.count(c2)) queuelinef(tC0(V), gmatrix[c2]*C0, col, 2 + vid.linequality);
}
break;

View File

@ -1622,6 +1622,8 @@ void buildpolys() {
last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW | POLY_ISSIDE;
}
if(binarytiling) hexvdist = rhexf = 1, tessf = 1, gp::scale = 1, scalef = 1, crossf *= .8;
double floorrad0 = hexvdist*0.92;
double floorrad1 = rhexf / gp::scale *0.94;
@ -1722,21 +1724,32 @@ void buildpolys() {
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, floorrad0*7/8 * gp::scale) * C0);
}
bshape(shWall[0], PPR_WALL);
for(int t=0; t<=S6; t++) {
hpcpush(ddi(S7 + t*S14, floorrad0 * goldbf) * C0);
if(t != S6) hpcpush(ddi(S14 + t*S14, floorrad0 * goldbf/4) * C0);
}
bshape(shWall[1], PPR_WALL);
if(S7 == 6 || S7 == 4) {
for(int t=0; t<=S6; t++) {
hpcpush(ddi(S7 + t*S14, floorrad1 * goldbf) * C0);
if(t != S6) hpcpush(ddi(S14 + t*S14, floorrad1 * goldbf/4) * C0);
if(binarytiling) {
for(int i=0; i<2; i++) {
bshape(shWall[i], PPR_WALL);
horopoint(log(2)/8, .1);
horopoint(log(2)/8, -.1);
horopoint(-log(2)/8, 0);
}
}
else
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S36+td, floorrad1 * goldbf) * C0);
else {
bshape(shWall[0], PPR_WALL);
for(int t=0; t<=S6; t++) {
hpcpush(ddi(S7 + t*S14, floorrad0 * goldbf) * C0);
if(t != S6) hpcpush(ddi(S14 + t*S14, floorrad0 * goldbf/4) * C0);
}
bshape(shWall[1], PPR_WALL);
if(S7 == 6 || S7 == 4) {
for(int t=0; t<=S6; t++) {
hpcpush(ddi(S7 + t*S14, floorrad1 * goldbf) * C0);
if(t != S6) hpcpush(ddi(S14 + t*S14, floorrad1 * goldbf/4) * C0);
}
}
else
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S36+td, floorrad1 * goldbf) * C0);
}
bshape(shCross, PPR_WALL);
for(int i=0; i<=84; i+=7)

View File

@ -3374,6 +3374,8 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
}
}
if(binarytiling) return binary::relative_matrix(c2->master, c1->master);
if(torus) {
transmatrix t = Id;
if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));

View File

@ -1165,7 +1165,7 @@ void switch_game_mode(char switchWhat) {
case rg::bitrunc:
case rg::gp:
if(euclid6) geometry = gNormal;
if(euclid6 || binarytiling) geometry = gNormal;
nonbitrunc = !nonbitrunc; irr::on = false;
gp::on = (switchWhat == rg::gp && !gp::on);
need_reset_geometry = true;
@ -1191,6 +1191,7 @@ void switch_game_mode(char switchWhat) {
if(gp::param.second && gp::param.second != gp::param.first)
gp::param.second = 0;
}
if(geometry == gBinaryTiling) nonbitrunc = true, gp::on = irr::on = false;
need_reset_geometry = true;
#if CAP_TEXTURE

View File

@ -313,6 +313,31 @@ void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const trans
}
}
else if(binarytiling) {
mi.M = T;
mi.triangles.clear();
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
hyperpoint vertices[8];
vertices[0] = get_horopoint(-yy, xx);
vertices[1] = get_horopoint(yy, 2*xx);
vertices[2] = get_horopoint(yy, xx);
vertices[3] = get_horopoint(yy, 0);
vertices[4] = get_horopoint(yy, -xx);
vertices[5] = get_horopoint(yy, -2*xx);
vertices[6] = get_horopoint(-yy, -xx);
vertices[7] = get_horopoint(-yy, 0);
for(int i=0; i<8; i++) {
hyperpoint h1 = vertices[i];
hyperpoint h2 = vertices[(i+1)%8];
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
}
else {
mi.M = T * applyPatterndir(c, si);