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