mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
kite-and-dart tiling
This commit is contained in:
parent
f72da51b38
commit
cf496e8940
@ -1158,7 +1158,7 @@ int wallchance(cell *c, bool deepOcean) {
|
||||
|
||||
bool horo_ok() {
|
||||
// do the horocycles work in the current geometry?
|
||||
return hyperbolic && !binarytiling && !archimedean;
|
||||
return hyperbolic && !binarytiling && !archimedean && !penrose;
|
||||
}
|
||||
|
||||
bool gp_wall_test() {
|
||||
@ -1208,7 +1208,7 @@ bool good_for_wall(cell *c) {
|
||||
}
|
||||
|
||||
void buildBigStuff(cell *c, cell *from) {
|
||||
if(sphere || quotient || sol) return;
|
||||
if(sphere || quotient || sol || penrose) return;
|
||||
if(chaosmode > 1) return;
|
||||
bool deepOcean = deep_ocean_at(c, from);
|
||||
|
||||
@ -1537,6 +1537,9 @@ void moreBigStuff(cell *c) {
|
||||
else if(geometry == gHoroTris || geometry == gHoroRec) {
|
||||
if(c->c.spin(S7-1) != 0) c->wall = waColumn;
|
||||
}
|
||||
else if(geometry == gKiteDart3) {
|
||||
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
|
||||
}
|
||||
else if(WDIM == 3) {
|
||||
if(c->master->zebraval != 1) c->wall = waColumn;
|
||||
}
|
||||
|
11
cell.cpp
11
cell.cpp
@ -93,6 +93,10 @@ cell *createMov(cell *c, int d) {
|
||||
}
|
||||
|
||||
if(c->move(d)) return c->move(d);
|
||||
#if CAP_BT
|
||||
else if(penrose)
|
||||
kite::find_cell_connection(c, d);
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
else if(IRREGULAR) {
|
||||
irr::link_cell(c, d);
|
||||
@ -223,6 +227,9 @@ void initcells() {
|
||||
#if MAXMDIM >= 4
|
||||
else if(euclid && WDIM == 3) currentmap = euclid3::new_map();
|
||||
#endif
|
||||
#if CAP_BT
|
||||
else if(penrose) currentmap = kite::new_map();
|
||||
#endif
|
||||
else if(fulltorus) currentmap = new hrmap_torus;
|
||||
else if(euclid) currentmap = new hrmap_euclidean;
|
||||
#if MAXMDIM >= 4
|
||||
@ -401,7 +408,7 @@ int celldist(cell *c) {
|
||||
return torusconfig::cyldist(decodeId(c->master), 0);
|
||||
if(masterless)
|
||||
return eudist(decodeId(c->master));
|
||||
if(sphere || binarytiling || WDIM == 3 || geometry == gCrystal || sol) return celldistance(c, currentmap->gamestart());
|
||||
if(sphere || binarytiling || WDIM == 3 || geometry == gCrystal || sol || penrose) return celldistance(c, currentmap->gamestart());
|
||||
#if CAP_IRR
|
||||
if(IRREGULAR) return irr::celldist(c, false);
|
||||
#endif
|
||||
@ -852,7 +859,7 @@ int celldistance(cell *c1, cell *c2) {
|
||||
if(geometry == gCrystal) return crystal::precise_distance(c1, c2);
|
||||
#endif
|
||||
|
||||
if(masterless || archimedean || quotient || sol) {
|
||||
if(masterless || archimedean || quotient || sol || penrose) {
|
||||
|
||||
if(saved_distances.count(make_pair(c1,c2)))
|
||||
return saved_distances[make_pair(c1,c2)];
|
||||
|
@ -507,6 +507,7 @@ static const flagtype qsDOCKS = qANYQ | qSMALL | qBOUNDED | qDOCKS;
|
||||
static const flagtype qsSMALLB = qSMALL | qBOUNDED;
|
||||
static const flagtype qsSMALLBF = qsSMALLB | qsFIELD;
|
||||
static const flagtype qsSMALLBE = qsSMALLB | qELLIPTIC;
|
||||
static const flagtype qsBP = qBINARY | qPENROSE;
|
||||
|
||||
vector<geometryinfo> ginf = {
|
||||
{"{7,3}", "none", "{7,3} (standard HyperRogue map)", "HR", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::bitruncated},
|
||||
@ -560,7 +561,9 @@ vector<geometryinfo> ginf = {
|
||||
{"{5,3,4}","field", "{5,3,4} field quotient space", "f435", 12, 4, qsSMALLBF, gcHyperbolic, 0x40800, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
||||
{"binary4","none", "standard binary tiling", "binary4", 5, 4, qBINARY, gcHyperbolic, 0, {{7, 5}}, eVariation::pure},
|
||||
{"sol", "none", "Sol", "sol", 8, 4, qBINARY, gcSol, 0, {{7, 5}}, eVariation::pure},
|
||||
};
|
||||
{"kd2", "none", "kite-and-dart", "kd2", 4, 3, qPENROSE, gcEuclid, 0x48000, {{7, 7}}, eVariation::pure},
|
||||
{"kd3", "none", "kite-and-dart on horospheres", "kd3", 12, 3, qsBP, gcHyperbolic, 0x48200, {{7, 3}}, eVariation::pure},
|
||||
};
|
||||
|
||||
// bits: 9, 10, 15, 16, (reserved for later) 17, 18
|
||||
|
||||
|
@ -201,6 +201,7 @@ enum eGeometry {
|
||||
gHoroTris, gHoroRec, gHoroHex,
|
||||
gField435, gField534,
|
||||
gBinary4, gSol,
|
||||
gKiteDart2, gKiteDart3,
|
||||
gGUARD};
|
||||
|
||||
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSol };
|
||||
@ -233,6 +234,7 @@ static const flagtype qZEBRA = 64;
|
||||
static const flagtype qELLIPTIC = 128;
|
||||
|
||||
static const flagtype qBINARY = 256;
|
||||
static const flagtype qPENROSE = 512;
|
||||
|
||||
// note: dnext assumes that x&7 equals 7
|
||||
static const int SEE_ALL = 50;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "fieldpattern.cpp"
|
||||
#include "heptagon.cpp"
|
||||
#include "binary-tiling.cpp"
|
||||
#include "penrose.cpp"
|
||||
#include "archimedean.cpp"
|
||||
#include "euclid.cpp"
|
||||
#include "sphere.cpp"
|
||||
|
@ -439,6 +439,8 @@ void initConfig() {
|
||||
addsaver(sightranges[gHoroTris], "sight-horotris", 2.9 + bonus);
|
||||
addsaver(sightranges[gHoroRec], "sight-hororec", 2.2 + bonus);
|
||||
addsaver(sightranges[gHoroHex], "sight-horohex", 2.75 + bonus);
|
||||
|
||||
addsaver(sightranges[gKiteDart3], "sight-kd3", 2.25 + bonus);
|
||||
|
||||
addsaver(sightranges[gField435], "sight-field435", 4 + bonus);
|
||||
addsaver(sightranges[gField534], "sight-field534", 3.8 + bonus);
|
||||
|
@ -297,7 +297,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
for(auto pfsh: all_plain_floorshapes) {
|
||||
auto& fsh = *pfsh;
|
||||
|
||||
if(STDVAR && !archimedean) {
|
||||
if(STDVAR && !archimedean && !penrose) {
|
||||
|
||||
// standard and binary
|
||||
ld hexside = fsh.rad0, heptside = fsh.rad1;
|
||||
@ -422,7 +422,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
sizeto(fsh.b, id);
|
||||
sizeto(fsh.shadow, id);
|
||||
|
||||
if(STDVAR && !binarytiling && !archimedean) {
|
||||
if(STDVAR && !binarytiling && !archimedean && !penrose) {
|
||||
generate_matrices_scale(fsh.scale, fsh.noftype);
|
||||
if(PURE && geosupport_football() < 2) {
|
||||
bshape2(fsh.b[id], fsh.prio, fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1, hept_matrices);
|
||||
@ -611,6 +611,20 @@ void geometry_information::generate_floorshapes() {
|
||||
|
||||
else if(GOLDBERG) { /* will be generated on the fly */ }
|
||||
|
||||
#if CAP_BT
|
||||
else if(penrose) {
|
||||
dynamicval<bool> ncor(approx_nearcorner, true);
|
||||
heptagon master;
|
||||
cell model;
|
||||
model.master = &master;
|
||||
model.type = 4;
|
||||
for(int i=0; i<2; i++) {
|
||||
master.s = hstate(i); /* kite/dart shape */
|
||||
generate_floorshapes_for(i, &model, 0, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CAP_ARCM
|
||||
else if(archimedean) {
|
||||
heptagon master;
|
||||
@ -750,6 +764,8 @@ int shvid(cell *c) {
|
||||
return pseudohept(c);
|
||||
else if(geometry == gBinaryTiling)
|
||||
return c->type-6;
|
||||
else if(penrose)
|
||||
return kite::getshape(c->master);
|
||||
else if(geometry == gBinary4)
|
||||
return c->master->zebraval;
|
||||
else if(PURE)
|
||||
@ -782,9 +798,9 @@ dqi_poly *draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &s
|
||||
return &queuepolyat(V, shv[arcm::id_of(c->master)], col, prio);
|
||||
}
|
||||
#endif
|
||||
else if((euclid || GOLDBERG) && ishex1(c))
|
||||
else if((euclid || GOLDBERG) && ishex1(c) && !penrose)
|
||||
return &queuepolyat(V * pispin, shv[0], col, prio);
|
||||
else if(!(S7&1) && PURE) {
|
||||
else if(!(S7&1) && PURE && !penrose) {
|
||||
auto si = patterns::getpatterninfo(c, patterns::PAT_COLORING, 0);
|
||||
if(si.id == 8) si.dir++;
|
||||
transmatrix D = applyPatterndir(c, si);
|
||||
|
@ -373,7 +373,7 @@ void ge_land_selection() {
|
||||
vector<eGeometry> tilinglist = {
|
||||
gTinySphere, gSmallSphere, gSphere, gEuclid, gNormal, gOctagon,
|
||||
gOctahedron, gEuclidSquare, g45, g46, g47,
|
||||
gArchimedean, gBinary4, gBinaryTiling
|
||||
gArchimedean, gBinary4, gBinaryTiling, gKiteDart2
|
||||
};
|
||||
|
||||
vector<eGeometry> quotientlist = {
|
||||
@ -394,7 +394,7 @@ vector<eGeometry> list3d = {
|
||||
gCell24, gECell24,
|
||||
gCell16, gECell16,
|
||||
gCell8, gECell8,
|
||||
gCell5
|
||||
gCell5, gKiteDart3
|
||||
};
|
||||
|
||||
void ge_select_tiling(const vector<eGeometry>& lst) {
|
||||
@ -635,7 +635,7 @@ void showEuclideanMenu() {
|
||||
extern void add_edit_wall_quality(char);
|
||||
add_edit_wall_quality('W');
|
||||
}
|
||||
else if(WDIM == 3) dialog::addBreak(100);
|
||||
else if(WDIM == 3 || penrose) dialog::addBreak(100);
|
||||
else {
|
||||
dialog::addSelItem(XLAT("variations"), gp::operation_name(), 'v');
|
||||
dialog::add_action([] {
|
||||
|
@ -135,7 +135,7 @@ void geometry_information::prepare_basics() {
|
||||
#endif
|
||||
#if CAP_BT
|
||||
if(binarytiling) hexvdist = rhexf = 1, tessf = 1, scalefactor = 1, crossf = hcrossf7;
|
||||
if(geometry == gHoroRec) hexvdist = rhexf = .5, tessf = .5, scalefactor = .5, crossf = hcrossf7/2;
|
||||
if(geometry == gHoroRec || penrose) hexvdist = rhexf = .5, tessf = .5, scalefactor = .5, crossf = hcrossf7/2;
|
||||
#endif
|
||||
#if CAP_BT && MAXMDIM >= 4
|
||||
if(binarytiling) binary::build_tmatrix();
|
||||
|
@ -283,7 +283,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
|
||||
|
||||
transmatrix bestV;
|
||||
|
||||
if(WDIM == 2 && !binarytiling) for(int d=0; d<S7; d++) {
|
||||
if(WDIM == 2 && !binarytiling && !penrose) for(int d=0; d<S7; d++) {
|
||||
heptspin hs(h, d, false);
|
||||
heptspin hs2 = hs + wstep;
|
||||
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * cgi.invheptmove[d];
|
||||
@ -315,7 +315,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
|
||||
at = bestV * at;
|
||||
}
|
||||
else at = master_relative(base, true) * at;
|
||||
if(binarytiling || (tohex && (GOLDBERG || IRREGULAR)) || WDIM == 3) {
|
||||
if(binarytiling || (tohex && (GOLDBERG || IRREGULAR)) || WDIM == 3 || penrose) {
|
||||
while(true) {
|
||||
newbase = NULL;
|
||||
forCellCM(c2, base) {
|
||||
@ -387,16 +387,16 @@ void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
|
||||
}
|
||||
|
||||
double cellgfxdist(cell *c, int i) {
|
||||
if(euclid) {
|
||||
if(euclid && !penrose) {
|
||||
if(c->type == 8 && (i&1)) return cgi.crossf * sqrt(2);
|
||||
return cgi.crossf;
|
||||
}
|
||||
if(NONSTDVAR || archimedean || WDIM == 3 || binarytiling) return hdist0(tC0(calc_relative_matrix(c->move(i), c, i)));
|
||||
if(NONSTDVAR || archimedean || WDIM == 3 || binarytiling || penrose) return hdist0(tC0(calc_relative_matrix(c->move(i), c, i)));
|
||||
return !BITRUNCATED ? cgi.tessf : (c->type == 6 && (i&1)) ? cgi.hexhexdist : cgi.crossf;
|
||||
}
|
||||
|
||||
transmatrix cellrelmatrix(cell *c, int i) {
|
||||
if(NONSTDVAR || archimedean) return calc_relative_matrix(c->move(i), c, i);
|
||||
if(NONSTDVAR || archimedean || penrose) return calc_relative_matrix(c->move(i), c, i);
|
||||
double d = cellgfxdist(c, i);
|
||||
transmatrix T = ddspin(c, i) * xpush(d);
|
||||
if(c->c.mirror(i)) T = T * Mirror;
|
||||
@ -407,7 +407,7 @@ transmatrix cellrelmatrix(cell *c, int i) {
|
||||
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
|
||||
|
||||
hyperpoint randomPointIn(int t) {
|
||||
if(NONSTDVAR || archimedean) {
|
||||
if(NONSTDVAR || archimedean || penrose) {
|
||||
// Let these geometries be less confusing.
|
||||
// Also easier to implement ;)
|
||||
return xspinpush0(2 * M_PI * randd(), asinh(randd() / 20));
|
||||
@ -432,6 +432,7 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
|
||||
}
|
||||
#endif
|
||||
#if CAP_BT
|
||||
if(penrose) return kite::get_corner(c, cid, cf);
|
||||
if(binarytiling) {
|
||||
if(WDIM == 3) {
|
||||
println(hlog, "get_corner_position called");
|
||||
@ -473,6 +474,8 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
|
||||
return C0;
|
||||
}
|
||||
|
||||
bool approx_nearcorner = false;
|
||||
|
||||
hyperpoint nearcorner(cell *c, int i) {
|
||||
if(GOLDBERG) {
|
||||
cellwalker cw(c, i);
|
||||
@ -521,6 +524,13 @@ hyperpoint nearcorner(cell *c, int i) {
|
||||
neis[4] = binary::get_horopoint(0, -1);
|
||||
return neis[i];
|
||||
}
|
||||
if(penrose) {
|
||||
using namespace hyperpoint_vec;
|
||||
if(approx_nearcorner)
|
||||
return kite::get_corner(c, i, 3) + kite::get_corner(c, i+1, 3) - C0;
|
||||
else
|
||||
return calc_relative_matrix(c->move(i), c, C0) * C0;
|
||||
}
|
||||
if(binarytiling) {
|
||||
if(WDIM == 3) {
|
||||
println(hlog, "nearcorner called");
|
||||
@ -577,7 +587,7 @@ hyperpoint farcorner(cell *c, int i, int which) {
|
||||
}
|
||||
#endif
|
||||
#if CAP_BT
|
||||
if(binarytiling)
|
||||
if(binarytiling || penrose)
|
||||
return nearcorner(c, (i+which) % c->type); // lazy
|
||||
#endif
|
||||
#if CAP_ARCM
|
||||
|
12
graph.cpp
12
graph.cpp
@ -361,13 +361,13 @@ double hexshiftat(cell *c) {
|
||||
|
||||
transmatrix ddspin(cell *c, int d, ld bonus) {
|
||||
if(WDIM == 3 && d < c->type) return rspintox(tC0(calc_relative_matrix(c->move(d), c, C0))) * cspin(2, 0, bonus);
|
||||
if(WDIM == 2 && binarytiling) return spin(bonus) * rspintox(nearcorner(c, d));
|
||||
if(WDIM == 2 && (binarytiling || penrose)) return spin(bonus) * rspintox(nearcorner(c, d));
|
||||
return spin(displayspin(c, d) + bonus - hexshiftat(c));
|
||||
}
|
||||
|
||||
transmatrix iddspin(cell *c, int d, ld bonus) {
|
||||
if(WDIM == 3 && d < c->type) return cspin(0, 2, bonus) * spintox(tC0(calc_relative_matrix(c->move(d), c, C0)));
|
||||
if(WDIM == 2 && binarytiling) return spin(bonus) * spintox(nearcorner(c, d));
|
||||
if(WDIM == 2 && (binarytiling || penrose)) return spin(bonus) * spintox(nearcorner(c, d));
|
||||
return spin(hexshiftat(c) - displayspin(c, d) + bonus);
|
||||
}
|
||||
|
||||
@ -3956,9 +3956,10 @@ bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, color_t co
|
||||
else if(sidepar == SIDE_BTOI) prio = PPR::BELOWBOTTOM;
|
||||
else prio = PPR::REDWALL-2+4*(sidepar-SIDE_SLEV);
|
||||
|
||||
dynamicval<bool> ncor(approx_nearcorner, true);
|
||||
transmatrix V2 = V * ddspin(c, i);
|
||||
|
||||
if(binarytiling || archimedean || NONSTDVAR) {
|
||||
if(binarytiling || archimedean || NONSTDVAR || penrose) {
|
||||
#if CAP_ARCM
|
||||
if(archimedean && !PURE)
|
||||
i = (i + arcm::parent_index_of(c->master)/DUALMUL + MODFIXER) % c->type;
|
||||
@ -4399,12 +4400,14 @@ int get_darkval(int d) {
|
||||
const int darkval_hh[14] = {0,0,0,1,1,1,2,2,2,3,3,3,1,0};
|
||||
const int darkval_hrec[7] = {0,0,2,4,2,4,0};
|
||||
const int darkval_sol[8] = {0,2,4,5,0,2,4,5};
|
||||
const int darkval_penrose[12] = {0, 2, 0, 2, 4, 4, 6, 6, 6, 6, 6, 6};
|
||||
if(sphere) return darkval_s12[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];
|
||||
if(geometry == gHoroHex) return darkval_hh[d];
|
||||
if(geometry == gHoroRec) return darkval_hrec[d];
|
||||
if(penrose) return darkval_penrose[d];
|
||||
if(binarytiling) return darkval_hbt[d];
|
||||
if(hyperbolic && S7 == 6) return darkval_e6[d];
|
||||
if(hyperbolic && S7 == 12) return darkval_s12[d];
|
||||
@ -4518,6 +4521,7 @@ void radar_grid(cell *c, const transmatrix& V) {
|
||||
}
|
||||
|
||||
int wall_offset(cell *c) {
|
||||
if(penrose && kite::getshape(c->master) == kite::pKite) return 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5952,7 +5956,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
for(int a=0; a<c->type; a++)
|
||||
if(c->move(a) && !isWall3(c->move(a), dummy)) {
|
||||
if(pmodel == mdPerspective && !sphere && !quotient && !sol) {
|
||||
if(pmodel == mdPerspective && !sphere && !quotient && !sol && !penrose) {
|
||||
if(a < 4 && among(geometry, gHoroTris, gBinary3) && celldistAlt(c) >= celldistAlt(viewctr.at->c7)) continue;
|
||||
else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewctr.at->c7)) continue;
|
||||
else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue;
|
||||
|
15
hyper.h
15
hyper.h
@ -103,6 +103,7 @@ void addMessage(string s, char spamtype = 0);
|
||||
|
||||
#define binarytiling (ginf[geometry].flags & qBINARY)
|
||||
#define archimedean (geometry == gArchimedean)
|
||||
#define penrose (ginf[geometry].flags & qPENROSE)
|
||||
|
||||
// these geometries do not feature alternate structures for horocycles
|
||||
#define eubinary (euclid || binarytiling || geometry == gCrystal)
|
||||
@ -327,7 +328,7 @@ extern videopar vid;
|
||||
#if MAXMDIM == 3
|
||||
#define WDIM 2
|
||||
#else
|
||||
#define WDIM ((geometry >= gBinary3 && geometry != gBinary4) ? 3 : 2)
|
||||
#define WDIM ((geometry >= gBinary3 && geometry != gBinary4 && geometry != gKiteDart2) ? 3 : 2)
|
||||
#endif
|
||||
#define GDIM (vid.always3 ? 3 : WDIM)
|
||||
#define DIM GDIM
|
||||
@ -1609,7 +1610,7 @@ bool bearsCamelot(eLand l);
|
||||
extern bool safety;
|
||||
|
||||
#define SAGEMELT .1
|
||||
#define TEMPLE_EACH (among(geometry, gHoroRec, gHoroHex) ? 3 : (WDIM == 3 && binarytiling) ? 2 : geometry == gSpace435 ? 4 : (WDIM == 3 && hyperbolic) ? 3 : 6)
|
||||
#define TEMPLE_EACH (among(geometry, gHoroRec, gHoroHex, gKiteDart3) ? 3 : (WDIM == 3 && binarytiling) ? 2 : geometry == gSpace435 ? 4 : (WDIM == 3 && hyperbolic) ? 3 : 6)
|
||||
#define PT(x, y) ((tactic::on || quotient == 2 || daily::on) ? (y) : inv::on ? min(2*(y),x) : (x))
|
||||
#define ROCKSNAKELENGTH 50
|
||||
#define WORMLENGTH 15
|
||||
@ -5613,4 +5614,14 @@ int wingphase(int period, int phase = 0);
|
||||
|
||||
void queuecircle(int x, int y, int size, color_t color, PPR prio = PPR::CIRCLE, color_t fillcolor = 0);
|
||||
|
||||
#if CAP_BT
|
||||
namespace kite {
|
||||
hrmap *new_map();
|
||||
void find_cell_connection(cell *c, int d);
|
||||
enum pshape {pDart, pKite};
|
||||
pshape getshape(heptagon *h);
|
||||
pair<vector<vector<hyperpoint>>, vector<vector<ld>>> make_walls();
|
||||
hyperpoint get_corner(cell *c, int d, ld cf);
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1317,9 +1317,10 @@ void optimizeview() {
|
||||
if(0) ;
|
||||
|
||||
#if CAP_BT || CAP_ARCM || MAXMDIM == 4
|
||||
else if(binarytiling || archimedean || WDIM == 3) {
|
||||
else if(binarytiling || archimedean || penrose || WDIM == 3) {
|
||||
turn = -1, best = hdist0(tC0(View));
|
||||
for(int i=0; i<viewctr.at->c7->type; i++) {
|
||||
for(int i=0; i<viewctr.at->type; i++) {
|
||||
if(penrose && euclid && (i < 4 || i >= 8)) continue;
|
||||
int i1 = i * DUALMUL;
|
||||
heptagon *h2 = createStep(viewctr.at, i1);
|
||||
transmatrix T = currentmap->relative_matrix(h2, viewctr.at);
|
||||
|
@ -2523,7 +2523,7 @@ void setdist(cell *c, int d, cell *from) {
|
||||
cell *cseek = c;
|
||||
int step = 0;
|
||||
if(geometry == gHoroHex) z *= 2;
|
||||
while(z < 3.999 && step < 10) cseek = cseek->cmove(S7-1), z *= 2;
|
||||
while(z < 3.999 && step < 10) cseek = cseek->cmove(penrose ? 4 : S7-1), z *= 2;
|
||||
if(cseek->master->emeraldval) setland(c, eLand(cseek->master->emeraldval));
|
||||
}
|
||||
|
||||
|
@ -1126,11 +1126,13 @@ bool geosupport_chessboard() {
|
||||
(archimedean && PURE) ? arcm::current.support_chessboard() :
|
||||
(archimedean && DUAL) ? arcm::current.support_threecolor_bitruncated() :
|
||||
#endif
|
||||
(binarytiling || penrose) ? 0 :
|
||||
(VALENCE % 2 == 0);
|
||||
}
|
||||
|
||||
int geosupport_threecolor() {
|
||||
if(IRREGULAR) return 0;
|
||||
if(penrose || binarytiling) return 0;
|
||||
#if CAP_ARCM
|
||||
if(archimedean && PURE) return arcm::current.support_threecolor();
|
||||
if(archimedean && BITRUNCATED) return arcm::current.support_threecolor_bitruncated();
|
||||
@ -1150,6 +1152,7 @@ int geosupport_threecolor() {
|
||||
int geosupport_football() {
|
||||
// always works in bitrunc geometries
|
||||
if(BITRUNCATED) return 2;
|
||||
if(binarytiling || penrose) return 0;
|
||||
|
||||
#if CAP_ARCM
|
||||
if(archimedean && DUAL) return false;
|
||||
@ -1293,6 +1296,7 @@ bool pseudohept(cell *c) {
|
||||
if(IRREGULAR) return irr::pseudohept(c);
|
||||
#endif
|
||||
#if CAP_BT
|
||||
if(penrose) return kite::getshape(c->master) == kite::pDart;
|
||||
if(binarytiling) return binary::pseudohept(c);
|
||||
#endif
|
||||
#if MAXMDIM == 4
|
||||
|
436
penrose.cpp
Normal file
436
penrose.cpp
Normal file
@ -0,0 +1,436 @@
|
||||
// Hyperbolic Rogue -- Kite-and-dart tiling
|
||||
// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details
|
||||
|
||||
namespace hr {
|
||||
|
||||
namespace kite {
|
||||
#if CAP_BT
|
||||
|
||||
transmatrix meuscale(ld z) {
|
||||
if(euclid) {
|
||||
transmatrix T = Id;
|
||||
T[0][0] = z;
|
||||
T[1][1] = z;
|
||||
return T;
|
||||
}
|
||||
else
|
||||
return xpush(log(z));
|
||||
}
|
||||
|
||||
transmatrix mspin(ld alpha) {
|
||||
if(euclid)
|
||||
return spin(alpha);
|
||||
else
|
||||
return cspin(1, 2, alpha);
|
||||
}
|
||||
|
||||
const ld euscale = 0.5;
|
||||
|
||||
transmatrix meupush(ld x, ld y) {
|
||||
if(euclid)
|
||||
return eupush(euscale * x, euscale * y);
|
||||
else
|
||||
return binary::parabolic3(x, y);
|
||||
}
|
||||
|
||||
hyperpoint mhpxy(ld x, ld y) {
|
||||
if(euclid) return hpxy(euscale * x, euscale * y);
|
||||
else return binary::parabolic3(x, y) * C0;
|
||||
}
|
||||
|
||||
const ld phi = (1 + sqrt(5)) / 2;
|
||||
const ld rphi = 1 / phi;
|
||||
|
||||
const ld down = 1 / tan(36 * degree);
|
||||
const ld up = 1 / tan(72 * degree);
|
||||
|
||||
const ld dart_center = (down + 2 * up) / 3;
|
||||
const ld kite_center = up;
|
||||
|
||||
pshape getshape(heptagon *h) { return pshape(h->s); }
|
||||
|
||||
hyperpoint get_corner(cell *c, int d, ld cf) {
|
||||
bool kite = getshape(c->master) == pKite;
|
||||
int t = kite ? 1 : -1;
|
||||
ld shf = kite ? kite_center : dart_center;
|
||||
|
||||
ld mul = 3/cf;
|
||||
|
||||
switch(d & 3) {
|
||||
case 0: return mhpxy(-mul, (shf)*mul);
|
||||
case 1: return mhpxy(0, (shf-down)*mul);
|
||||
case 2: return mhpxy(+mul, shf*mul);
|
||||
case 3: return mhpxy(0, (shf + t*up)*mul);
|
||||
}
|
||||
|
||||
return C0; /* unreachable! */
|
||||
}
|
||||
|
||||
pair<vector<vector<hyperpoint>>, vector<vector<ld>>> make_walls() {
|
||||
|
||||
vector<vector<hyperpoint>> kv;
|
||||
vector<vector<ld>> weights;
|
||||
|
||||
for(pshape sh: {pDart, pKite}) {
|
||||
bool kite = sh == pKite;
|
||||
|
||||
int t = kite ? 1 : -1;
|
||||
|
||||
ld shf = kite ? kite_center : dart_center;
|
||||
|
||||
hyperpoint left = mhpxy(-1, shf);
|
||||
hyperpoint right = mhpxy( 1, shf);
|
||||
hyperpoint top = mhpxy( 0, shf + t*up);
|
||||
hyperpoint bottom = mhpxy( 0, shf-down);
|
||||
hyperpoint dleft = meupush(-1, shf) * meuscale(rphi) * C0;
|
||||
hyperpoint dright = meupush( 1, shf) * meuscale(rphi) * C0;
|
||||
hyperpoint dtop = meupush( 0, shf+t*up) * meuscale(rphi) * C0;
|
||||
hyperpoint dbottom = meupush( 0, shf-down) * meuscale(rphi) * C0;
|
||||
|
||||
hyperpoint dleftmid = (!kite) ? meupush(0, shf-down) * meuscale(rphi) * meupush(-1, down) * C0 : meupush(0, shf-down) * meuscale(rphi) * mspin(-36 * degree) * meupush(0, down - up) * C0;
|
||||
hyperpoint drightmid = (!kite) ? meupush(0, shf-down) * meuscale(rphi) * meupush(1, down) * C0 : meupush(0, shf-down) * meuscale(rphi) * mspin(36 * degree) * meupush(0, down - up) * C0;
|
||||
|
||||
hyperpoint dcenter = meupush( 0, shf-up) * meuscale(rphi) * C0;
|
||||
|
||||
auto pw = [&] (int id, const vector<hyperpoint> v, const vector<ld> w) { kv.push_back(v); weights.push_back(w); };
|
||||
|
||||
pw(0, {left, bottom, dbottom, dleftmid, dleft}, {1,1,1,1,1});
|
||||
pw(1, {bottom, right, dright, drightmid, dbottom}, {1,1,1,1,1});
|
||||
pw(2, {right, top, dtop, dright}, {1,1,1,1});
|
||||
pw(3, {top, left, dleft, dtop}, {1,1,1,1});
|
||||
|
||||
ld b = 10; // big weight
|
||||
|
||||
pw(4, {left, bottom, top}, {1,b,b});
|
||||
pw(5, {right, bottom, top}, {1,b,b});
|
||||
|
||||
if(kite) {
|
||||
pw(6, {dcenter, drightmid, dright}, {b,1,1});
|
||||
pw(7, {dcenter, dright, dtop}, {b,1,1});
|
||||
pw(8, {dcenter, dleft, dleftmid}, {b,1,1});
|
||||
pw(9, {dcenter, dtop, dleft}, {b,1,1});
|
||||
pw(10,{dbottom, drightmid, dcenter}, {1,1,b});
|
||||
pw(11,{dbottom, dcenter, dleftmid}, {1,b,1});
|
||||
}
|
||||
else {
|
||||
pw(6, {dbottom, dtop, dleftmid}, {1,b,1});
|
||||
pw(7, {dbottom, drightmid, dtop}, {1,1,b});
|
||||
pw(8, {dleftmid, dtop, dleft}, {b,b,1});
|
||||
pw(9, {drightmid, dright, dtop}, {b,1,b});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {kv, weights};
|
||||
}
|
||||
|
||||
inline void print(hstream& hs, pshape sh) { print(hs, sh == pKite ? "pKite" : "pDart"); }
|
||||
|
||||
struct hrmap_kite : hrmap {
|
||||
|
||||
transmatrix pKite1, pKite2, pKite3, pDart1, pDart2, ipKite1, ipKite2, ipKite3, ipDart1, ipDart2;
|
||||
|
||||
heptagon *origin;
|
||||
|
||||
heptagon *getOrigin() override { return origin; }
|
||||
|
||||
heptagon *newtile(pshape s, int dist) {
|
||||
heptagon *h = tailored_alloc<heptagon> (8);
|
||||
h->s = hstate(s);
|
||||
h->dm4 = h->distance = dist;
|
||||
if(binarytiling || dist == 0)
|
||||
h->c7 = newCell(euclid ? 4 : s == pKite ? 12 : 10, h);
|
||||
else
|
||||
h->c7 = NULL;
|
||||
h->zebraval = 0;
|
||||
h->emeraldval = 0;
|
||||
h->fieldval = 0;
|
||||
h->cdata = NULL;
|
||||
h->alt = NULL;
|
||||
return h;
|
||||
}
|
||||
|
||||
heptagon *hspawn(heptagon *of, int our, int their, pshape s) {
|
||||
auto h = newtile(s, of->distance + (our ? 1 : -1));
|
||||
of->c.connect(our, h, their, false);
|
||||
return h;
|
||||
}
|
||||
|
||||
heptagon *create_step(heptagon *of, int dir) {
|
||||
if(of->move(dir)) return of->move(dir);
|
||||
|
||||
auto sh = getshape(of);
|
||||
|
||||
if(sh == pKite && dir == 0) return hspawn(of, 0, 1, pKite);
|
||||
if(sh == pKite && dir == 1) return hspawn(of, 1, 0, pKite);
|
||||
if(sh == pKite && dir == 2) return hspawn(of, 2, 0, pKite);
|
||||
if(sh == pKite && dir == 3) return hspawn(of, 3, 0, pDart);
|
||||
|
||||
if(sh == pDart && dir == 1) return hspawn(of, 1, 0, pKite);
|
||||
if(sh == pDart && dir == 2) return hspawn(of, 2, 0, pDart);
|
||||
if(sh == pDart && dir == 3) of->c.connect(3, of, 3, false); /* illegal */
|
||||
|
||||
/* generated by findmore */
|
||||
|
||||
#define RULEFOR(sh0, dir0, z, dir1) if(sh == sh0 && dir == dir0) { heptagon *at = of; if(z true) of->c.connect(dir0, at, dir1, false); }
|
||||
#define GO(our, shape) (at = at->cmove(our)) && getshape(at) == shape &&
|
||||
#define GOIF(our, shape, their) at->cmove(our) && at->c.spin(our) == their && getshape(at->move(our)) == shape && (at = at->move(our), true) &&
|
||||
|
||||
RULEFOR(pDart, 5, GOIF(0, pDart, 2) GO(4, pKite) GO(3, pDart), 4)
|
||||
RULEFOR(pDart, 5, GOIF(0, pDart, 2) GO(4, pDart) GO(6, pKite) GO(2, pKite), 5)
|
||||
RULEFOR(pDart, 5, GOIF(0, pDart, 2) GO(7, pKite) GO(6, pKite) GO(2, pKite), 5)
|
||||
RULEFOR(pDart, 5, GOIF(0, pKite, 3) GO(5, pKite) GO(3, pDart), 4)
|
||||
RULEFOR(pDart, 5, GOIF(0, pKite, 3) GO(5, pDart) GO(6, pKite) GO(2, pKite), 5)
|
||||
RULEFOR(pDart, 4, GOIF(0, pDart, 2) GO(7, pKite) GO(1, pKite), 4)
|
||||
RULEFOR(pDart, 4, GOIF(0, pKite, 3) GO(4, pDart) GO(2, pDart), 5)
|
||||
RULEFOR(pDart, 4, GOIF(0, pKite, 3) GO(4, pKite) GO(3, pDart), 5)
|
||||
RULEFOR(pDart, 6, GOIF(0, pDart, 2) GO(4, pDart) GO(1, pKite), 6)
|
||||
RULEFOR(pDart, 6, GOIF(0, pDart, 2) GO(4, pKite) GO(1, pKite), 6)
|
||||
RULEFOR(pDart, 6, GOIF(0, pKite, 3) GO(5, pDart) GO(1, pKite), 6)
|
||||
RULEFOR(pDart, 6, GOIF(0, pKite, 3) GO(5, pKite) GO(1, pKite), 6)
|
||||
RULEFOR(pDart, 7, GOIF(0, pDart, 2) GO(1, pKite), 7)
|
||||
RULEFOR(pDart, 7, GOIF(0, pKite, 3) GO(2, pKite), 7)
|
||||
RULEFOR(pKite, 5, GOIF(0, pDart, 1) GO(5, pDart) GO(1, pKite), 4)
|
||||
RULEFOR(pKite, 5, GOIF(0, pDart, 1) GO(5, pKite) GO(2, pKite), 4)
|
||||
RULEFOR(pKite, 5, GOIF(0, pKite, 1) GO(4, pDart) GO(1, pKite), 4)
|
||||
RULEFOR(pKite, 5, GOIF(0, pKite, 1) GO(4, pKite) GO(2, pKite), 4)
|
||||
RULEFOR(pKite, 5, GOIF(0, pKite, 2) GO(6, pKite) GO(1, pKite), 4)
|
||||
RULEFOR(pKite, 5, GOIF(0, pKite, 2) GO(6, pDart) GO(5, pDart) GO(2, pDart), 5)
|
||||
RULEFOR(pKite, 5, GOIF(0, pKite, 2) GO(6, pDart) GO(5, pKite) GO(3, pDart), 5)
|
||||
RULEFOR(pKite, 5, GOIF(0, pKite, 2) GO(7, pKite) GO(7, pDart) GO(2, pDart), 5)
|
||||
RULEFOR(pKite, 4, GOIF(0, pDart, 1) GO(4, pDart) GO(1, pKite), 5)
|
||||
RULEFOR(pKite, 4, GOIF(0, pDart, 1) GO(4, pKite) GO(1, pKite), 5)
|
||||
RULEFOR(pKite, 4, GOIF(0, pKite, 1) GO(7, pDart) GO(2, pDart), 4)
|
||||
RULEFOR(pKite, 4, GOIF(0, pKite, 1) GO(7, pKite) GO(2, pKite), 5)
|
||||
RULEFOR(pKite, 4, GOIF(0, pKite, 2) GO(5, pDart) GO(1, pKite), 5)
|
||||
RULEFOR(pKite, 4, GOIF(0, pKite, 2) GO(5, pKite) GO(1, pKite), 5)
|
||||
RULEFOR(pKite, 6, GOIF(0, pDart, 1) GO(5, pDart) GO(2, pDart), 6)
|
||||
RULEFOR(pKite, 6, GOIF(0, pDart, 1) GO(5, pKite) GO(3, pDart), 6)
|
||||
RULEFOR(pKite, 6, GOIF(0, pKite, 1) GO(4, pDart) GO(2, pDart), 6)
|
||||
RULEFOR(pKite, 6, GOIF(0, pKite, 1) GO(4, pKite) GO(3, pDart), 6)
|
||||
RULEFOR(pKite, 6, GOIF(0, pKite, 2) GO(1, pKite), 7)
|
||||
RULEFOR(pKite, 7, GOIF(0, pDart, 1) GO(2, pDart), 7)
|
||||
RULEFOR(pKite, 7, GOIF(0, pKite, 1) GO(2, pKite), 6)
|
||||
RULEFOR(pKite, 7, GOIF(0, pKite, 2) GO(3, pDart), 7)
|
||||
|
||||
#undef RULEFOR
|
||||
#undef GO
|
||||
#undef GOIF
|
||||
|
||||
return of->move(dir);
|
||||
}
|
||||
|
||||
map<int, transmatrix> graphrules;
|
||||
|
||||
auto encode(pshape s0, int d0, pshape s1, int d1) {
|
||||
return d0 + d1 * 16 + s0 * 256 + s1 * 512;
|
||||
}
|
||||
|
||||
void graphrule(pshape s0, int d0, pshape s1, int d1, transmatrix T) {
|
||||
graphrules[encode(s0, d0, s1, d1)] = T;
|
||||
}
|
||||
|
||||
void make_graphrules() {
|
||||
pKite1 = meupush(-1, kite_center + 0) * mspin(108 * degree) * meuscale(rphi) * meupush(0, down - kite_center);
|
||||
pKite2 = meupush(1, kite_center + 0) * mspin(-108 * degree) * meuscale(rphi) * meupush(0, down - kite_center);
|
||||
pKite3 = meupush(0, kite_center - down) * mspin(36 * degree) * meuscale(rphi) * meupush(0, down - dart_center);
|
||||
|
||||
pDart1 = meupush(0, dart_center-down) * meuscale(rphi) * meupush(0, down - kite_center);
|
||||
pDart2 = meupush(-1, dart_center+0) * mspin((54 + 90) * degree) * meuscale(rphi) * meupush(0, down - dart_center);
|
||||
|
||||
ipKite1 = inverse(pKite1);
|
||||
ipKite2 = inverse(pKite2);
|
||||
ipKite3 = inverse(pKite3);
|
||||
|
||||
ipDart1 = inverse(pDart1);
|
||||
ipDart2 = inverse(pDart2);
|
||||
|
||||
/* generated with facelift */
|
||||
graphrule(pDart, 0, pDart, 1, ipKite3 * ipKite1 * ipKite1 * pKite2 * pKite2 * pKite3); // ipKite3 * ipKite1 * ipDart1 * pDart2 * pDart2 * pDart2);
|
||||
graphrule(pDart, 0, pKite, 0, ipDart2 * ipDart2 * pDart1 * pKite1);
|
||||
graphrule(pDart, 1, pDart, 0, ipDart2 * ipDart2 * ipDart2 * pDart1 * pKite1 * pKite3);
|
||||
graphrule(pDart, 1, pKite, 1, ipDart2 * ipKite3 * pKite1 * pKite2);
|
||||
graphrule(pDart, 2, pKite, 2, ipDart2 * ipDart2 * ipDart2 * pDart1 * pKite1 * pKite1);
|
||||
graphrule(pDart, 3, pKite, 3, ipKite3 * pKite2);
|
||||
graphrule(pKite, 0, pDart, 0, ipKite1 * ipDart1 * pDart2 * pDart2);
|
||||
graphrule(pKite, 0, pKite, 1, ipKite1 * ipKite1 * pKite2 * pKite2);
|
||||
graphrule(pKite, 1, pDart, 1, ipKite2 * ipKite1 * pKite3 * pDart2);
|
||||
graphrule(pKite, 1, pKite, 0, ipKite2 * ipKite2 * pKite1 * pKite1);
|
||||
graphrule(pKite, 2, pDart, 2, ipDart1 * ipDart2 * ipKite3 * pKite1 * pKite2 * pKite3);
|
||||
graphrule(pKite, 2, pKite, 3, ipKite2 * pKite1);
|
||||
graphrule(pKite, 3, pDart, 3, ipDart1 * pDart2);
|
||||
graphrule(pKite, 3, pKite, 2, ipKite1 * pKite2);
|
||||
|
||||
graphrule(pDart, 4, pDart, 8, ipDart2);
|
||||
graphrule(pDart, 4, pKite, 10, ipKite3);
|
||||
graphrule(pDart, 5, pDart, 9, ipKite3 * ipKite2 * ipKite1 * pKite3 * pDart2);
|
||||
graphrule(pDart, 5, pKite, 11, ipDart2 * ipDart2 * ipDart2 * pDart1 * pKite1);
|
||||
graphrule(pKite, 4, pDart, 6, ipDart1);
|
||||
graphrule(pKite, 4, pKite, 6, ipKite2);
|
||||
graphrule(pKite, 4, pKite, 9, ipKite1);
|
||||
graphrule(pKite, 5, pDart, 7, ipDart1);
|
||||
graphrule(pKite, 5, pKite, 7, ipKite2);
|
||||
graphrule(pKite, 5, pKite, 8, ipKite1);
|
||||
|
||||
graphrule(pDart, 6, pKite, 4, pDart1);
|
||||
graphrule(pDart, 7, pKite, 5, pDart1);
|
||||
graphrule(pDart, 8, pDart, 4, pDart2);
|
||||
graphrule(pDart, 9, pDart, 5, ipDart2 * ipKite3 * pKite1 * pKite2 * pKite3);
|
||||
graphrule(pKite, 6, pKite, 4, pKite2);
|
||||
graphrule(pKite, 7, pKite, 5, pKite2);
|
||||
graphrule(pKite, 8, pKite, 5, pKite1);
|
||||
graphrule(pKite, 9, pKite, 4, pKite1);
|
||||
graphrule(pKite, 10, pDart, 4, pKite3);
|
||||
graphrule(pKite, 11, pDart, 5, ipKite1 * ipDart1 * pDart2 * pDart2 * pDart2);
|
||||
}
|
||||
|
||||
const transmatrix& tmatrix(cell *c, int dir) {
|
||||
auto c1 = c->cmove(dir);
|
||||
auto code = encode(getshape(c->master), dir, getshape(c1->master), c->c.spin(dir));
|
||||
if(!graphrules.count(code)) {
|
||||
println(hlog, "rule missing: ", tuple(getshape(c->master), dir, getshape(c1->master), c->c.spin(dir)));
|
||||
throw 0;
|
||||
}
|
||||
return graphrules[code];
|
||||
}
|
||||
|
||||
/* works only for dir = 0,1,2,3 */
|
||||
transmatrix get_tmatrix(heptagon *h2, int dir, bool inverted) {
|
||||
if(dir == 0) inverted = !inverted, h2->cmove(dir), tie(dir, h2) = make_pair(h2->c.spin(dir), h2->move(dir));
|
||||
if(inverted) {
|
||||
if(dir == 1) return getshape(h2) == pKite ? ipKite1 : ipDart1;
|
||||
if(dir == 2) return getshape(h2) == pKite ? ipKite2 : ipDart2;
|
||||
return ipKite3;
|
||||
}
|
||||
else {
|
||||
if(dir == 1) return getshape(h2) == pKite ? pKite1 : pDart1;
|
||||
if(dir == 2) return getshape(h2) == pKite ? pKite2 : pDart2;
|
||||
return pKite3;
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) override {
|
||||
/* 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)
|
||||
where = get_tmatrix(h2, 0, true) * where, h2 = h2->cmove(0);
|
||||
else
|
||||
gm = gm * get_tmatrix(h1, 0, false), h1 = h1->cmove(0);
|
||||
}
|
||||
return gm * where;
|
||||
}
|
||||
|
||||
hrmap_kite() {
|
||||
make_graphrules();
|
||||
origin = newtile(pKite, 0);
|
||||
}
|
||||
|
||||
void draw() override {
|
||||
|
||||
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<c->type; i++)
|
||||
dq::enqueue(c->cmove(i)->master, V * tmatrix(c, i));
|
||||
/*
|
||||
ld err = hdist(where[h->c7->cmove(i)->master] * C0, where[h] * M * C0);
|
||||
if(err > -.01)
|
||||
println(hlog,
|
||||
" for ", make_tuple(getshape(h), i, getshape(h->c7->cmove(i)->master), h->c7->c.spin(i)),
|
||||
" error = ", format("%f", float(err)),
|
||||
" source = ", s0+source[{h->c7, h->c7->cmove(i)}]
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
~hrmap_kite() {
|
||||
clearfrom(origin);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
hrmap *new_map() { return new hrmap_kite; }
|
||||
hrmap_kite *kite_map() { return (hrmap_kite*) currentmap; }
|
||||
|
||||
void con(cell *c0, int d0, cell *c1, int d1) {
|
||||
c0->c.connect(d0, c1, d1, false);
|
||||
}
|
||||
|
||||
void find_cell_connection(cell *c, int d) {
|
||||
auto h0 = c->master;
|
||||
auto sh = getshape(h0);
|
||||
auto crule = [&] (pshape s0, int d0, pshape s1, int d1, pshape sparent, int child, int sibling, int rsibling) {
|
||||
if(sh == s0 && d == d0) {
|
||||
auto h = h0->cmove(child);
|
||||
if(getshape(h) != sparent) { printf("bad sparent\n"); exit(1); }
|
||||
if(sibling != 8) h = h->cmove(sibling);
|
||||
if(getshape(h) != s1) { printf("bad s1\n"); exit(1); }
|
||||
con(c, d0, h->c7, d1);
|
||||
// c->c.connect(d0, h->c7, d1, false);
|
||||
}
|
||||
if(sh == s1 && d == d1 && sibling == 8 && getshape(h0->cmove(0)) == s0 && h0->c.spin(0) == child)
|
||||
con(c, d1, h0->cmove(0)->c7, d0);
|
||||
// c->c.connect(d1, h0->cmove(0)->c7, d0, false);
|
||||
if(sh == s1 && d == d1 && sibling != 8 && (h0->cmove(rsibling), h0->c.spin(rsibling) == sibling) && getshape(h0->cmove(rsibling)) == sparent && getshape(h0->cmove(rsibling)->cmove(0)) == s0)
|
||||
// c->c.connect(d1, h0->cmove(sibling)->cmove(0)->c7, d0, false);
|
||||
con(c, d1, h0->cmove(rsibling)->cmove(0)->c7, d0);
|
||||
};
|
||||
|
||||
if(d < 4) {
|
||||
int dx = d;
|
||||
dx += 4;
|
||||
heptagon *h1 = h0->cmove(dx);
|
||||
dx = h0->c.spin(dx);
|
||||
dx -= 4;
|
||||
// c->c.connect(d, h1->c7, h0->c.spin(4+d)-4, false);
|
||||
con(c, d, h1->c7, dx);
|
||||
return;
|
||||
}
|
||||
|
||||
crule(pDart, 6, pKite, 4, pDart, 2, 7, 7);
|
||||
crule(pDart, 6, pKite, 4, pKite, 1, 8, 8);
|
||||
crule(pDart, 7, pKite, 5, pDart, 2, 7, 7);
|
||||
crule(pDart, 7, pKite, 5, pKite, 1, 8, 8);
|
||||
crule(pDart, 8, pDart, 4, pDart, 2, 8, 8);
|
||||
crule(pDart, 8, pDart, 4, pKite, 1, 7, 7);
|
||||
crule(pDart, 9, pDart, 5, pKite, 1, 6, 6);
|
||||
crule(pKite, 10, pDart, 4, pDart, 3, 8, 8);
|
||||
crule(pKite, 10, pDart, 4, pKite, 2, 7, 7);
|
||||
crule(pKite, 11, pDart, 5, pDart, 3, 4, 5);
|
||||
crule(pKite, 11, pDart, 5, pKite, 1, 6, 6);
|
||||
crule(pKite, 6, pKite, 4, pDart, 3, 7, 7);
|
||||
crule(pKite, 6, pKite, 4, pKite, 1, 7, 6);
|
||||
crule(pKite, 6, pKite, 4, pKite, 2, 8, 8);
|
||||
crule(pKite, 7, pKite, 5, pDart, 3, 7, 7);
|
||||
crule(pKite, 7, pKite, 5, pKite, 1, 7, 6);
|
||||
crule(pKite, 7, pKite, 5, pKite, 2, 8, 8);
|
||||
crule(pKite, 8, pKite, 5, pKite, 1, 8, 8);
|
||||
crule(pKite, 8, pKite, 5, pKite, 2, 6, 7);
|
||||
crule(pKite, 9, pKite, 4, pKite, 1, 8, 8);
|
||||
crule(pKite, 9, pKite, 4, pKite, 2, 6, 7);
|
||||
if(!c->move(d)) {
|
||||
println(hlog, "connection rule missing: ", d);
|
||||
throw "connection rule missing";
|
||||
}
|
||||
}
|
||||
|
||||
auto hooksw = addHook(hooks_swapdim, 100, [] { if(penrose && currentmap) kite_map()->make_graphrules(); });
|
||||
#endif
|
||||
}}
|
||||
|
||||
|
23
polygons.cpp
23
polygons.cpp
@ -420,22 +420,24 @@ void geometry_information::procedural_shapes() {
|
||||
#endif
|
||||
|
||||
else {
|
||||
ld rad0 = floorrad0, rad1 = floorrad1;
|
||||
if(penrose) rad0 /= 2, rad1 /= 2;
|
||||
bshape(shWall[0], PPR::WALL);
|
||||
for(int t=0; t<=S6; t++) {
|
||||
hpcpush(ddi(S7 + t*S14, floorrad0) * C0);
|
||||
if(t != S6) hpcpush(ddi(S14 + t*S14, floorrad0 /4) * C0);
|
||||
hpcpush(ddi(S7 + t*S14, rad0) * C0);
|
||||
if(t != S6) hpcpush(ddi(S14 + t*S14, rad0 /4) * C0);
|
||||
}
|
||||
|
||||
bshape(shWall[1], PPR::WALL);
|
||||
int td = ((!BITRUNCATED || euclid) && !(S7&1)) ? S42+S6 : 0;
|
||||
if(S7 == 6 || S7 == 4) {
|
||||
for(int t=0; t<=S6; t++) {
|
||||
hpcpush(ddi(S7 + t*S14, floorrad1) * C0);
|
||||
if(t != S6) hpcpush(ddi(S14 + t*S14, floorrad1/4) * C0);
|
||||
hpcpush(ddi(S7 + t*S14, rad1) * C0);
|
||||
if(t != S6) hpcpush(ddi(S14 + t*S14, rad1/4) * C0);
|
||||
}
|
||||
}
|
||||
else
|
||||
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S36+td, floorrad1) * C0);
|
||||
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S36+td, rad1) * C0);
|
||||
}
|
||||
|
||||
bshape(shCross, PPR::WALL);
|
||||
@ -751,7 +753,7 @@ vector<hyperpoint> make5(hyperpoint a, hyperpoint b, hyperpoint c) {
|
||||
void geometry_information::create_wall3d() {
|
||||
if(WDIM == 2) return;
|
||||
using namespace hyperpoint_vec;
|
||||
int howmany = S7;
|
||||
int howmany = penrose ? 22 : S7;
|
||||
shWall3D.resize(howmany);
|
||||
shPlainWall3D.resize(howmany);
|
||||
shWireframe3D.resize(howmany);
|
||||
@ -932,6 +934,15 @@ void geometry_information::create_wall3d() {
|
||||
make_wall(6, {pt(-1,+1,+1), pt(+1,+1,+1), pt(+1,00,+1), pt(-1,00,+1)});
|
||||
make_wall(7, {pt(-1,00,+1), pt(+1,00,+1), pt(+1,-1,+1), pt(-1,-1,+1)});
|
||||
}
|
||||
|
||||
if(penrose) {
|
||||
auto kv = kite::make_walls();
|
||||
for(auto& v: kv.first) for(auto& h: v) {
|
||||
h = binary::deparabolic3(h);
|
||||
h = point3(h[1], h[2], h[0] / (log(2)/2));
|
||||
}
|
||||
for(int i=0; i<isize(kv.first); i++) make_wall(i, kv.first[i], kv.second[i]);
|
||||
}
|
||||
|
||||
if(DIM == 3) {
|
||||
shMiniWall3D.resize(isize(shWall3D));
|
||||
|
@ -1149,7 +1149,7 @@ void set_geometry(eGeometry target) {
|
||||
if(DUAL && geometry != gArchimedean)
|
||||
variation = ginf[geometry].default_variation;
|
||||
#if CAP_BT
|
||||
if(binarytiling || WDIM == 3) variation = eVariation::pure;
|
||||
if(binarytiling || WDIM == 3 || penrose) variation = eVariation::pure;
|
||||
#endif
|
||||
if(DIM == 3 && old_DIM == 2 && pmodel == mdDisk) pmodel = mdPerspective;
|
||||
if(DIM == 2 && pmodel == mdPerspective) pmodel = mdDisk;
|
||||
|
Loading…
Reference in New Issue
Block a user