mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 22:12:59 +00:00 
			
		
		
		
	kite-and-dart tiling
This commit is contained in:
		| @@ -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,6 +561,8 @@ 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" | ||||
|   | ||||
| @@ -440,6 +440,8 @@ void initConfig() { | ||||
|   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); | ||||
|   addsaver(vid.sloppy_3d, "sloppy3d", true); | ||||
|   | ||||
| @@ -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); | ||||
| @@ -933,6 +935,15 @@ void geometry_information::create_wall3d() { | ||||
|     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)); | ||||
|     for(int i=0; i<isize(shWall3D); i++) { | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue