mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 21:42:59 +00:00 
			
		
		
		
	synt:: replaced the combinatorial building process with floating-point-based one for hyperbolic geometry too
This commit is contained in:
		| @@ -208,7 +208,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) { | ||||
|   alt->s = firststate; | ||||
|   alt->emeraldval = 0; | ||||
|   alt->zebraval = 0; | ||||
|   for(int i=0; i<MAX_EDGE; i++) alt->move(i) = NULL; | ||||
|   alt->c.clear(); | ||||
|   alt->distance = 0; | ||||
|   alt->c7 = NULL; | ||||
|   alt->alt = alt; | ||||
|   | ||||
							
								
								
									
										3
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -349,9 +349,6 @@ namespace torusconfig { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| int decodeId(heptagon* h); | ||||
| heptagon* encodeId(int id); | ||||
|  | ||||
| int euclid_getvec(int dx, int dy) { | ||||
|   if(torus) return torusconfig::getvec(dx, dy); | ||||
|   else return pair_to_vec(dx, dy); | ||||
|   | ||||
| @@ -52,12 +52,10 @@ void precalc() { | ||||
|   int vertexdegree = S6/2; | ||||
|   ld fmin, fmax;   | ||||
|  | ||||
|   if(syntetic) { | ||||
|     synt::prepare(); | ||||
|     return; | ||||
|     } | ||||
|   if(syntetic)  | ||||
|     ginf[gSyntetic].cclass = gcHyperbolic; | ||||
|  | ||||
|   if(euclid) {  | ||||
|   if(euclid) { | ||||
|     // dynamicval<eGeometry> g(geometry, gNormal); | ||||
|     // precalc(); } | ||||
|     // for(int i=0; i<S84; i++) spinmatrix[i] = spin(i * M_PI / S42); | ||||
| @@ -175,6 +173,7 @@ void precalc() { | ||||
|    | ||||
|   gp::compute_geometry();   | ||||
|   irr::compute_geometry(); | ||||
|   if(syntetic) synt::prepare(); | ||||
|   } | ||||
|  | ||||
| transmatrix ddi(ld dir, ld dist) { | ||||
|   | ||||
| @@ -307,6 +307,41 @@ void virtualRebase(cell*& base, hyperpoint& h, bool tohex) { | ||||
|   virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return h; }); | ||||
|   } | ||||
|  | ||||
| // works only in geometries similar to the standard one, and only on heptagons | ||||
| void virtualRebaseSimple(heptagon*& base, transmatrix& at) { | ||||
|  | ||||
|   while(true) { | ||||
|    | ||||
|     double currz = at[2][2]; | ||||
|      | ||||
|     heptagon *h = base; | ||||
|      | ||||
|     heptagon *newbase = NULL; | ||||
|      | ||||
|     transmatrix bestV; | ||||
|      | ||||
|     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) * invheptmove[d] * at; | ||||
|       double newz = V2[2][2]; | ||||
|       if(newz < currz) { | ||||
|         currz = newz; | ||||
|         bestV = V2; | ||||
|         newbase = hs2.at; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     if(newbase) { | ||||
|       base = newbase; | ||||
|       at = bestV; | ||||
|       continue; | ||||
|       } | ||||
|  | ||||
|     return; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| double cellgfxdist(cell *c, int i) { | ||||
|   if(gp::on || irr::on) return hdist0(tC0(calc_relative_matrix(c->move(i), c, i))); | ||||
|   return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf; | ||||
|   | ||||
							
								
								
									
										5
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -3840,5 +3840,10 @@ namespace synt { | ||||
| hyperpoint get_warp_corner(cell *c, int cid); | ||||
| hyperpoint get_corner_position(cell *c, int cid, ld cf = 3); | ||||
|  | ||||
| int decodeId(heptagon* h); | ||||
| heptagon* encodeId(int id); | ||||
|  | ||||
| void virtualRebaseSimple(heptagon*& base, transmatrix& at); | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										454
									
								
								syntetic.cpp
									
									
									
									
									
								
							
							
						
						
									
										454
									
								
								syntetic.cpp
									
									
									
									
									
								
							| @@ -2,42 +2,13 @@ namespace hr { | ||||
|  | ||||
| namespace synt { | ||||
|  | ||||
| int indent; | ||||
|  | ||||
| struct indenter { | ||||
|   indenter() { indent += 2; } | ||||
|   ~indenter() { indent -= 2; } | ||||
|   }; | ||||
|  | ||||
| void doindent() { fflush(stdout); for(int i=0; i<indent; i++) printf(" "); } | ||||
|  | ||||
| bool do_sdebug = false; | ||||
|  | ||||
| #define SDEBUG(x) if(do_sdebug) { doindent(); x; fflush(stdout); } | ||||
| #define SDEBUG(x) if(debug_geometry) { doindent(); x; fflush(stdout); } | ||||
|  | ||||
| // Marek-snub | ||||
| vector<int> faces = {3, 6, 6, 6}; | ||||
| vector<int> adj = {1, 0, 2, 3}; | ||||
| vector<bool> invert = {false, false, true, false}; | ||||
|  | ||||
| /* | ||||
| vector<int> faces = {3, 6, 6, 6}; | ||||
| vector<int> adj = {1, 0, 2, 3}; | ||||
| vector<bool> invert = {false, false, false, false}; | ||||
| */ | ||||
|  | ||||
| /* | ||||
| vector<int> faces = {7, 6, 6}; | ||||
| vector<int> adj = {1, 0, 2}; | ||||
| vector<bool> invert = {false, false, false}; | ||||
| */ | ||||
|  | ||||
| /* | ||||
| vector<int> faces = {8, 8, 8}; | ||||
| vector<int> adj = {0, 1, 2}; | ||||
| vector<bool> invert = {false, false, false}; | ||||
| */ | ||||
|  | ||||
| int repetition = 1; | ||||
| int N; | ||||
|  | ||||
| @@ -50,14 +21,6 @@ vector<vector<pair<ld, ld>>> triangles; | ||||
| // 0, 2, ..., 2(N-1) = as in the symbol | ||||
| // 2N = bitruncated tile | ||||
|  | ||||
| map<heptagon*, int> create_order; | ||||
|  | ||||
| map<heptagon*, transmatrix> syntetic_gmatrix; | ||||
|  | ||||
| int nextorder = 1; | ||||
|  | ||||
| static const int PRUNED = 100; | ||||
|  | ||||
| short& id_of(heptagon *h) { | ||||
|   return h->zebraval; | ||||
|   } | ||||
| @@ -74,27 +37,9 @@ int neighbors_of(heptagon *h) { | ||||
|   return isize(triangles[id_of(h)]); | ||||
|   } | ||||
|  | ||||
| // right_sibling_of(h) has the same distance ('right sibling'), then we have some at smaller or equal distance, | ||||
| // parents_of(h) has the same distance again ('left sibling'), and then we have vertices at bigger distance, | ||||
| // who are our 'children' except the rightmost one which is typically a child of the right sibling | ||||
|  | ||||
| short& right_sibling_of(heptagon *h) { | ||||
|   return h->fiftyval; | ||||
|   } | ||||
|  | ||||
| int parents_of(heptagon *h) { | ||||
|   return h->s; | ||||
|   } | ||||
|  | ||||
| int children_of(heptagon *h) { | ||||
|   return right_sibling_of(h) - 1 - parents_of(h); | ||||
|   } | ||||
|  | ||||
| ld edgelength; | ||||
| vector<ld> inradius, circumradius, alphas; | ||||
|  | ||||
| extern void draw_debug_map(heptagon *h); | ||||
| void draw_debug_map_exit(heptagon *h) { draw_debug_map(h); exit(1); } | ||||
| vector<ld> inradius, circumradius, alphas; | ||||
|  | ||||
| void prepare() { | ||||
|  | ||||
| @@ -248,6 +193,10 @@ void prepare() { | ||||
|    | ||||
|   } | ||||
|  | ||||
| map<heptagon*, vector<pair<heptagon*, transmatrix> > > altmap; | ||||
|  | ||||
| map<heptagon*, pair<heptagon*, transmatrix>> syntetic_gmatrix; | ||||
|  | ||||
| void initialize(heptagon *h) { | ||||
|   | ||||
|   /* initialize the root */ | ||||
| @@ -256,336 +205,111 @@ void initialize(heptagon *h) { | ||||
|   id_of(h) = 0; | ||||
|   h->c7 = newCell(isize(adjacent[0]), h); | ||||
|    | ||||
|   if(!hyperbolic) syntetic_gmatrix[h] = Id; | ||||
|   heptagon *alt = NULL; | ||||
|    | ||||
|   if(sphere) celllister cl(h->c7, 1000, 1000000, NULL); | ||||
|   if(hyperbolic) { | ||||
|     dynamicval<eGeometry> g(geometry, gNormal);  | ||||
|     alt = new heptagon; | ||||
|     alt->s = hsOrigin; | ||||
|     alt->emeraldval = 0; | ||||
|     alt->zebraval = 0; | ||||
|     alt->c.clear(); | ||||
|     alt->distance = 0; | ||||
|     alt->c7 = NULL; | ||||
|     alt->alt = alt; | ||||
|     alt->cdata = NULL; | ||||
|     newAltMap(alt);  | ||||
|     } | ||||
|  | ||||
|   transmatrix T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * Id; | ||||
|   syntetic_gmatrix[h] = make_pair(alt, T); | ||||
|   altmap[alt].emplace_back(h, T); | ||||
|    | ||||
|   base_distlimit = 0; | ||||
|   celllister cl(h->c7, 1000, 200, NULL); | ||||
|   base_distlimit = cl.dists.back(); | ||||
|   }; | ||||
|  | ||||
| void verify_distance_delta(heptagon *h, int d, int delta) { | ||||
|   if(!h->move(d)) return; | ||||
|   if(h->move(d)->distance != h->distance + delta) { | ||||
|     SDEBUG( printf("ERROR: delta H%d.%d (%d/%d)\n", create_order[h], d, h->move(d)->distance, h->distance + delta); ) | ||||
|     // exit(1); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void debug(heptagon *h) { | ||||
|   if(id_of(h) == PRUNED) return; | ||||
|   auto& p = adjacent[id_of(h)]; | ||||
|   if(h->s == hsOrigin) { | ||||
|     for(int i=0; i<isize(p); i++) verify_distance_delta(h, i, 1); | ||||
|     } | ||||
|   else { | ||||
|     int first = h->s + 1; | ||||
|     verify_distance_delta(h, 0, -1); | ||||
|     verify_distance_delta(h, first-2, -1); | ||||
|     verify_distance_delta(h, first-1, 0); | ||||
|     verify_distance_delta(h, isize(p)-1, 0); | ||||
|     for(int d=first; d<isize(p)-1; d++) verify_distance_delta(h, d, 1); | ||||
|     for(int d=0; d<isize(p); d++) if(h->move(d)) { | ||||
|       auto& p = adjacent[id_of(h)]; | ||||
|       auto uv = p[(parent_index_of(h) + d) % isize(p)]; | ||||
|       if(neighbors_of(h->move(d)) != isize(adjacent[uv.first])) { | ||||
|         SDEBUG( printf("neighbors mismatch at H%d.%d->H%d: is %d expected %d\n", create_order[h], d, create_order[h->move(d)], neighbors_of(h->move(d)), isize(adjacent[uv.first])); ) | ||||
|         draw_debug_map_exit(h); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| transmatrix adjcell_matrix(heptagon *h, int d); | ||||
|  | ||||
| heptagon *build_child(heptagon *parent, int d, int id, int pindex) { | ||||
|   indenter ind; | ||||
|   auto h = buildHeptagon1(new heptagon, parent, d, hstate(1), 0); | ||||
|   create_order[h] = nextorder++; | ||||
|   SDEBUG( printf("NEW %p.%d ~ %p.0\n", parent, d, h); ) | ||||
|   id_of(h) = id; | ||||
|   parent_index_of(h) = pindex; | ||||
|   int nei = neighbors_of(h); | ||||
|   right_sibling_of(h) = nei - 1; | ||||
|   h->distance = parent->distance + 1; | ||||
|   h->c7 = newCell(nei, h); | ||||
|   SDEBUG( printf("H%d.%d/%d ~ H%d.0/%d (state=1/NEW,id=%d,pindex=%d,distance=%d)\n", create_order[parent], d, neighbors_of(parent), create_order[h], neighbors_of(h), id, pindex, h->distance); ) | ||||
|   if(!hyperbolic) syntetic_gmatrix[h] = syntetic_gmatrix[parent] * adjcell_matrix(parent, d); | ||||
|   else { debug(h); debug(parent); }   | ||||
|   h->distance = parent->distance + 1; | ||||
|   return h; | ||||
|   } | ||||
|  | ||||
| void connectHeptagons(heptagon *h, int i, heptspin hs) { | ||||
|   if(id_of(h) == PRUNED) { h->move(i) = h; return; } | ||||
|   if(id_of(hs.at) == PRUNED) { hs.at->move(i) = hs.at; return; } | ||||
|   indenter ind; | ||||
|   SDEBUG( printf("H%d.%d/%d ~ H%d.%d/%d (state=%d,id=%d,pindex=%d,distance=%d)\n", create_order[h], i, neighbors_of(h), create_order[hs.at], hs.spin, neighbors_of(hs.at),  | ||||
|     hs.at->s, id_of(hs.at), parent_index_of(hs.at), hs.at->distance); ) | ||||
|   SDEBUG( printf("OLD %p.%d ~ %p.%d\n", h, i, hs.at, hs.spin); ) | ||||
|   if(h->move(i) == hs.at && h->c.spin(i) == hs.spin) { | ||||
|     SDEBUG( printf("WARNING: already connected\n"); ) | ||||
|     return; | ||||
|     } | ||||
|   if(h->move(i)) { | ||||
|     SDEBUG( printf("ERROR: already connected left to: H%d not H%d\n", create_order[h->move(i)], create_order[hs.at]); ) | ||||
|     draw_debug_map_exit(h); | ||||
|     SDEBUG( printf("ERROR: already connected left\n"); ) | ||||
|     exit(1); | ||||
|     } | ||||
|   if(hs.peek()) { | ||||
|     SDEBUG( printf("ERROR: already connected right to: H%d not H%d\n", create_order[hs.peek()], create_order[h]); ) | ||||
|     draw_debug_map_exit(h); | ||||
|     // exit(1); | ||||
|     SDEBUG( printf("ERROR: already connected right\n"); ) | ||||
|     exit(1); | ||||
|     } | ||||
|   h->c.connect(i, hs); | ||||
|   if(hyperbolic) { | ||||
|     debug(h); | ||||
|     debug(hs.at); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| int prune(heptagon*& h) { | ||||
|   if(!h) return 0; | ||||
|   int result = 1; | ||||
|   int n = neighbors_of(h); | ||||
|   auto h0 = h; | ||||
|   SDEBUG( printf("pruning: H%d\n", create_order[h0]); ) | ||||
|   for(int i=0; i<n; i++)  | ||||
|     if(h0->move(i)) { | ||||
|       if(h0->c.spin(i) == 0) | ||||
|         result += prune(h0->move(i)); | ||||
|       else { | ||||
|         h0->move(i)->move(h0->c.spin(i)) = NULL; | ||||
|         h0->move(i) = NULL; | ||||
|         } | ||||
|       } | ||||
|   id_of(h0) = PRUNED; | ||||
|   /* | ||||
|   delete h0->c7; | ||||
|   delete h0; | ||||
|   */ | ||||
|   return result; | ||||
|   } | ||||
|  | ||||
| void mayprune(heptagon *hleft, heptagon *hright) { | ||||
|   if(children_of(hleft) >= 1 && children_of(hright) >= 1) | ||||
|   if(hleft->move(right_sibling_of(hleft) - 1) != hright->move(parents_of(hright)+1)) { | ||||
|     SDEBUG( printf("pruning extra children after contraction\n"); ) | ||||
|     prune(hleft->move(right_sibling_of(hleft) - 1)); | ||||
|     prune(hright->move(parents_of(hright)+1)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void contract(heptagon *h) { | ||||
|   if(id_of(h) == PRUNED) return; | ||||
|   switch(children_of(h)) { | ||||
|     case 0: { | ||||
|       SDEBUG( printf("handling contraction (0) at H%d\n", create_order[h]); ) | ||||
|       heptspin right = heptspin(h, right_sibling_of(h)) + wstep + 1; | ||||
|       heptspin left = heptspin(h, parents_of(h)) + wstep - 1; | ||||
|       connectHeptagons(right.at, right.spin, left); | ||||
|       right.at->s++; | ||||
|       right_sibling_of(left.at)--; | ||||
|       mayprune(left.at, right.at); | ||||
|       contract(right.at); | ||||
|       contract(left.at); | ||||
|       break; | ||||
|       } | ||||
|     case -1: { | ||||
|       SDEBUG( printf("handling contraction (-1) at H%d\n", create_order[h]); ) | ||||
|       indenter ind2; | ||||
|       heptspin hs0(h, neighbors_of(h)-1); | ||||
|       heptspin hs = hs0; | ||||
|       hs = hs + 1 + wstep + 1; | ||||
|       while(hs.spin == neighbors_of(hs.at) - 1) { | ||||
|         SDEBUG( printf("hsr at H%d.%d/%d (%d parents)\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); ) | ||||
|         hs = hs + wstep + 1; | ||||
|         } | ||||
|       SDEBUG( printf("hsr at H%d.%d/%d (%d parents)\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); ) | ||||
|       heptspin correct = hs + wstep; | ||||
|       SDEBUG( printf("correct is: H%d.%d/%d (%d parents)\n", create_order[correct.at], correct.spin, neighbors_of(correct.at), parents_of(correct.at)); ) | ||||
|       heptspin hsl = hs0; | ||||
|       correct = correct+1; correct.at->s++; | ||||
|       connectHeptagons(hsl.at, hsl.spin, correct); | ||||
|       hsl = hsl - 1 + wstep - 1; | ||||
|       while(true) { | ||||
|         SDEBUG( printf("hsl at %d.%d/%d (%d parents)\n", create_order[hsl.at], hsl.spin, neighbors_of(hsl.at), parents_of(hsl.at)); ) | ||||
|         if(hsl.spin == parents_of(hsl.at)) { | ||||
|           SDEBUG(printf("go left\n")) | ||||
|           hsl = hsl + wstep - 1; | ||||
|           } | ||||
|         else if(hsl.peek() && hsl.peek() != correct.at) { | ||||
|           SDEBUG(printf("prune\n");) | ||||
|           if(neighbors_of(hsl.peek()) != neighbors_of(correct.at)) { | ||||
|             SDEBUG(printf("neighbors mismatch while pruning %d -> %d\n", | ||||
|               neighbors_of(hsl.peek()), | ||||
|               neighbors_of(correct.at) | ||||
|               );) | ||||
|             draw_debug_map_exit(correct.at); | ||||
|             } | ||||
|           prune(hsl.peek()); | ||||
|           } | ||||
|         else if(hsl.peek() == NULL) { | ||||
|           correct = correct+1; correct.at->s++; | ||||
|           SDEBUG( printf("connect\n") )  | ||||
|           connectHeptagons(hsl.at, hsl.spin, correct); | ||||
|           } | ||||
|         else if(hsl.spin == parents_of(hsl.at)+1) { | ||||
|           SDEBUG( printf("single child so go left\n") ) | ||||
|           hsl = hsl - 1 + wstep - 1; | ||||
|           } | ||||
|         else { SDEBUG( printf("ready\n"); ) break; } | ||||
|         } | ||||
|       contract(correct.at); | ||||
|       break; | ||||
|       } | ||||
|     case -2: { | ||||
|       SDEBUG( printf("ERROR: contraction (-2) not handled\n"); ) | ||||
|       break; | ||||
|       } | ||||
|     } | ||||
|   if(!sphere) for(int i=0; i<neighbors_of(h); i++) if(!h->move(i)) { | ||||
|     auto uv = adjacent[id_of(h)][(parent_index_of(h) + i) % neighbors_of(h)]; | ||||
|     if(isize(adjacent[uv.first]) < 5 && hyperbolic) { | ||||
|       SDEBUG( printf("prebuilding weak neighbor\n") ) | ||||
|       createStep(h, i); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void build_siblings(heptagon *h, int x) { | ||||
|   for(int i=right_sibling_of(h); i<neighbors_of(h); i++) createStep(h, i); | ||||
|   for(int i=0; i<=parents_of(h); i++) createStep(h, i); | ||||
|   } | ||||
|  | ||||
| pair<int, int>& get_adj(heptagon *h, int cid); | ||||
| pair<ld, ld>& get_triangle(heptagon *h, int cid); | ||||
| pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0); | ||||
|  | ||||
| void create_adjacent(heptagon *h, int d) { | ||||
|  | ||||
|   if(!hyperbolic) { | ||||
|   SDEBUG( printf("%p.%d ~ ?\n", h, d); ) | ||||
|  | ||||
|     SDEBUG( printf("h=%d dist=%d d=%d/%d s=%d id=%d pindex=%d\n", | ||||
|       create_order[h], h->distance, d, neighbors_of(h), h->s, id_of(h), parent_index_of(h)); ) | ||||
|     indenter ind2; | ||||
|   auto& t1 = get_triangle(h, d); | ||||
|  | ||||
|     auto& t1 = get_triangle(h, d); | ||||
|   // * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first) | ||||
|    | ||||
|     // * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first) | ||||
|   auto& p = syntetic_gmatrix[h]; | ||||
|    | ||||
|     transmatrix T = syntetic_gmatrix[h] * spin(-t1.first) * xpush(t1.second); | ||||
|   heptagon *alt = p.first; | ||||
|  | ||||
|     for(auto gm: syntetic_gmatrix) if(intval(gm.second * C0, T * C0) < 1e-6) { | ||||
|       SDEBUG( printf("cell found\n"); ) | ||||
|       for(int d2=0; d2<gm.first->c7->type; d2++) { | ||||
|         auto& t2 = get_triangle(gm.first, d2); | ||||
|         transmatrix T1 = T * spin(M_PI + t2.first); | ||||
|         if(intval(T1 * xpush(1) * C0, gm.second * xpush(1) * C0) < 1e-6) { | ||||
|           connectHeptagons(h, d, heptspin(gm.first, d2)); | ||||
|           return; | ||||
|           } | ||||
|         } | ||||
|       SDEBUG( printf("but rotation not found\n")); | ||||
|       } | ||||
|     build_child(h, d, get_adj(h, d).first, get_adj(h, d).second); | ||||
|     return; | ||||
|     } | ||||
|  | ||||
|   if(id_of(h) == PRUNED) { h->move(d) = h; return; } | ||||
|   if(indent >= 200) draw_debug_map_exit(h); | ||||
|   indenter ind; | ||||
|   int nei = neighbors_of(h); | ||||
|   transmatrix T = p.second * spin(-t1.first) * xpush(t1.second); | ||||
|    | ||||
|   if(h->s == 0) { | ||||
|     auto& p = adjacent[id_of(h)]; | ||||
|     for(int i=0; i<nei; i++)  | ||||
|       build_child(h, i, p[i].first, p[i].second); | ||||
|     for(int i=0; i<nei; i++) { | ||||
|       heptagon *h1 = h->move(i); | ||||
|       heptagon *h2 = h->move((i+nei-1)%nei); | ||||
|       connectHeptagons(h1, 1, heptspin(h2, isize(adjacent[id_of(h2)])-1)); | ||||
|       } | ||||
|   if(hyperbolic) { | ||||
|     dynamicval<eGeometry> g(geometry, gNormal);  | ||||
|     virtualRebaseSimple(alt, T); | ||||
|     } | ||||
|    | ||||
|   else { | ||||
|     int first = h->s + 1; | ||||
|     SDEBUG( printf("h=%d dist=%d d=%d/%d s=%d id=%d pindex=%d\n", | ||||
|       create_order[h], h->distance, d, nei, h->s, id_of(h), parent_index_of(h)); ) | ||||
|     indenter ind2; | ||||
|        | ||||
|     // these vertices are not children (or possibly contractions) | ||||
|     if(d < first || d > right_sibling_of(h)) | ||||
|       connectHeptagons(h, d, heptspin(h, d-1) + wstep - 1 + wstep - 1); | ||||
|     else if(d == right_sibling_of(h)) { | ||||
|       connectHeptagons(h, d, heptspin(h, 0) + wstep + 1 + wstep + 1); | ||||
|       } | ||||
|     else { | ||||
|       build_siblings(h, 10); | ||||
|       build_siblings(h, -10); | ||||
|       if(h->move(d)) return; | ||||
|       heptspin hs(h, d); | ||||
|       // make sure no contractions on the left | ||||
|       heptspin hsl(h, d); | ||||
|       int steps = 0; | ||||
|       while(hsl.spin == parents_of(hsl.at) + 1 && steps < 100) { | ||||
|         hsl = hsl - 1 + wstep - 1; | ||||
|         steps++; | ||||
|         } | ||||
|       if(steps == 100) { | ||||
|         SDEBUG( printf("generating top\n"); ) | ||||
|         auto uv = adjacent[id_of(hs.at)][(parent_index_of(hs.at) + hs.spin) % neighbors_of(hs.at)]; | ||||
|         heptagon *newchild = build_child(hs.at, hs.spin, uv.first, uv.second); | ||||
|         hs = hs - 1 + wstep - 1; | ||||
|         while(hs.at != h) { | ||||
|           newchild->s++; | ||||
|           connectHeptagons(hs.at, hs.spin, heptspin(newchild, newchild->s-1)); | ||||
|           hs = hs - 1 + wstep - 1; | ||||
|           } | ||||
|   if(euclid)  | ||||
|     alt = encodeId(pair_to_vec(int(T[0][2]), int(T[1][2]))); | ||||
|      | ||||
|   SDEBUG( printf("look for: %p / %s\n", alt, display(T * C0)); ) | ||||
|    | ||||
|   for(auto& p: altmap[alt]) if(intval(p.second * C0, T * C0) < 1e-6) { | ||||
|     SDEBUG( printf("cell found: %p\n", p.first); ) | ||||
|     for(int d2=0; d2<p.first->c7->type; d2++) { | ||||
|       auto& t2 = get_triangle(p.first, d2); | ||||
|       transmatrix T1 = T * spin(M_PI + t2.first); | ||||
|       SDEBUG( printf("compare: %s", display(T1 * xpush(1) * C0)); ) | ||||
|       SDEBUG( printf(":: %s\n", display(p.second * xpush(1) * C0)); ) | ||||
|       if(intval(T1 * xpush(1) * C0, p.second * xpush(1) * C0) < 1e-6) {         | ||||
|         connectHeptagons(h, d, heptspin(p.first, d2)); | ||||
|         return; | ||||
|         } | ||||
|       // while trying to generate the last child, go right | ||||
|       while(true) { | ||||
|         if(h->move(d)) { | ||||
|           SDEBUG( printf("solved itself\n"); ) | ||||
|           return; | ||||
|           } | ||||
|         SDEBUG( printf("going right at H%d.%d/%d parents = %d\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); ) | ||||
|         if(id_of(hs.at) == PRUNED) { create_adjacent(h, d); return; } | ||||
|         // rightmost child | ||||
|         if(hs.spin == right_sibling_of(hs.at) - 1) | ||||
|           hs = hs + 1 + wstep + 1; | ||||
|         else if(children_of(hs.at) <= 0) { | ||||
|           SDEBUG( printf("unexpected situation\n"); ) | ||||
|           create_adjacent(h, d); | ||||
|           return; | ||||
|           } | ||||
|         else break; | ||||
|         } | ||||
|       auto uv = adjacent[id_of(hs.at)][(parent_index_of(hs.at) + hs.spin) % neighbors_of(hs.at)]; | ||||
|       heptagon *newchild = build_child(hs.at, hs.spin, uv.first, uv.second); | ||||
|       bool add_parent = false; | ||||
|       while(true) { | ||||
|         if(id_of(hs.at) == PRUNED) { create_adjacent(h, d); return; } | ||||
|         SDEBUG( printf("going left at H%d.%d/%d parents = %d\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); ) | ||||
|         // add parent | ||||
|         if(hs.spin > parents_of(hs.at) && add_parent) { | ||||
|           SDEBUG( printf("add parent\n"); ) | ||||
|           newchild->s++; | ||||
|           connectHeptagons(hs.at, hs.spin, heptspin(newchild, newchild->s-1)); | ||||
|           add_parent = false; | ||||
|           } | ||||
|         // childless | ||||
|         if(children_of(hs.at) <= 0) { | ||||
|           SDEBUG( printf("unexpected situation v2\n"); ) | ||||
|           create_adjacent(h, d); | ||||
|           return; | ||||
|           } | ||||
|         // lefmost child | ||||
|         else if(hs.spin == parents_of(hs.at)+1) { | ||||
|           SDEBUG( printf("(leftmost child)\n"); ) | ||||
|           hs = hs - 1 + wstep - 1; | ||||
|           add_parent = true; | ||||
|           } | ||||
|         // no more parents | ||||
|         else break; | ||||
|         } | ||||
|       contract(newchild); | ||||
|       } | ||||
|     SDEBUG( printf("but rotation not found\n")); | ||||
|     } | ||||
|   debug(h); | ||||
|    | ||||
|   auto& t2 = get_triangle(get_adj(h, d)); | ||||
|   transmatrix T1 = T * spin(M_PI + t2.first); | ||||
|  | ||||
|   heptagon *hnew = build_child(h, d, get_adj(h, d).first, get_adj(h, d).second); | ||||
|   altmap[alt].emplace_back(hnew, T1); | ||||
|   syntetic_gmatrix[hnew] = make_pair(alt, T1); | ||||
|   } | ||||
|  | ||||
| set<heptagon*> visited; | ||||
| @@ -613,6 +337,10 @@ pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0) { | ||||
|   return adjacent[p.first][(p.second + delta) % isize(adjacent[p.first])]; | ||||
|   } | ||||
|  | ||||
| pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta) { | ||||
|   return triangles[p.first][(p.second + delta) % isize(adjacent[p.first])]; | ||||
|   } | ||||
|  | ||||
| transmatrix adjcell_matrix(heptagon *h, int d) { | ||||
|   auto& t1 = get_triangle(h, d); | ||||
|  | ||||
| @@ -621,8 +349,6 @@ transmatrix adjcell_matrix(heptagon *h, int d) { | ||||
|   int d2 = h->c.spin(d); | ||||
|   auto& t2 = get_triangle(h2, d2); | ||||
|    | ||||
|   // * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first) | ||||
|  | ||||
|   return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first); | ||||
|   } | ||||
|  | ||||
| @@ -726,53 +452,17 @@ int readArgs() { | ||||
|     showstartmenu = false; | ||||
|     shift(); parse_symbol(args()); | ||||
|     } | ||||
|   else if(argis("-sd")) do_sdebug = true; | ||||
|   else if(argis("-sdeb")) { PHASE(3); draw_debug_map(cwt.at->master); } | ||||
|   else if(argis("-dgeom")) debug_geometry = true; | ||||
|   else return 1; | ||||
|   return 0; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| map<heptagon*, transmatrix> debugmap; | ||||
|  | ||||
| void add_to_debug(heptagon *h, transmatrix T) { | ||||
|   debugmap[h] = T; | ||||
|   for(int i=0; i<neighbors_of(h); i++) | ||||
|     if(h->move(i) && h->c.spin(i) == 0 && h->move(i)->s != hsOrigin) | ||||
|       add_to_debug(h->move(i), T * adjcell_matrix(h, i)); | ||||
|   } | ||||
|  | ||||
| void draw_debug_map(heptagon *h) { | ||||
|   debugmap.clear(); | ||||
|   while(h->s != hsOrigin) h = h->move(0); | ||||
|   add_to_debug(h, Id); | ||||
|   svg::render("syntetic-debug.svg", [] () { | ||||
|     ptds.clear(); | ||||
|     for(auto p: debugmap) { | ||||
|       heptagon *h = p.first; | ||||
|       queuestr(p.second*C0, vid.yres/50, its(create_order[h]) + "/" + its(h->c7->mpdist), 0xFF000000); | ||||
|       for(int i=0; i<neighbors_of(h); i++) { | ||||
|         if(h->move(i)) | ||||
|           queueline(p.second*C0, debugmap[h->move(i)]*C0,  | ||||
|             i == parents_of(h) ? 0xFF0000FF : | ||||
|             i == right_sibling_of(h) ? 0x800000FF : | ||||
|             i == 0 ? 0x008000FF : | ||||
|             0x000000FF); | ||||
|         } | ||||
|       } | ||||
|     hr::drawqueue(); | ||||
|     }); | ||||
|   exit(1); | ||||
|   } | ||||
|  | ||||
| #if CAP_COMMANDLINE | ||||
| auto hook =  | ||||
|   addHook(hooks_args, 100, readArgs); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| } | ||||
							
								
								
									
										11
									
								
								util.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								util.cpp
									
									
									
									
									
								
							| @@ -133,4 +133,15 @@ bool appears(const string& haystack, const string& needle) { | ||||
|   return haystack.find(needle) != string::npos; | ||||
|   } | ||||
|  | ||||
| /* indenter */ | ||||
|  | ||||
| int current_indentation; | ||||
|  | ||||
| struct indenter { | ||||
|   indenter() { current_indentation += 2; } | ||||
|   ~indenter() { current_indentation -= 2; } | ||||
|   }; | ||||
|  | ||||
| void doindent() { for(int i=0; i<current_indentation; i++) printf(" "); } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue