From 9aeece0fa455c8f142c969fc0a5d3d79ac2448a3 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Mon, 25 May 2020 02:32:44 +0200 Subject: [PATCH] added the plane immersion visualization --- rogueviz/plane-immersion.cpp | 228 +++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 rogueviz/plane-immersion.cpp diff --git a/rogueviz/plane-immersion.cpp b/rogueviz/plane-immersion.cpp new file mode 100644 index 00000000..3d142308 --- /dev/null +++ b/rogueviz/plane-immersion.cpp @@ -0,0 +1,228 @@ +#include "rogueviz.h" + +/** \brief Immersed plane + * + * Euclidean plane immersed in various geometries. + * + * Compile with HyperRogue, enable a 3D geometry, and press oo to view or to change the direction. + * + **/ + +namespace rogueviz { + +namespace embed { + +ld scale = 1; + +color_t gridcol = 0xFFFFFFFF; + +hyperpoint fp(ld x, ld y) { + x *= scale; + y *= scale; + x *= M_PI/10 * sqrt(2)/2; + y *= M_PI/10 * sqrt(2)/2; + if(euclid) + return hyperpoint(x, y, 0, 1); + + if(sphere) { + ld a = sqrt(2)/2; + x /= a; + y /= a; + hyperpoint h = cspin(2, 3, -M_PI/4) * hyperpoint(sin(x)*a, sin(y)*a, cos(x)*a, cos(y)*a); + return h; + } + + if(hyperbolic) + return cspin(0, 2, -M_PI/2) * tC0(parabolic13(x, y)); + + if(nil) + return hyperpoint(0, y, x, 1); + + if(prod) + return zpush(y) * xpush0(x); + + if(sl2) { + ld a = sqrt(2)/2; + x /= a; + y /= a; + hyperpoint h = cspin(2, 3, -M_PI/4) * hyperpoint(sinh(x)*a, sinh(y)*a, cosh(x)*a, cosh(y)*a); + return h; + } + + if(sol || nih) + return hyperpoint(x, y, 0, 1); + + return hyperpoint(x, y, 0, 1); + } + +void embed(const transmatrix& V, ld x, ld y, ld x1, ld y1) { + queueline(V* fp(x, y), V*fp(x1, y1), gridcol, 0, PPR::LINE); + } + +void draw_grid(const transmatrix& V) { + for(int x=-10; x<=10; x++) { + for(int y=-10; y<10; y++) { + for(int a=0; a<=10; a++) + curvepoint(V * fp(x, y+a/10.)); + queuecurve(gridcol, 0, PPR::LINE).flags |= POLY_FORCEWIDE | POLY_ONE_LEVEL; + + for(int a=0; a<=10; a++) + curvepoint(V * fp(y+a/10., x)); + queuecurve(gridcol, 0, PPR::LINE).flags |= POLY_FORCEWIDE | POLY_ONE_LEVEL; + } + } + } + +bool draw_embed(cell *c, const transmatrix& V) { + + if(c == cwt.at && false) + draw_grid(V); + + return false; + } + +int emba; + +void relocate() { + View = Id; + NLP = Id; + centerover = currentmap->gamestart(); + + vid.fixed_yz = false; + + if(nil) rotate_view(cspin(2, 0, M_PI/2)); + if(prod) rotate_view(cspin(1, 2, M_PI/2)); + + if(emba == 1) { + rotate_view(cspin(0, 1, M_PI/4)); + rotate_view(cspin(1, 2, M_PI/6)); + } + + if(emba == 2) { + rotate_view(cspin(1, 2, M_PI/2 * .9)); + } + + for(int a=0; a<100; a++) + shift_view(ztangent(scale/100)); + if(scale < 0) rotate_view(diag(-1,-1,-1,1)); + playermoved = false; + + } + +int part = 1; + +ld wider = 1.5; + +void draw_all() { + vid.linewidth *= wider; + if(1) { + + int id = 0; + + auto draw_colored = [&] (eGeometry gg, eGeometry g2, color_t col) { + dynamicval g(geometry, gg); + if(g2 != gNormal) { + hybrid::configure(g2); + geometry = g2; + } + // dynamicval gc(gridcol, col); + dynamicval gm(pmodel, default_model()); + int idx = id % 3; + int idy = id / 3; + id++; + auto& cd = current_display; + dynamicval gx1(cd->xmin, idx / 3.); + dynamicval gxy(cd->ymin, idy / 3.); + dynamicval gx2(cd->xmax, (idx+1) / 3.); + dynamicval gy2(cd->ymax, (idy+1) / 3.); + calcparam(); + dynamicval gs(scale, scale); + + /* verification + hyperpoint h1 = fp(0, 0); + hyperpoint h2 = fp(1, 0); + hyperpoint h3 = fp(0, 1); + hyperpoint h4 = fp(1, 1); + println(hlog, geometry_name(), " : ", geo_dist(h1, h2), " = ", geo_dist(h3, h4)); + println(hlog, geometry_name(), " : ", geo_dist(h1, h3), " = ", geo_dist(h2, h4)); + */ + + if(nih) scale /= log(2); + relocate(); + initquickqueue(); + make_actual_view(); + draw_grid(cview()); + drawqueue(); + }; + + draw_colored(gCell120, gNormal, 0x00FF00FF); + draw_colored(gNil, gNormal, 0xFF0000FF); + draw_colored(gNormal, gRotSpace, 0x0000FFFF); + + draw_colored(gSphere, gProduct, 0x00FF80FF); + draw_colored(gNIH, gNormal, 0xFF8000FF); + draw_colored(gNormal, gProduct, 0x00FFFFFF); + + draw_colored(gSpace534, gNormal, 0xFF0000FF); + draw_colored(gSolN, gNormal, 0xFF80FFFF); + draw_colored(gSol, gNormal, 0xFF00FFFF); + + calcparam(); + + //draw_colored(gCubeTiling, gNormal, 0xFFFFFFFF); + + relocate(); + } + vid.linewidth /= wider; + } + +void show() { + dialog::editNumber(scale, -2, 2, 0.1, 1, "distance", "distance"); + dialog::extra_options = [] { + draw_all(); + + dialog::addItem("direction", 'A'); + dialog::add_action([] { + emba ++; + emba %= 3; + }); + }; + dialog::reaction = [] { relocate(); }; + } + +void o_key(o_funcs& v) { + v.push_back(named_functionality("plane embedding", show)); + } + +auto hchook = addHook(hooks_drawcell, 100, draw_embed) + ++ addHook(hooks_o_key, 80, o_key) + ++ addHook(hooks_args, 100, [] { + using namespace arg; + + if(0) ; + else if(argis("-embed-angle")) { + shift(); emba = argi(); + } + else if(argis("-embed-video")) { + start_game(); + shot::transparent = 0; + shot::shotx = 500; + shot::shoty = 500; + shift(); + anims::record_video(args(), [] { + for(int i=0; i<360; i++) { + scale = sin((i+.5) * degree); + shot::take("x", draw_all); + } + return true; + }); + } + else return 1; + return 0; + }); + + +} +}