mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
SolN manifold
This commit is contained in:
parent
4872ad01f4
commit
d69cb4e946
@ -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);
|
||||
|
213
nonisotropic.cpp
213
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) {
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user