mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-11-04 07:43:02 +00:00 
			
		
		
		
	added the plane immersion visualization
This commit is contained in:
		
							
								
								
									
										228
									
								
								rogueviz/plane-immersion.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								rogueviz/plane-immersion.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -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<eGeometry> g(geometry, gg);
 | 
			
		||||
      if(g2 != gNormal) {
 | 
			
		||||
        hybrid::configure(g2);
 | 
			
		||||
        geometry = g2;
 | 
			
		||||
        }
 | 
			
		||||
      // dynamicval<color_t> gc(gridcol, col);
 | 
			
		||||
      dynamicval<eModel> gm(pmodel, default_model());
 | 
			
		||||
      int idx = id % 3;
 | 
			
		||||
      int idy = id / 3;
 | 
			
		||||
      id++;
 | 
			
		||||
      auto& cd = current_display;
 | 
			
		||||
      dynamicval<ld> gx1(cd->xmin, idx / 3.);
 | 
			
		||||
      dynamicval<ld> gxy(cd->ymin, idy / 3.);
 | 
			
		||||
      dynamicval<ld> gx2(cd->xmax, (idx+1) / 3.);
 | 
			
		||||
      dynamicval<ld> gy2(cd->ymax, (idy+1) / 3.);
 | 
			
		||||
      calcparam();
 | 
			
		||||
      dynamicval<ld> 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;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user