mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-11-03 23:33:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Hyperbolic Rogue
 | 
						|
// Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details
 | 
						|
 | 
						|
// example commandline:
 | 
						|
// -spiral 2,10000 -spiraledge 0,2 -spiraledge 1,1 -lab -spiralcolor 2 FF4040FF
 | 
						|
 | 
						|
#include "rogueviz.h"
 | 
						|
 | 
						|
namespace rogueviz {
 | 
						|
 | 
						|
namespace spiral {
 | 
						|
 | 
						|
  ld mul;
 | 
						|
  
 | 
						|
  transmatrix at(double d) {
 | 
						|
    return spin(log(d) * TAU / log(mul)) * xpush(log(d));
 | 
						|
    }
 | 
						|
 | 
						|
  void place(int N, ld _mul) {
 | 
						|
    mul = _mul;
 | 
						|
    init(RV_GRAPH | RV_HAVE_WEIGHT | RV_INVERSE_WEIGHT);
 | 
						|
    rv_hook(hooks_alt_edges, 100, spiral_altedge);
 | 
						|
    rv_hook(hooks_frame, 0, drawExtra);
 | 
						|
    weight_label = "extent";
 | 
						|
    vdata.resize(N);
 | 
						|
  
 | 
						|
    for(int i=0; i<N; i++) {
 | 
						|
      vertexdata& vd = vdata[i];
 | 
						|
      
 | 
						|
      double d = i + 1;
 | 
						|
      
 | 
						|
      transmatrix h = at(d);
 | 
						|
  
 | 
						|
      createViz(i, cwt.at, h);
 | 
						|
      vd.name = its(i+1);
 | 
						|
      virtualRebase(vd.m);
 | 
						|
  
 | 
						|
      vd.cp = dftcolor;
 | 
						|
      }
 | 
						|
  
 | 
						|
    storeall();
 | 
						|
    }
 | 
						|
  
 | 
						|
  void edge(ld shift, ld mul) {
 | 
						|
    int N = isize(vdata);
 | 
						|
    auto t = add_edgetype(fts(shift)+" " + fts(mul));
 | 
						|
    t->visible_from = 1. / (N+.5);
 | 
						|
    for(int i=0; i<N; i++) {
 | 
						|
      int i0 = i+1;
 | 
						|
      int j0 = int(i0 * mul + shift) - 1;
 | 
						|
      if(j0 >= 0 && j0 < N) addedge(i, j0, 1/(i+1), false, t);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  
 | 
						|
  void color(ld start, ld period, colorpair c) {
 | 
						|
    int N = isize(vdata);
 | 
						|
    int maxw = N;
 | 
						|
    while(start >= 0 && start < N) {
 | 
						|
      int i = int(start);
 | 
						|
      vdata[i].cp = c;
 | 
						|
      start += period;
 | 
						|
      maxw--; if(maxw <= 0) break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
bool spiral_altedge(edgeinfo* ei, bool store) {
 | 
						|
  bool onspiral = abs(ei->i - ei->j) == 1;
 | 
						|
 | 
						|
  if(onspiral) {
 | 
						|
    const int prec = 20; 
 | 
						|
    if(store) ei->orig = currentmap->gamestart();
 | 
						|
    transmatrix T = ggmatrix(currentmap->gamestart());
 | 
						|
    hyperpoint l1 = tC0(spiral::at(1+ei->i));
 | 
						|
    if(!store) l1 = T * l1;
 | 
						|
    for(int z=1; z<=prec; z++) {
 | 
						|
      hyperpoint l2 = tC0(spiral::at(1+ei->i+(ei->j-ei->i) * z / (prec+.0)));
 | 
						|
      if(!store)
 | 
						|
        queueline(l1, T*l2, col, vid.linequality).prio = PPR::STRUCT0;
 | 
						|
      else
 | 
						|
        storeline(ei->prec, l1, l2);
 | 
						|
      l1 = l2;
 | 
						|
      }
 | 
						|
    return true;
 | 
						|
    }
 | 
						|
  
 | 
						|
  return false;
 | 
						|
  }
 | 
						|
 | 
						|
auto hooks =
 | 
						|
  addHook(hooks_args, 100, [] {
 | 
						|
    using namespace arg;
 | 
						|
 | 
						|
    if(argis("-spiral")) {
 | 
						|
      PHASE(3); 
 | 
						|
      ld mul = 2;
 | 
						|
      int N = 1000;
 | 
						|
      shift(); sscanf(argcs(), LDF ",%d", &mul, &N);
 | 
						|
      spiral::place(N, mul);
 | 
						|
      return 0;
 | 
						|
      }
 | 
						|
  
 | 
						|
    else if(argis("-spiraledge")) {
 | 
						|
      PHASE(3); 
 | 
						|
      ld shft = 1;
 | 
						|
      ld mul = 1;
 | 
						|
      shift(); sscanf(argcs(), LDF "," LDF, &shft, &mul);
 | 
						|
      spiral::edge(shft, mul);
 | 
						|
      return 0;
 | 
						|
      }
 | 
						|
  
 | 
						|
    else if(argis("-spiralcolor")) {
 | 
						|
      PHASE(3); 
 | 
						|
      ld period = 1;
 | 
						|
      ld start = 1;
 | 
						|
      shift(); sscanf(argcs(), LDF "," LDF, &period, &start);
 | 
						|
      start--;
 | 
						|
      shift();
 | 
						|
      spiral::color(start, period, parse(args()));
 | 
						|
      return 0;
 | 
						|
      }
 | 
						|
 | 
						|
    return 1;
 | 
						|
    });
 | 
						|
 | 
						|
}}
 |