mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +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;
 | |
|     });
 | |
| 
 | |
| }}
 | 
