stretch:: renamed rots_twist to stretch, also implemented for slr

This commit is contained in:
Zeno Rogue 2020-05-09 10:41:15 +02:00
parent ecb88d8501
commit fd9ea8793e
6 changed files with 101 additions and 52 deletions

View File

@ -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"));

View File

@ -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);

View File

@ -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;

View File

@ -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")) {

View File

@ -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");

View File

@ -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);