mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	SolN manifold
This commit is contained in:
		| @@ -336,7 +336,7 @@ void display_data::set_projection(int ed) { | ||||
|    | ||||
|   #if CAP_SOLV | ||||
|   if(among(glhr::new_shader_projection, glhr::shader_projection::standardSolv, glhr::shader_projection::standardNIH)) { | ||||
|     auto &tab = ((glhr::new_shader_projection == glhr::shader_projection::standardSolv) ? solv::solt : nihv::niht); | ||||
|     auto &tab = solnihv::get_tabled(); | ||||
|      | ||||
|     GLuint invexpid = tab.get_texture_id(); | ||||
|      | ||||
|   | ||||
							
								
								
									
										2
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -914,7 +914,7 @@ EX int heptdistance(heptagon *h1, heptagon *h2) { | ||||
|   if(cryst) return crystal::space_distance(h1->c7, h2->c7); | ||||
|   #endif | ||||
|   #if CAP_SOLV | ||||
|   if(solnih) return solv::approx_distance(h1, h2); | ||||
|   if(solnih) return solnihv::approx_distance(h1, h2); | ||||
|   #endif | ||||
|   while(true) { | ||||
|     if(h1 == h2) return d; | ||||
|   | ||||
| @@ -524,13 +524,11 @@ EX geometryinfo1 giEuclid3 = { gcEuclid,     3, 3, 4, {1,1, 1,0 } }; | ||||
| EX geometryinfo1 giHyperb3 = { gcHyperbolic, 3, 3, 4, {1,1, 1,-1} }; | ||||
| EX geometryinfo1 giSphere3 = { gcSphere,     3, 3, 4, {1,1, 1,+1} }; | ||||
|  | ||||
| EX geometryinfo1 giSol     = { gcSol,        3, 3, 4, {1,1, 1,0 } }; | ||||
| EX geometryinfo1 giSolNIH  = { gcSolNIH,     3, 3, 4, {1,1, 1,0 } }; | ||||
| EX geometryinfo1 giNil     = { gcNil,        3, 3, 4, {1,1, 1,0 } }; | ||||
| EX geometryinfo1 giProduct = { gcSL2,        3, 3, 4, {1,1, 1,0 } /* will be filled in product::configure() */ }; | ||||
| EX geometryinfo1 giSL2     = { gcSL2,        3, 3, 4, {1,1,-1,-1} }; | ||||
|  | ||||
| EX geometryinfo1 giH23     = { gcNIH,        3, 3, 4, {1,1, 1,0 } }; | ||||
|  | ||||
| /** list of available geometries */ | ||||
| vector<geometryinfo> ginf = { | ||||
|   {"{7,3}", "none",     "{7,3} (standard HyperRogue map)",            "HR",       7, 3, 0,         giHyperb2,       0, {{7, 5}}, eVariation::bitruncated}, | ||||
| @@ -583,14 +581,15 @@ vector<geometryinfo> ginf = { | ||||
|   {"{4,3,5}","field",   "{4,3,5} field quotient space",               "f435",     6, 5, qsSMALLBF, giHyperb3, 0x40600, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, | ||||
|   {"{5,3,4}","field",   "{5,3,4} field quotient space",               "f435",    12, 4, qsSMALLBF, giHyperb3, 0x40800, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, | ||||
|   {"binary4","none",    "standard binary tiling",                     "binary4",  5, 3, qBINARY,   giHyperb2, 0x41400, {{7, 5}}, eVariation::pure}, | ||||
|   {"sol",    "none",    "Solv geometry",                              "sol",      8, 3, qBINARY,   giSol,     0x41600, {{7, 5}}, eVariation::pure}, | ||||
|   {"sol",    "none",    "Solv geometry",                              "sol",      8, 3, qBINARY|qSOL,   giSolNIH,  0x41600, {{7, 5}}, eVariation::pure}, | ||||
|   {"kd2",    "none",    "kite-and-dart",                              "kd2",      4, 3, qPENROSE,  giEuclid2, 0x48000, {{7, 7}}, eVariation::pure}, | ||||
|   {"kd3",    "none",    "kite-and-dart on horospheres",               "kd3",     12, 3, qsBP,      giHyperb3, 0x48200, {{7, 3}}, eVariation::pure}, | ||||
|   {"nil",    "none",    "Nil geometry",                               "nil",      6, 3, 0,         giNil,     0x48600, {{7, 5}}, eVariation::pure}, | ||||
|   {"product","none",    "product space",                              "product",  7, 3, qHYBRID,   giProduct, 0x00000, {{7, 3}}, eVariation::pure}, | ||||
|   {"twisted","none",    "rotation space",                             "twisted",  7, 3, qHYBRID,   giSL2,     0x00000, {{6, 4}}, eVariation::pure}, | ||||
|   {"ternary","none",    "standard ternary tiling",                    "ternary",  6, 3, qBINARY,   giHyperb2, 0x48400, {{6, 4}}, eVariation::pure}, | ||||
|   {"NIH",    "none",    "non-isotropic hyperbolic",                   "NIH",     11, 3, qBINARY,   giH23,     0x49000, {{6, 4}}, eVariation::pure}, | ||||
|   {"NIH",    "none",    "non-isotropic hyperbolic",                   "NIH",     11, 3, qBINARY|qNIH,   giSolNIH,  0x49000, {{6, 3}}, eVariation::pure}, | ||||
|   {"solN",   "none",    "Solv geometry NI",                           "solN",     9, 3, (qBINARY|qSOL|qNIH),   giSolNIH,  0x49200, {{7, 3}}, eVariation::pure}, | ||||
|   }; | ||||
|  | ||||
|   // bits: 9, 10, 15, 16, (reserved for later) 17, 18 | ||||
|   | ||||
| @@ -215,10 +215,10 @@ enum eGeometry { | ||||
|   gField435, gField534, | ||||
|   gBinary4, gSol, | ||||
|   gKiteDart2, gKiteDart3, gNil, gProduct, gRotSpace, | ||||
|   gTernary, gNIH, | ||||
|   gTernary, gNIH, gSolN, | ||||
|   gGUARD}; | ||||
|  | ||||
| enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSol, gcNil, gcProduct, gcSL2, gcNIH }; | ||||
| enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSolNIH, gcNil, gcProduct, gcSL2 }; | ||||
|  | ||||
| enum class eVariation { bitruncated, pure, goldberg, irregular, dual };   | ||||
|  | ||||
| @@ -270,8 +270,9 @@ static const flagtype qREGULAR         = 1024; /* not set! */ | ||||
| static const flagtype qARCHI           = 2048; | ||||
| static const flagtype qHYBRID          = 4096; | ||||
| static const flagtype qCRYSTAL         = 8192; | ||||
|  | ||||
| static const flagtype qSOL             = 16384; | ||||
| static const flagtype qEXPERIMENTAL    = 32768; | ||||
| static const flagtype qNIH             = 65536; | ||||
|  | ||||
| // note: dnext assumes that x&7 equals 7 | ||||
| static const int SEE_ALL = 50; | ||||
|   | ||||
							
								
								
									
										14
									
								
								config.cpp
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								config.cpp
									
									
									
									
									
								
							| @@ -509,8 +509,8 @@ EX void initConfig() { | ||||
|   addsaver(vid.cells_generated_limit, "limit on cells generated", 25); | ||||
|    | ||||
|   #if CAP_SOLV | ||||
|   addsaver(solv::solrange_xy, "solrange-xy"); | ||||
|   addsaver(solv::solrange_z, "solrange-z"); | ||||
|   addsaver(solnihv::solrange_xy, "solrange-xy"); | ||||
|   addsaver(solnihv::solrange_z, "solrange-z"); | ||||
|   #endif | ||||
|   addsaver(slr::steps, "slr-steps"); | ||||
|   addsaver(slr::range_xy, "slr-range-xy"); | ||||
| @@ -869,16 +869,16 @@ EX void edit_sightrange() { | ||||
|         dialog::editNumber(sightranges[geometry], 0, 10, 0.5, M_PI, solhelp(), ""); | ||||
|         dialog::extra_options = xo; popScreen(); | ||||
|         }); | ||||
|       dialog::addSelItem(XLAT("max difference in X/Y coordinates"), fts(solv::solrange_xy), 'X'); | ||||
|       dialog::addSelItem(XLAT("max difference in X/Y coordinates"), fts(solnihv::solrange_xy), 'X'); | ||||
|       dialog::add_action([] { | ||||
|         auto xo = dialog::extra_options; | ||||
|         dialog::editNumber(solv::solrange_xy, 0.01, 200, 0.1, 50, XLAT("max difference in X/Y coordinates"), solhelp()), dialog::scaleLog(); | ||||
|         dialog::editNumber(solnihv::solrange_xy, 0.01, 200, 0.1, 50, XLAT("max difference in X/Y coordinates"), solhelp()), dialog::scaleLog(); | ||||
|         dialog::extra_options = xo; popScreen(); | ||||
|         }); | ||||
|       dialog::addSelItem(XLAT("max difference in Z coordinate"), fts(solv::solrange_z), 'Z'); | ||||
|       dialog::addSelItem(XLAT("max difference in Z coordinate"), fts(solnihv::solrange_z), 'Z'); | ||||
|       dialog::add_action([] { | ||||
|         auto xo = dialog::extra_options; | ||||
|         dialog::editNumber(solv::solrange_z, 0, 20, 0.1, 6, XLAT("max difference in Z coordinates"), solhelp()); | ||||
|         dialog::editNumber(solnihv::solrange_z, 0, 20, 0.1, 6, XLAT("max difference in Z coordinates"), solhelp()); | ||||
|         dialog::extra_options = xo; popScreen(); | ||||
|         }); | ||||
|       #endif | ||||
| @@ -955,7 +955,7 @@ EX void menuitem_sightrange(char c IS('c')) { | ||||
|     dialog::addSelItem(XLAT("minimum visible cell in pixels"), fts(WDIM == 3 ? vid.smart_range_detail_3 : vid.smart_range_detail), c); | ||||
|   #if CAP_SOLV | ||||
|   else if(pmodel == mdGeodesic && sol) | ||||
|     dialog::addSelItem(XLAT("3D sight range"), fts(solv::solrange_xy) + "x" + fts(solv::solrange_z), c); | ||||
|     dialog::addSelItem(XLAT("3D sight range"), fts(solnihv::solrange_xy) + "x" + fts(solnihv::solrange_z), c); | ||||
|   #endif | ||||
|   else if(WDIM == 3) | ||||
|     dialog::addSelItem(XLAT("3D sight range"), fts(sightranges[geometry]), c); | ||||
|   | ||||
| @@ -6062,7 +6062,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | ||||
|                 else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewcenter())) continue; | ||||
|                 else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue; | ||||
|                 } | ||||
|               else if(sol && in_perspective()) { | ||||
|               else if(sol && in_perspective() && !nih) { | ||||
|                 ld b = vid.binary_width * log(2) / 2; | ||||
|                 const ld l = log(2) / 2; | ||||
|                 switch(a) { | ||||
|   | ||||
							
								
								
									
										6
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -129,9 +129,9 @@ void addMessage(string s, char spamtype = 0); | ||||
| #define cgclass (ginf[geometry].cclass) | ||||
| #define euclid (cgclass == gcEuclid) | ||||
| #define sphere (cgclass == gcSphere) | ||||
| #define sol (cgclass == gcSol) | ||||
| #define nih (cgclass == gcNIH) | ||||
| #define solnih (sol || nih) | ||||
| #define solnih (cgclass = gcSolNIH) | ||||
| #define sol (ginf[geometry].flags & qSOL) | ||||
| #define nih (ginf[geometry].flags & qNIH) | ||||
| #define nil (cgclass == gcNil) | ||||
| #define sl2 (cgclass == gcSL2) | ||||
| #define prod (cgclass == gcProduct) | ||||
|   | ||||
| @@ -1131,8 +1131,12 @@ enum iePrecision { iLazy, iTable }; | ||||
| /** inverse exponential function \see hr::direct_exp */ | ||||
| EX hyperpoint inverse_exp(const hyperpoint h, iePrecision p, bool just_direction IS(true)) { | ||||
|   #if CAP_SOLV | ||||
|   if(sol) return solv::get_inverse_exp(h, p == iLazy, just_direction); | ||||
|   if(nih) return nihv::get_inverse_exp(h, p == iLazy, just_direction); | ||||
|   if(solnih) { | ||||
|     if(nih)  | ||||
|       return solnihv::get_inverse_exp_nsym(h, p == iLazy, just_direction); | ||||
|     else | ||||
|       return solnihv::get_inverse_exp_symsol(h, p == iLazy, just_direction); | ||||
|     } | ||||
|   #endif | ||||
|   if(nil) return nilv::get_inverse_exp(h, p == iLazy ? 5 : 20); | ||||
|   if(sl2) return slr::get_inverse_exp(h); | ||||
|   | ||||
| @@ -969,7 +969,7 @@ EX bool in_smart_range(const transmatrix& T) { | ||||
|   if(invalid_point(h)) return false; | ||||
|   if(nil || nih) return true; | ||||
|   #if CAP_SOLV | ||||
|   if(pmodel == mdGeodesic) return solv::in_table_range(h); | ||||
|   if(pmodel == mdGeodesic) return solnihv::in_table_range(h); | ||||
|   #endif | ||||
|   hyperpoint h1; | ||||
|   applymodel(h, h1); | ||||
|   | ||||
							
								
								
									
										225
									
								
								nonisotropic.cpp
									
									
									
									
									
								
							
							
						
						
									
										225
									
								
								nonisotropic.cpp
									
									
									
									
									
								
							| @@ -25,11 +25,15 @@ EX namespace nisot { | ||||
|       return slr::translate(h); | ||||
|     transmatrix T = Id; | ||||
|     for(int i=0; i<GDIM; i++) T[i][LDIM] = h[i]; | ||||
|     if(sol) { | ||||
|     if(sol && nih) { | ||||
|       T[0][0] = pow(2, -h[2]); | ||||
|       T[1][1] = pow(3, h[2]); | ||||
|       } | ||||
|     else if(sol) { | ||||
|       T[0][0] = exp(-h[2]); | ||||
|       T[1][1] = exp(+h[2]); | ||||
|       } | ||||
|     if(nih) { | ||||
|     else if(nih) { | ||||
|       T[0][0] = pow(2, h[2]); | ||||
|       T[1][1] = pow(3, h[2]); | ||||
|       } | ||||
| @@ -53,6 +57,8 @@ EX namespace solnihv { | ||||
|     void load(); | ||||
|     hyperpoint get(ld ix, ld iy, ld iz, bool lazy); | ||||
|      | ||||
|     nisot::ptlow& get_int(int ix, int iy, int iz) { return tab[(iz*PRECY+iy)*PRECX+ix]; } | ||||
|    | ||||
|     GLuint texture_id; | ||||
|     bool toload; | ||||
|      | ||||
| @@ -84,7 +90,7 @@ EX namespace solnihv { | ||||
|     hyperpoint res; | ||||
|      | ||||
|     if(lazy) { | ||||
|       auto r = tab[(int(iz)*PRECY+int(iy))*PRECX+int(ix)]; | ||||
|       auto r = get_int(int(ix), int(iy), int(iz)); | ||||
|       for(int i=0; i<3; i++) res[i] = r[i]; | ||||
|       } | ||||
|      | ||||
| @@ -98,7 +104,7 @@ EX namespace solnihv { | ||||
|       int ay = iy, by = ay+1; | ||||
|       int az = iz, bz = az+1; | ||||
|        | ||||
|       #define S0(x,y,z) tab[(z*PRECY+y)*PRECX+x][t] | ||||
|       #define S0(x,y,z) get_int(x, y, z)[t] | ||||
|       #define S1(x,y) (S0(x,y,az) * (bz-iz) + S0(x,y,bz) * (iz-az)) | ||||
|       #define S2(x) (S1(x,ay) * (by-iy) + S1(x,by) * (iy-ay)) | ||||
|    | ||||
| @@ -245,7 +251,9 @@ EX namespace solnihv { | ||||
|         return g; | ||||
|         }; | ||||
|        | ||||
|       if(sol) switch(d) { | ||||
|       switch(geometry){ | ||||
|  | ||||
|       case gSol: switch(d) { | ||||
|         case 0: // right | ||||
|           return rule(altstep(pf, 2), ps, 4); | ||||
|         case 1: // up | ||||
| @@ -266,7 +274,7 @@ EX namespace solnihv { | ||||
|           return NULL; | ||||
|         } | ||||
|  | ||||
|       else switch(d) { | ||||
|       case gNIH: switch(d) { | ||||
|         case 0: // right | ||||
|           return rule(altstep(pf, 2), ps, 2); | ||||
|         case 1: // up | ||||
| @@ -280,6 +288,26 @@ EX namespace solnihv { | ||||
|         default: | ||||
|           return rule(altstep(pf, (d-5) % 2), altstep3(ps, (d-5)/2), 4); | ||||
|         } | ||||
|  | ||||
|       case gSolN: switch(d) { | ||||
|         case 0: // right | ||||
|           return rule(altstep(pf, 2), ps, 2); | ||||
|         case 1: // up | ||||
|           return rule(pf, altstep3(ps, 3), 3); | ||||
|         case 2: // left | ||||
|           return rule(altstep(pf, 4), ps, 0); | ||||
|         case 3: // down | ||||
|           return rule(pf, altstep3(ps, 5), 1); | ||||
|         case 4: case 5:  | ||||
|           return rule(altstep(pf, d-4), altstep3(ps, 4), ps->zebraval + 6); | ||||
|         case 6: case 7: case 8:  | ||||
|           return rule(altstep(pf, 3), altstep3(ps, d-6), pf->zebraval + 4); | ||||
|         default: | ||||
|           return NULL; | ||||
|         } | ||||
|  | ||||
|         default: throw "not solnihv"; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     ~hrmap_solnih() { | ||||
| @@ -289,23 +317,23 @@ EX namespace solnihv { | ||||
|       } | ||||
|  | ||||
|     transmatrix adjmatrix(int i, int j) { | ||||
|       if(sol) { | ||||
|       switch(geometry) { | ||||
|       case gSol: { | ||||
|         ld z = log(2); | ||||
|         ld bw = vid.binary_width * z; | ||||
|         ld bwh = bw / 4; | ||||
|         switch(i) { | ||||
|           case 0: return xpush(+bw); | ||||
|           case 1: return ypush(+bw); | ||||
|           case 2: return xpush(-bwh) * zpush(+z) * ypush(j == 6 ? +bwh : -bwh); | ||||
|           case 3: return xpush(+bwh) * zpush(+z) * ypush(j == 6 ? +bwh : -bwh); | ||||
|           case 2: case 3: | ||||
|             return ypush(bw*(6.5-j)) * zpush(+z) * xpush(bw*(i-2.5)); | ||||
|           case 4: return xpush(-bw); | ||||
|           case 5: return ypush(-bw); | ||||
|           case 6: return ypush(-bwh) * zpush(-z) * xpush(j == 2 ? +bwh : -bwh); | ||||
|           case 7: return ypush(+bwh) * zpush(-z) * xpush(j == 2 ? +bwh : -bwh); | ||||
|           case 6: case 7: | ||||
|             return xpush(bw*(2.5-j)) * zpush(-z) * ypush(bw*(i-6.5)); | ||||
|           default:return Id; | ||||
|           } | ||||
|         } | ||||
|       else { | ||||
|       case gNIH: { | ||||
|         ld bw = vid.binary_width; | ||||
|         switch(i) {           | ||||
|           case 0: return xpush(+bw); | ||||
| @@ -379,30 +407,39 @@ EX namespace solnihv { | ||||
|     "  return 0.5 - atan((0.5-x) / y) / 3.1415926535897932384626433832795;" | ||||
|     "  }"; | ||||
|  | ||||
| EX } | ||||
|  | ||||
| EX namespace solv { | ||||
|  | ||||
|   EX ld solrange_xy = 15; | ||||
|   EX ld solrange_z = 4; | ||||
|    | ||||
|   EX bool in_table_range(hyperpoint h) { | ||||
|     return abs(h[0]) < solrange_xy && abs(h[1]) < solrange_xy && abs(h[2]) < solrange_z; | ||||
|     } | ||||
|  | ||||
|   EX solnihv::tabled_inverses solt = solnihv::tabled_inverses("solv-geodesics.dat"); | ||||
|  | ||||
|   hyperpoint christoffel(const hyperpoint at, const hyperpoint velocity, const hyperpoint transported) { | ||||
|     return hpxyz3( | ||||
|       -velocity[2] * transported[0] - velocity[0] * transported[2], | ||||
|        velocity[2] * transported[1] + velocity[1] * transported[2], | ||||
|        velocity[0] * transported[0] * exp(2*at[2]) - velocity[1] * transported[1] * exp(-2*at[2]), | ||||
|        0 | ||||
|        ); | ||||
|     constexpr ld l2 = log(2); | ||||
|     constexpr ld l3 = log(3); | ||||
|     switch(geometry) { | ||||
|       case gSolN: | ||||
|         return hpxyz3( | ||||
|           -(velocity[2] * transported[0] + velocity[0] * transported[2]) * l2, | ||||
|            (velocity[2] * transported[1] + velocity[1] * transported[2]) * l3, | ||||
|            velocity[0] * transported[0] * exp(2*l2*at[2]) * l2 - velocity[1] * transported[1] * exp(-2*l3*at[2]) * l3, | ||||
|            0 | ||||
|            ); | ||||
|       case gSol: | ||||
|         return hpxyz3( | ||||
|           -velocity[2] * transported[0] - velocity[0] * transported[2], | ||||
|            velocity[2] * transported[1] + velocity[1] * transported[2], | ||||
|            velocity[0] * transported[0] * exp(2*at[2]) - velocity[1] * transported[1] * exp(-2*at[2]), | ||||
|            0 | ||||
|            ); | ||||
|       case gNIH: | ||||
|         return hpxyz3( | ||||
|            (velocity[2] * transported[0] + velocity[0] * transported[2]) * l2, | ||||
|            (velocity[2] * transported[1] + velocity[1] * transported[2]) * l3, | ||||
|            -(velocity[0] * transported[0] * exp(-2*l2*at[2]) * l2 + velocity[1] * transported[1] * exp(-2*l3*at[2]) * l3), | ||||
|            0 | ||||
|            ); | ||||
|       default: | ||||
|         throw "christoffel not in solnihv"; | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   EX hyperpoint get_inverse_exp(hyperpoint h, bool lazy, bool just_direction) { | ||||
|     solt.load(); | ||||
|   EX hyperpoint get_inverse_exp_symsol(hyperpoint h, bool lazy, bool just_direction) { | ||||
|     auto& s = get_tabled(); | ||||
|     s.load(); | ||||
|      | ||||
|     ld ix = h[0] >= 0. ? solnihv::x_to_ix(h[0]) : solnihv::x_to_ix(-h[0]); | ||||
|     ld iy = h[1] >= 0. ? solnihv::x_to_ix(h[1]) : solnihv::x_to_ix(-h[1]); | ||||
| @@ -410,7 +447,7 @@ EX namespace solv { | ||||
|      | ||||
|     if(h[2] < 0.) { iz = -iz; swap(ix, iy); } | ||||
|      | ||||
|     hyperpoint res = solt.get(ix, iy, iz, lazy); | ||||
|     hyperpoint res = s.get(ix, iy, iz, lazy); | ||||
|    | ||||
|     if(h[2] < 0.) { swap(res[0], res[1]); res[2] = -res[2]; } | ||||
|     if(h[0] < 0.) res[0] = -res[0]; | ||||
| @@ -425,7 +462,29 @@ EX namespace solv { | ||||
|     return res; | ||||
|     } | ||||
|  | ||||
|   EX string solshader = solnihv::common + | ||||
|   EX hyperpoint get_inverse_exp_nsym(hyperpoint h, bool lazy, bool just_direction) { | ||||
|     auto& s = get_tabled(); | ||||
|     s.load(); | ||||
|      | ||||
|     ld ix = h[0] >= 0. ? solnihv::x_to_ix(h[0]) : solnihv::x_to_ix(-h[0]); | ||||
|     ld iy = h[1] >= 0. ? solnihv::x_to_ix(h[1]) : solnihv::x_to_ix(-h[1]); | ||||
|     ld iz = (tanh(h[2]/4)+1)/2; | ||||
|      | ||||
|     hyperpoint res = s.get(ix, iy, iz, lazy); | ||||
|    | ||||
|     if(h[0] < 0.) res[0] = -res[0]; | ||||
|     if(h[1] < 0.) res[1] = -res[1]; | ||||
|      | ||||
|     if(!just_direction) { | ||||
|       ld r = hypot_d(3, res); | ||||
|       if(r == 0.) return res; | ||||
|       return res * atanh(r) / r; | ||||
|       } | ||||
|  | ||||
|     return res; | ||||
|     } | ||||
|  | ||||
|   EX string shader_symsol = solnihv::common + | ||||
|  | ||||
|     "vec4 inverse_exp(vec4 h) {" | ||||
|      | ||||
| @@ -456,57 +515,7 @@ EX namespace solv { | ||||
|     "return res;" | ||||
|     "}"; | ||||
|  | ||||
|   EX int approx_distance(heptagon *h1, heptagon *h2) { | ||||
|     auto m = (solnihv::hrmap_solnih*) currentmap; | ||||
|     dynamicval<eGeometry> g(geometry, gBinary4);  | ||||
|     dynamicval<hrmap*> cm(currentmap, m->binary_map); | ||||
|     int d1 = binary::celldistance3_approx(m->coords[h1].first, m->coords[h2].first); | ||||
|     int d2 = binary::celldistance3_approx(m->coords[h1].second, m->coords[h2].second); | ||||
|     return d1 + d2 - abs(h1->distance - h2->distance); | ||||
|     }     | ||||
| EX } | ||||
|  | ||||
| EX namespace nihv { | ||||
|  | ||||
|   EX solnihv::tabled_inverses niht = solnihv::tabled_inverses("h23-geodesics.dat"); | ||||
|  | ||||
|   hyperpoint christoffel(const hyperpoint at, const hyperpoint velocity, const hyperpoint transported) { | ||||
|     static const ld l2 = log(2); | ||||
|     static const ld l3 = log(3); | ||||
|     return hpxyz3( | ||||
|        (velocity[2] * transported[0] + velocity[0] * transported[2]) * l2, | ||||
|        (velocity[2] * transported[1] + velocity[1] * transported[2]) * l3, | ||||
|        -(velocity[0] * transported[0] * exp(-2*l2*at[2]) * l2 + velocity[1] * transported[1] * exp(-2*l3*at[2]) * l3), | ||||
|  | ||||
| //       (-velocity[2] * transported[0] - velocity[0] * transported[2]) * l2, | ||||
| //       (-velocity[2] * transported[1] - velocity[1] * transported[2]) * l3, | ||||
| //       velocity[0] * transported[0] * exp(2*l2*at[2]) * l2 + velocity[1] * transported[1] * exp(2*l3*at[2]) * l3, | ||||
|        0 | ||||
|        ); | ||||
|     }   | ||||
|      | ||||
|   EX hyperpoint get_inverse_exp(hyperpoint h, bool lazy, bool just_direction) { | ||||
|     niht.load(); | ||||
|      | ||||
|     ld ix = h[0] >= 0. ? solnihv::x_to_ix(h[0]) : solnihv::x_to_ix(-h[0]); | ||||
|     ld iy = h[1] >= 0. ? solnihv::x_to_ix(h[1]) : solnihv::x_to_ix(-h[1]); | ||||
|     ld iz = (tanh(h[2]/4)+1)/2; | ||||
|      | ||||
|     hyperpoint res = niht.get(ix, iy, iz, lazy); | ||||
|    | ||||
|     if(h[0] < 0.) res[0] = -res[0]; | ||||
|     if(h[1] < 0.) res[1] = -res[1]; | ||||
|      | ||||
|     if(!just_direction) { | ||||
|       ld r = hypot_d(3, res); | ||||
|       if(r == 0.) return res; | ||||
|       return res * atanh(r) / r; | ||||
|       } | ||||
|  | ||||
|     return res; | ||||
|     } | ||||
|    | ||||
|   EX string nihshader = solnihv::common + | ||||
|   EX string shader_nsym = solnihv::common + | ||||
|  | ||||
|     "vec4 inverse_exp(vec4 h) {" | ||||
|      | ||||
| @@ -527,6 +536,35 @@ EX namespace nihv { | ||||
|      | ||||
|     "return res;" | ||||
|     "}"; | ||||
|  | ||||
|   EX ld solrange_xy = 15; | ||||
|   EX ld solrange_z = 4; | ||||
|    | ||||
|   EX bool in_table_range(hyperpoint h) { | ||||
|     return abs(h[0]) < solrange_xy && abs(h[1]) < solrange_xy && abs(h[2]) < solrange_z; | ||||
|     } | ||||
|  | ||||
|   EX tabled_inverses solt = solnihv::tabled_inverses("solv-geodesics.dat"); | ||||
|   EX tabled_inverses niht = solnihv::tabled_inverses("h23-geodesics.dat"); | ||||
|   EX tabled_inverses sont = solnihv::tabled_inverses("sont-geodesics.dat"); | ||||
|    | ||||
|   EX tabled_inverses& get_tabled() { | ||||
|     switch(geometry) { | ||||
|       case gSol: return solt; | ||||
|       case gNIH: return niht; | ||||
|       case gSolN: return sont; | ||||
|       default: throw "not solnih"; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   EX int approx_distance(heptagon *h1, heptagon *h2) { | ||||
|     auto m = (solnihv::hrmap_solnih*) currentmap; | ||||
|     dynamicval<eGeometry> g(geometry, gBinary4);  | ||||
|     dynamicval<hrmap*> cm(currentmap, m->binary_map); | ||||
|     int d1 = binary::celldistance3_approx(m->coords[h1].first, m->coords[h2].first); | ||||
|     int d2 = binary::celldistance3_approx(m->coords[h1].second, m->coords[h2].second); | ||||
|     return d1 + d2 - abs(h1->distance - h2->distance); | ||||
|     }     | ||||
| EX } | ||||
| #endif | ||||
|  | ||||
| @@ -1513,8 +1551,7 @@ EX namespace nisot { | ||||
|   EX hyperpoint christoffel(const hyperpoint at, const hyperpoint velocity, const hyperpoint transported) { | ||||
|     if(nil) return nilv::christoffel(at, velocity, transported); | ||||
|     #if CAP_SOLV | ||||
|     else if(sol) return solv::christoffel(at, velocity, transported); | ||||
|     else if(nih) return nihv::christoffel(at, velocity, transported); | ||||
|     else if(solnih) return solnihv::christoffel(at, velocity, transported); | ||||
|     #endif | ||||
|     else if(sl2) return slr::christoffel(at, velocity, transported); | ||||
|     else return point3(0, 0, 0); | ||||
| @@ -1522,7 +1559,7 @@ EX namespace nisot { | ||||
|  | ||||
|   EX bool in_table_range(hyperpoint h) { | ||||
|     #if CAP_SOLV | ||||
|     if(solnih) return solv::in_table_range(h); | ||||
|     if(sol) return solnihv::in_table_range(h); | ||||
|     #endif | ||||
|     return true; | ||||
|     } | ||||
| @@ -1625,8 +1662,8 @@ EX namespace nisot { | ||||
|     using namespace arg; | ||||
|     #if CAP_SOLV | ||||
|     if(argis("-solrange")) { | ||||
|       shift_arg_formula(solv::solrange_xy); | ||||
|       shift_arg_formula(solv::solrange_z); | ||||
|       shift_arg_formula(solnihv::solrange_xy); | ||||
|       shift_arg_formula(solnihv::solrange_z); | ||||
|       return 0; | ||||
|       } | ||||
|     #endif | ||||
| @@ -1636,11 +1673,11 @@ EX namespace nisot { | ||||
|       } | ||||
|     #if CAP_SOLV | ||||
|     else if(argis("-fsol")) { | ||||
|       shift(); solv::solt.fname = args(); | ||||
|       shift(); solnihv::solt.fname = args(); | ||||
|       return 0; | ||||
|       } | ||||
|     else if(argis("-nihsol")) { | ||||
|       shift(); nihv::niht.fname = args(); | ||||
|       shift(); solnihv::niht.fname = args(); | ||||
|       return 0; | ||||
|       } | ||||
|     #endif | ||||
|   | ||||
							
								
								
									
										15
									
								
								polygons.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								polygons.cpp
									
									
									
									
									
								
							| @@ -1014,6 +1014,21 @@ void geometry_information::create_wall3d() { | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   if(geometry == gSolN) { | ||||
|     ld zstep = -.5; | ||||
|     ld bwh = vid.binary_width / 6; | ||||
|     auto pt = [&] (int x, int y, int z) { return xpush(bwh*x) * ypush(bwh*y) * zpush(zstep*z) * C0; }; | ||||
|     make_wall(0, {pt(+3,-3,-1), pt(+3,-3,+1), pt(+3,-1,+1), pt(+3,+1,+1), pt(+3,+3,+1), pt(+3,+3,-1)}); | ||||
|     make_wall(1, {pt(-3,+3,-1), pt(00,+3,-1), pt(+3,+3,-1), pt(+3,+3,+1), pt(-3,+3,+1)}); | ||||
|     make_wall(2, {pt(-3,-3,-1), pt(-3,-3,+1), pt(-3,-1,+1), pt(-3,+1,+1), pt(-3,+3,+1), pt(-3,+3,-1)}); | ||||
|     make_wall(3, {pt(-3,-3,-1), pt(00,-3,-1), pt(+3,-3,-1), pt(+3,-3,+1), pt(-3,-3,+1)}); | ||||
|     make_wall(4, {pt(-3,+3,-1), pt(-3,-3,-1), pt(00,-3,-1), pt(00,+3,-1)}); | ||||
|     make_wall(5, {pt(00,+3,-1), pt(00,-3,-1), pt(+3,-3,-1), pt(+3,+3,-1)}); | ||||
|     make_wall(6, {pt(-3,-3,+1), pt(+3,-3,+1), pt(+3,-1,+1), pt(-3,-1,+1)}); | ||||
|     make_wall(7, {pt(-3,-1,+1), pt(+3,-1,+1), pt(+3,+1,+1), pt(-3,+1,+1)}); | ||||
|     make_wall(8, {pt(-3,+1,+1), pt(+3,+1,+1), pt(+3,+3,+1), pt(-3,+3,+1)}); | ||||
|     } | ||||
|    | ||||
|   if(geometry == gNil) { | ||||
|     for(int i=0; i<S7; i++) make_wall(i, nilv::facevertices[i]); | ||||
|     } | ||||
|   | ||||
| @@ -757,8 +757,8 @@ void init() { | ||||
|       1,       "  }", | ||||
|        | ||||
|       #if CAP_SOLV | ||||
|       ssol,    solv::solshader, | ||||
|       snih,    nihv::nihshader, | ||||
|       ssol,    solnihv::shader_symsol, | ||||
|       snih,    solnihv::shader_nsym, | ||||
|       #endif | ||||
|       snil,    nilv::nilshader, | ||||
|       ssl2,    slr::slshader, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue