mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-02 12:19:18 +00:00
stretch:: renamed rots_twist to stretch, also implemented for slr
This commit is contained in:
parent
ecb88d8501
commit
fd9ea8793e
@ -1983,6 +1983,8 @@ EX void draw_main() {
|
||||
if(ray::in_use && !ray::comparison_mode) {
|
||||
ray::cast();
|
||||
reset_projection();
|
||||
/* currently incompatible with primitive-based renderer */
|
||||
/* also not implemented in stretch */
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2023,6 +2025,7 @@ EX void draw_main() {
|
||||
if(ray::in_use && !ray::comparison_mode) {
|
||||
ray::cast();
|
||||
reset_projection();
|
||||
if(stretch::in()) return; /*primitive not implemented */
|
||||
}
|
||||
|
||||
DEBB(DF_GRAPH, ("outcircle"));
|
||||
|
14
geom-exp.cpp
14
geom-exp.cpp
@ -826,6 +826,20 @@ EX void showEuclideanMenu() {
|
||||
});
|
||||
}
|
||||
|
||||
if(stretch::applicable()) {
|
||||
dialog::addSelItem(XLAT("stretched geometry"), fts(stretch::factor), 'S');
|
||||
dialog::add_action([] {
|
||||
dialog::editNumber(stretch::factor, -1, 9, 0.1, 0, XLAT("stretched geometry"),
|
||||
XLAT(
|
||||
"Stretch the metric along the fibers. This can currently be done in rotation spaces and in 8-cell, 24-cell and 120-cell. "
|
||||
"Value of 0 means not stretched, -1 means S2xE or H2xE (works only in the limit). "
|
||||
"Only the raycaster is implemented for stretched geometry, so you will see only walls."
|
||||
)
|
||||
);
|
||||
dialog::reaction = ray::reset_raycaster;
|
||||
});
|
||||
}
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addSelItem(XLAT("land"), XLAT1(linf[specialland].name), 'l');
|
||||
dialog::add_action_push(ge_land_selection);
|
||||
|
@ -2149,7 +2149,7 @@ EX void rotate_view(transmatrix T) {
|
||||
|
||||
/** shift the view according to the given tangent vector */
|
||||
EX transmatrix get_shift_view_of(const hyperpoint H, const transmatrix V) {
|
||||
if(!nonisotropic && !rots_twist::in()) {
|
||||
if(!nonisotropic && !stretch::in()) {
|
||||
return rgpushxto0(direct_exp(lp_iapply(H))) * V;
|
||||
}
|
||||
else if(!nisot::geodesic_movement) {
|
||||
@ -2169,7 +2169,7 @@ EX void shift_view(hyperpoint H) {
|
||||
auto oView = View;
|
||||
View = get_shift_view_of(H, View);
|
||||
auto& wc = current_display->which_copy;
|
||||
if(nonisotropic || rots_twist::in()) {
|
||||
if(nonisotropic || stretch::in()) {
|
||||
transmatrix ioldv = eupush(tC0(inverse(oView)));
|
||||
transmatrix newv = inverse(eupush(tC0(inverse(View))));
|
||||
wc = newv * ioldv * wc;
|
||||
|
@ -1839,8 +1839,6 @@ EX }
|
||||
|
||||
EX namespace rots {
|
||||
|
||||
EX ld stretch_factor;
|
||||
|
||||
EX transmatrix uxpush(ld x) {
|
||||
if(sl2) return xpush(x);
|
||||
return cspin(1, 3, x) * cspin(0, 2, x);
|
||||
@ -2034,16 +2032,21 @@ EX namespace rots {
|
||||
|
||||
EX }
|
||||
|
||||
/** twisted S2xE */
|
||||
EX namespace rots_twist {
|
||||
/** stretched rotation space (S3 or SLR) */
|
||||
EX namespace stretch {
|
||||
|
||||
EX ld factor;
|
||||
|
||||
EX bool applicable() {
|
||||
return among(geometry, gCell120, gECell120, gCell24, gECell24, gCell8, gECell8);
|
||||
return rotspace || among(geometry, gCell120, gECell120, gCell24, gECell24, gCell8, gECell8);
|
||||
}
|
||||
|
||||
EX bool in() { return rots::stretch_factor && sphere && (rotspace || applicable()); }
|
||||
EX bool in() {
|
||||
return factor && applicable();
|
||||
}
|
||||
|
||||
EX transmatrix translate(hyperpoint h) {
|
||||
if(!sphere) return slr::translate(h);
|
||||
return matrix4(
|
||||
h[3], -h[2], h[1], h[0],
|
||||
h[2], h[3], -h[0], h[1],
|
||||
@ -2056,6 +2059,7 @@ EX namespace rots_twist {
|
||||
h[0] = -h[0];
|
||||
h[1] = -h[1];
|
||||
h[2] = -h[2];
|
||||
if(!sphere) return slr::translate(h);
|
||||
return translate(h);
|
||||
}
|
||||
|
||||
@ -2066,11 +2070,11 @@ EX namespace rots_twist {
|
||||
}
|
||||
|
||||
hyperpoint isometric_to_actual(const hyperpoint at, const hyperpoint velocity) {
|
||||
return mulz(at, velocity, 1/sqrt(1+rots::stretch_factor));
|
||||
return mulz(at, velocity, 1/sqrt(1+factor));
|
||||
}
|
||||
|
||||
hyperpoint actual_to_isometric(const hyperpoint at, const hyperpoint velocity) {
|
||||
return mulz(at, velocity, sqrt(1+rots::stretch_factor));
|
||||
return mulz(at, velocity, sqrt(1+factor));
|
||||
}
|
||||
|
||||
hyperpoint christoffel(const hyperpoint at, const hyperpoint velocity, const hyperpoint transported) {
|
||||
@ -2080,7 +2084,9 @@ EX namespace rots_twist {
|
||||
|
||||
hyperpoint c;
|
||||
|
||||
auto K = rots::stretch_factor;
|
||||
auto K = factor;
|
||||
|
||||
if(!sphere) K = -2 - K;
|
||||
|
||||
c[0] = -K * (vel[1] * tra[2] + vel[2] * tra[1]);
|
||||
c[1] = K * (vel[0] * tra[2] + vel[2] * tra[0]);
|
||||
@ -2089,7 +2095,13 @@ EX namespace rots_twist {
|
||||
|
||||
return translate(at) * c;
|
||||
}
|
||||
|
||||
|
||||
EX ld sqnorm(hyperpoint at, hyperpoint h) {
|
||||
if(sphere)
|
||||
return sqhypot_d(4, h);
|
||||
h = itranslate(at) * h;
|
||||
return h[0] * h[0] + h[1] * h[1] + h[2] * h[2];
|
||||
}
|
||||
EX }
|
||||
|
||||
EX namespace nisot {
|
||||
@ -2099,8 +2111,8 @@ EX namespace nisot {
|
||||
#if CAP_SOLV
|
||||
else if(sn::in()) return sn::christoffel(at, velocity, transported);
|
||||
#endif
|
||||
else if(stretch::in()) return stretch::christoffel(at, velocity, transported);
|
||||
else if(sl2) return slr::christoffel(at, velocity, transported);
|
||||
else if(rots_twist::in()) return rots_twist::christoffel(at, velocity, transported);
|
||||
else return point3(0, 0, 0);
|
||||
}
|
||||
|
||||
@ -2138,15 +2150,15 @@ EX namespace nisot {
|
||||
|
||||
EX transmatrix parallel_transport_bare(transmatrix Pos, hyperpoint h) {
|
||||
|
||||
bool stretch = rots_twist::in();
|
||||
|
||||
if(!stretch) h[3] = 0;
|
||||
bool stretch = stretch::in();
|
||||
|
||||
h[3] = 0;
|
||||
|
||||
auto tPos = transpose(Pos);
|
||||
|
||||
const ld eps = 1e-4;
|
||||
|
||||
if(sl2) {
|
||||
if(sl2 && !stretch) {
|
||||
hyperpoint p = slr::to_phigans(tPos[3]);
|
||||
for(int i=0; i<3; i++)
|
||||
tPos[i] = (slr::to_phigans(tPos[3] + tPos[i] * eps) - p) / eps;
|
||||
@ -2162,15 +2174,15 @@ EX namespace nisot {
|
||||
auto& vel = h;
|
||||
|
||||
array<ld, 4> ms;
|
||||
|
||||
|
||||
if(stretch) {
|
||||
for(int i=0; i<3; i++) {
|
||||
ms[i] = sqhypot_d(4, tPos[i]);
|
||||
tPos[i] = rots_twist::isometric_to_actual(at, tPos[i]);
|
||||
ms[i] = stretch::sqnorm(at, tPos[i]);
|
||||
tPos[i] = stretch::isometric_to_actual(at, tPos[i]);
|
||||
}
|
||||
ms[3] = sqhypot_d(4, vel);
|
||||
ms[3] = stretch::sqnorm(at, vel);
|
||||
if(!ms[3]) return Pos;
|
||||
vel = rots_twist::isometric_to_actual(at, vel);
|
||||
vel = stretch::isometric_to_actual(at, vel);
|
||||
}
|
||||
|
||||
for(int i=0; i<steps; i++) {
|
||||
@ -2200,27 +2212,25 @@ EX namespace nisot {
|
||||
at = normalize(at);
|
||||
|
||||
auto fix = [&] (hyperpoint& h, ld& m) {
|
||||
h = rots_twist::itranslate(at) * h;
|
||||
h = stretch::itranslate(at) * h;
|
||||
h[3] = 0;
|
||||
ld m1 = h[0] * h[0] + h[1] * h[1] + h[2] * h[2] * (1+rots::stretch_factor);
|
||||
ld m1 = h[0] * h[0] + h[1] * h[1] + h[2] * h[2] * (1 + stretch::factor);
|
||||
h /= sqrt(m1/m);
|
||||
h = rots_twist::translate(at) * h;
|
||||
h = stretch::translate(at) * h;
|
||||
};
|
||||
|
||||
if(i == 0) println(hlog, vel);
|
||||
fix(vel, ms[3]);
|
||||
if(i == 0) println(hlog, vel);
|
||||
for(int i=0; i<3; i++) fix(tPos[i], ms[i]);
|
||||
fix(vel, ms[3]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(stretch) {
|
||||
vel = rots_twist::actual_to_isometric(at, vel);
|
||||
for(int i=0; i<3; i++) tPos[i] = rots_twist::actual_to_isometric(at, tPos[i]);
|
||||
vel = stretch::actual_to_isometric(at, vel);
|
||||
for(int i=0; i<3; i++) tPos[i] = stretch::actual_to_isometric(at, tPos[i]);
|
||||
}
|
||||
|
||||
if(sl2) {
|
||||
|
||||
else if(sl2) {
|
||||
hyperpoint p = slr::from_phigans(tPos[3]);
|
||||
for(int i=0; i<3; i++)
|
||||
tPos[i] = (slr::from_phigans(tPos[3] + tPos[i] * eps) - p) / eps;
|
||||
@ -2363,7 +2373,7 @@ EX namespace nisot {
|
||||
}
|
||||
else if(argis("-rot-stretch")) {
|
||||
PHASEFROM(2);
|
||||
shift_arg_formula(rots::stretch_factor, ray::reset_raycaster);
|
||||
shift_arg_formula(stretch::factor, ray::reset_raycaster);
|
||||
return 0;
|
||||
}
|
||||
else if(argis("-prodturn")) {
|
||||
|
@ -41,16 +41,16 @@ EX int max_cells = 2048;
|
||||
EX bool rays_generate = true;
|
||||
|
||||
EX ld& exp_decay_current() {
|
||||
return (sn::in() || hyperbolic) ? exp_decay_exp : exp_decay_poly;
|
||||
return (sn::in() || hyperbolic || sl2) ? exp_decay_exp : exp_decay_poly;
|
||||
}
|
||||
|
||||
EX int& max_iter_current() {
|
||||
if(nonisotropic || rots_twist::in()) return max_iter_sol;
|
||||
if(nonisotropic || stretch::in()) return max_iter_sol;
|
||||
else return max_iter_iso;
|
||||
}
|
||||
|
||||
ld& maxstep_current() {
|
||||
if(sn::in() || rots_twist::in()) return maxstep_sol;
|
||||
if(sn::in() || stretch::in()) return maxstep_sol;
|
||||
else return maxstep_nil;
|
||||
}
|
||||
|
||||
@ -69,13 +69,13 @@ EX bool available() {
|
||||
return true;
|
||||
if(nil && S7 == 8)
|
||||
return false;
|
||||
if((sn::in() || nil) && pmodel == mdGeodesic)
|
||||
if((sn::in() || nil || sl2) && pmodel == mdGeodesic)
|
||||
return true;
|
||||
if(euclid && pmodel == mdPerspective && !bt::in())
|
||||
return true;
|
||||
if(prod && (PURE || BITRUNCATED))
|
||||
return true;
|
||||
if(sphere && pmodel == mdPerspective && rots_twist::in())
|
||||
if(pmodel == mdPerspective && stretch::in())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -83,13 +83,14 @@ EX bool available() {
|
||||
/** do we want to use the raycaster? */
|
||||
EX bool requested() {
|
||||
if(cgflags & qRAYONLY) return true;
|
||||
if(rots_twist::in()) return true;
|
||||
if(stretch::in()) return true;
|
||||
if(!want_use) return false;
|
||||
#if CAP_TEXTURE
|
||||
if(texture::config.tstate == texture::tsActive) return false;
|
||||
#endif
|
||||
if(!available()) return false;
|
||||
if(want_use == 2) return true;
|
||||
if(sphere) return false; /* currently incompatible with primitives */
|
||||
return racing::on || quotient;
|
||||
}
|
||||
|
||||
@ -321,7 +322,7 @@ void enable_raycaster() {
|
||||
"return vec2(1, 1);\n"
|
||||
"}\n";
|
||||
|
||||
bool stepbased = nonisotropic || rots_twist::in();
|
||||
bool stepbased = nonisotropic || stretch::in();
|
||||
|
||||
string fmain = "void main() {\n";
|
||||
|
||||
@ -347,6 +348,7 @@ void enable_raycaster() {
|
||||
|
||||
if(hyperbolic) fsh += " mediump float len(mediump vec4 x) { return x[3]; }\n";
|
||||
else if(sphere && rotspace) fsh += " mediump float len(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y-x.z*x.z-x.w*x.w; }\n";
|
||||
else if(sl2) fsh += " mediump float len(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y; }\n";
|
||||
else if(sphere) fsh += " mediump float len(mediump vec4 x) { return 1.-x[3]; }\n";
|
||||
|
||||
else fsh += " mediump float len(mediump vec4 x) { return length(x.xyz); }\n";
|
||||
@ -375,7 +377,7 @@ void enable_raycaster() {
|
||||
" mediump vec4 position = vw * vec4(0., 0., 0., 1.);\n"
|
||||
" mediump vec4 tangent = vw * at0;\n";
|
||||
|
||||
if(rots_twist::in()) {
|
||||
if(stretch::in()) {
|
||||
fmain +=
|
||||
"tangent = s_itranslate(position) * tangent;\n"
|
||||
"tangent[2] /= sqrt(1.+stretch);\n"
|
||||
@ -495,8 +497,9 @@ void enable_raycaster() {
|
||||
fmain +=
|
||||
" if(which == -1 && dist == 0.) return;";
|
||||
}
|
||||
|
||||
fsh += "const mediump float stretch = float(" + fts(rots::stretch_factor) + ");\n";
|
||||
|
||||
if(stretch::in() || sl2)
|
||||
fsh += "const mediump float stretch = float(" + fts(stretch::factor) + ");\n";
|
||||
|
||||
// shift d units
|
||||
if(use_reflect) fmain +=
|
||||
@ -549,7 +552,23 @@ void enable_raycaster() {
|
||||
" return vec4(x*vel.y*tra.y - 0.5*dot(vel.yz,tra.zy), -.5*x*dot(vel.yx,tra.xy) + .5 * dot(vel.zx,tra.xz), -.5*(x*x-1.)*dot(vel.yx,tra.xy)+.5*x*dot(vel.zx,tra.xz), 0.);\n"
|
||||
// " return vec4(0.,0.,0.,0.);\n"
|
||||
" }\n";
|
||||
else if(rots_twist::in()) {
|
||||
else if(sl2) {
|
||||
fsh += "mediump mat4 s_translate(vec4 h) {\n"
|
||||
"return mat4(h.w,h.z,h.y,h.x,-h.z,h.w,-h.x,h.y,h.y,-h.x,h.w,-h.z,h.x,h.y,h.z,h.w);\n"
|
||||
"}\n";
|
||||
fsh += "mediump mat4 s_itranslate(vec4 h) {\n"
|
||||
"h.xyz = -h.xyz; return s_translate(h);\n"
|
||||
"}\n";
|
||||
fsh += "mediump vec4 christoffel(mediump vec4 pos, mediump vec4 vel, mediump vec4 tra) {\n"
|
||||
"vel = s_itranslate(pos) * vel;\n"
|
||||
"tra = s_itranslate(pos) * tra;\n"
|
||||
"return s_translate(pos) * vec4(\n"
|
||||
" (vel.y*tra.z+vel.z*tra.y) * -(-stretch-2.), "
|
||||
" (vel.x*tra.z+vel.z*tra.x) * (-stretch-2.), "
|
||||
" 0, 0);\n"
|
||||
"}\n";
|
||||
}
|
||||
else if(stretch::in()) {
|
||||
fsh += "mediump mat4 s_translate(vec4 h) {\n"
|
||||
"return mat4(h.w,h.z,-h.y,-h.x,-h.z,h.w,h.x,-h.y,h.y,-h.x,h.w,-h.z,h.x,h.y,h.z,h.w);\n"
|
||||
"}\n";
|
||||
@ -600,7 +619,10 @@ void enable_raycaster() {
|
||||
"mediump vec4 acc4 = get_acc(position + vel + acc2/2., vel + acc3/2.);\n"
|
||||
"mediump vec4 nposition = position + vel + (acc1+acc2+acc3)/6.;\n";
|
||||
|
||||
if(rots_twist::in()) fmain +=
|
||||
if(sl2) fmain +=
|
||||
"nposition = nposition / sqrt(dot(position.zw, position.zw) - dot(nposition.xy, nposition.xy));\n";
|
||||
|
||||
else if(stretch::in()) fmain +=
|
||||
"nposition = nposition / sqrt(dot(nposition, nposition));\n";
|
||||
|
||||
if(nil) {
|
||||
@ -662,7 +684,7 @@ void enable_raycaster() {
|
||||
" mediump vec4 nposition = v;\n";
|
||||
}
|
||||
|
||||
bool reg = hyperbolic || sphere || euclid;
|
||||
bool reg = hyperbolic || sphere || euclid || sl2;
|
||||
|
||||
if(reg) {
|
||||
fsh += "mediump float len_h(vec4 h) { return 1. - h[3]; }\n";
|
||||
@ -765,7 +787,7 @@ void enable_raycaster() {
|
||||
else fmain +=
|
||||
"tangent = ntangent;\n";
|
||||
|
||||
if(rots_twist::in()) {
|
||||
if(stretch::in() || sl2) {
|
||||
fmain +=
|
||||
"tangent = s_itranslate(position) * tangent;\n"
|
||||
"tangent[3] = 0.;\n"
|
||||
@ -1306,7 +1328,7 @@ EX void configure() {
|
||||
});
|
||||
}
|
||||
|
||||
if(nonisotropic || rots_twist::in()) {
|
||||
if(nonisotropic || stretch::in()) {
|
||||
dialog::addSelItem(XLAT("max step"), fts(maxstep_current()), 'x');
|
||||
dialog::add_action([] {
|
||||
dialog::editNumber(maxstep_current(), 1e-6, 1, 0.1, sol ? 0.05 : 0.1, XLAT("max step"), "affects the precision of solving the geodesic equation in Solv");
|
||||
|
8
reg3.cpp
8
reg3.cpp
@ -187,7 +187,7 @@ EX namespace reg3 {
|
||||
if(loop == 4) cgi.strafedist = adjcheck;
|
||||
else cgi.strafedist = hdist(cgi.adjmoves[0] * C0, cgi.adjmoves[1] * C0);
|
||||
|
||||
if(rots_twist::applicable()) {
|
||||
if(stretch::applicable()) {
|
||||
transmatrix T = cspin(0, 2, 90 * degree);
|
||||
transmatrix iT = inverse(T);
|
||||
for(auto& v: cgi.adjmoves) v = T * v * iT;
|
||||
@ -698,14 +698,14 @@ EX namespace reg3 {
|
||||
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||
binary_map->virtualRebase(alt, T);
|
||||
}
|
||||
|
||||
|
||||
fixmatrix(T);
|
||||
auto hT = tC0(T);
|
||||
|
||||
bool hopf = rots_twist::applicable();
|
||||
bool hopf = stretch::applicable();
|
||||
|
||||
if(hopf)
|
||||
T = rots_twist::translate(hT);
|
||||
T = stretch::translate(hT);
|
||||
|
||||
if(DEB) println(hlog, "searching at ", alt, ":", hT);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user