mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	rv:: balloonsim added
This commit is contained in:
		
							
								
								
									
										579
									
								
								rogueviz/balloonsim.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										579
									
								
								rogueviz/balloonsim.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,579 @@ | ||||
| #include "../rogueviz/rogueviz.h" | ||||
|  | ||||
|  | ||||
| // torus balloon: | ||||
| // ./ht -smart .5 -geo beti -canvas-random 0 -zoom .1  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=1 -run "balloon_volume=10..150000../0..10" -grotate 1 2 90*deg -grotate 0 2 30*deg -animperiod 10000 -animrot 0 90 -shot-1000 -back ffffff -fore 0 -animvideo 1800 torus-balloon.mp4 | ||||
| // donutrad = 4 hexagonal = true SIZE = 21 noise = 1e-2 | ||||
|  | ||||
| // sphere balloon: | ||||
| // ./ht -smart .5 -geo beti -canvas-random 0 -zoom .1  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=1 "balloon_volume=1../0..150000../0..1../0" -grotate 1 2 90*deg -grotate 0 2 30*deg -animperiod 10000 -animrot 0 90 -shot-1000 -back ffffff -fore 0 -animvideo 1800 sphere-balloon.mp4 | ||||
| // donutrad = -1 hexagonal = true SIZE = 21 noise = 0 | ||||
|  | ||||
| // S2xE simulation: | ||||
| // ./ht -smart .5 -geo beti -canvas-random 0 -zoom .01  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=150000 -wsh 9 -ray-do -run -ibale -switch-fpp wall_height=100 depth=50 -ray-iter 600 -ray-range 1 100 -dgl -run -grotate 1 2 60*deg -animmove 400 -60 90 -shot-1000 -animvideo 600 balloonxe-sphere.mp4 | ||||
| // donutrad = -1 hexagonal = true SIZE = 21 noise = 0 | ||||
|  | ||||
| // flatxE simulation: | ||||
| // ./ht -smart .5 -geo beti -canvas-random 0 -zoom .01  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=.01 -wsh 9 -ray-do -run -ibale -switch-fpp wall_height=100 depth=50 -ray-iter 600 -ray-range 1 100 -dgl -run -grotate 1 2 60*deg -animmove 400 -60 90 -shot-1000 -animvideo 600 balloonxe-flat.mp4 | ||||
|  | ||||
| // intermediate xE | ||||
| // ./ht -msens 0 -smart .5 -geo beti -canvas-random 0 -zoom .01  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=150000 -run balloon_volume=5000 -grotate 1 2 90*deg -grotate 0 2 30*deg -animperiod 10000 -animrot 0 90  -shot-1000 -animvideo 120 balloonxe-intermediate.mp4 | ||||
|  | ||||
| // intermediate show: | ||||
| // ./ht -msens 0 -smart .5 -geo beti -canvas-random 0 -zoom .01  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=150000 -run balloon_volume=5000 -zoom 0.2 -run -grotate 1 2 90*deg -grotate 0 2 30*deg -animperiod 10000 -animrot 0 90  -shot-1000 -animvideo 120 intermediate-balloon.mp4 | ||||
|  | ||||
| // balloon-net: | ||||
| // ./ht -smart .5 -geo beti -canvas-random 0 -zoom .01  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -50 50 -ibal balloon_volume=150000 -shot-1000 -back ffffff -fore 0 -wsh 9  | ||||
| // animated: add  -run -animmove 20 0 30 -animvideo 600 net-moving.mp4 | ||||
|  | ||||
| // balloon algorithm on manifolds: | ||||
|  | ||||
| // ./ht -geo Zebra -gp 10 0 -ibalc -msens 0 -smart .5 -geo beti -canvas-random 0 -zoom .1  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -10 10 -ibal balloon_volume=150000 -lw 8 -fore 0 -back ffffff -run -animrot 0 90 -shot-1000 -animvideo 300 balloon-zebra.mp4 | ||||
| // ./ht -geo Klein -gp 10 0 -ibalc -msens 0 -smart .5 -geo beti -canvas-random 0 -zoom .1  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -10 10 -ibal balloon_volume=150000 -lw 8 -fore 0 -back ffffff -run -animrot 0 90 -shot-1000 -animvideo 300 balloon-klein.mp4 | ||||
| // ./ht -geo Macbeath -gp 10 0 -ibalc -msens 0 -smart .5 -geo beti -canvas-random 0 -zoom .1  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -10 10 -ibal balloon_volume=150000 -lw 8 -fore 0 -back ffffff -run -animrot 0 90 -shot-1000 -animvideo 300 balloon-mcb.mp4 | ||||
| // ./ht -geo Bolza -gp 10 0 -ibalc -msens 0 -smart .5 -geo beti -canvas-random 0 -zoom .1  -sight3 30 -smartlimit 10 -noplayer  -PM 0 -clip -10 10 -ibal balloon_volume=150000 -lw 8 -fore 0 -back ffffff -run -animrot 0 90 -shot-1000 -animvideo 300 balloon-bolza.mp4 | ||||
|  | ||||
| namespace hr { | ||||
|  | ||||
| namespace balloonsim { | ||||
|  | ||||
| #define SIZE 21 | ||||
|  | ||||
| struct data; | ||||
| using tri = array<data*, 3>; | ||||
|  | ||||
| bool hexagonal = true; | ||||
| int donutrad = -1; | ||||
| ld noise = 0; | ||||
|  | ||||
| ld part = 0.5; | ||||
|  | ||||
| struct data { | ||||
|   hyperpoint loc; | ||||
|   hyperpoint vel; | ||||
|   int side; | ||||
|   vector<pair<data*, data*> > tris; | ||||
|   data(hyperpoint h ) { loc = h; vel = C0-C0; side = 0; } | ||||
|   }; | ||||
|  | ||||
| vector<data*> allpoints; | ||||
|  | ||||
| data* top[SIZE][SIZE]; | ||||
| data* bot[SIZE][SIZE]; | ||||
|  | ||||
| vector<pair<data*, data*> > edges; | ||||
|  | ||||
| vector<tri> allfaces; | ||||
| vector<color_t> facecolor; | ||||
|  | ||||
| vector<pair<hyperpoint, hyperpoint> > intersections; | ||||
|  | ||||
| bool draw_intersections; | ||||
|  | ||||
| ld total_volume = 0; | ||||
| ld req_volume = 5; | ||||
|  | ||||
| ld volume_of(hyperpoint a, hyperpoint b, hyperpoint c) { | ||||
|   transmatrix T; | ||||
|   T[0] = a; | ||||
|   T[1] = b; | ||||
|   T[2] = c; | ||||
|   return det3(T); | ||||
|   } | ||||
|  | ||||
| int slowdown = 1; | ||||
|  | ||||
| int steps = 0; | ||||
|  | ||||
| int tsteps = 0, ssteps = 0; | ||||
|  | ||||
| bool physics(int delta) { | ||||
|   if(draw_intersections) return false; | ||||
|   tsteps += delta; | ||||
|   while(tsteps > ssteps) { | ||||
|     ssteps += slowdown; | ||||
|     steps++; | ||||
|  | ||||
|     // surface tension | ||||
|     for(auto e: edges) { | ||||
|       hyperpoint dis = e.second->loc - e.first->loc; | ||||
|       ld len = hypot_d(3, dis); | ||||
|       hyperpoint force = dis * ((len - 1) / len); | ||||
|       e.first->vel += force; | ||||
|       } | ||||
|      | ||||
|     ld pressure = req_volume / max(total_volume, req_volume * 1e-1); | ||||
|     pressure *= 1e-2; | ||||
|      | ||||
|     for(auto t: allfaces) { | ||||
|       hyperpoint e1 = t[1]->loc - t[0]->loc; | ||||
|       hyperpoint e2 = t[2]->loc - t[0]->loc; | ||||
|       hyperpoint cros = (e1 ^ e2); | ||||
|       cros[3] = 0; | ||||
|       // ld croslen = hypot_d(3, cros); | ||||
|       hyperpoint normal = pressure * cros; // * croslen / croslen; | ||||
|       // println(hlog, "normal = ", normal, " cros = ", cros, " pressure = ", pressure); | ||||
|       t[0]->vel += normal; | ||||
|       t[1]->vel += normal; | ||||
|       t[2]->vel += normal; | ||||
|       } | ||||
|  | ||||
|     /* if(false) if(steps < -1000)  | ||||
|       for(auto p: allpoints) p->vel = hyperpoint(0, 0, -p->side, 0); | ||||
|     else | ||||
|       for(auto p: allpoints) p->vel = hyperpoint(0, 0, 0, 0); */ | ||||
|      | ||||
|     ld step = 1e-2; | ||||
|  | ||||
|     // move stuff and friction | ||||
|     for(auto p: allpoints) { | ||||
|       // println(hlog, p->loc, " ++ ", p->vel); | ||||
|       for(auto tr: p->tris) | ||||
|         total_volume += volume_of(p->vel, tr.first->loc - p->loc, tr.second->loc - p->loc) * step; | ||||
|       p->loc = p->loc + p->vel * step; | ||||
|       p->vel = p->vel * .9; | ||||
|       } | ||||
|     println(hlog, "total volume = ", total_volume, " / ", req_volume, " ST = ", steps); | ||||
|     }     | ||||
|   return true; | ||||
|   } | ||||
|  | ||||
| void explore(); | ||||
|  | ||||
| int startid = 0; | ||||
|  | ||||
| void create_balloon() { | ||||
|  | ||||
|   for(int x=0; x<SIZE; x++) | ||||
|   for(int y=0; y<SIZE; y++) { | ||||
|     hyperpoint ini = C0; | ||||
|     ld dx = (x-(SIZE-1)/2); | ||||
|     ld dy = (y-(SIZE-1)/2); | ||||
|     ini[0] += dx + dy/2; | ||||
|     ini[1] += dy * sqrt(3) / 2; | ||||
|  | ||||
|     bool good = false; | ||||
|      | ||||
|     if(hexagonal) { | ||||
|       good = x>0 && y>0 && x<SIZE-1 && y<SIZE-1 && x+y >= SIZE/2+1 && x+y < 3*SIZE/2-1; | ||||
|       good &= (dx>donutrad || dy>donutrad || dx<-donutrad || dy<-donutrad || dx+dy>donutrad || dx+dy<-donutrad); | ||||
|       } | ||||
|     else | ||||
|       good = hdist0(ini) < SIZE * sqrt(3)/4.-2; | ||||
|      | ||||
|     if(good) { | ||||
|       if(x==0 || y==0 || x==SIZE-1 || y==SIZE-1) { | ||||
|         println(hlog, "BUG ", tie(x, y)); | ||||
|         exit(1); | ||||
|         } | ||||
|       top[y][x] = new data(ini); | ||||
|       allpoints.push_back(top[y][x]); | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   vector<pair<int, int> > dirs = | ||||
|     { {-1,0}, {1,0}, {0,-1}, {0,1}, {1, -1}, {-1, 1} }; | ||||
|  | ||||
|   for(int x=0; x<SIZE; x++) | ||||
|   for(int y=0; y<SIZE; y++) if(top[y][x]) { | ||||
|     int nei = 0; | ||||
|     for(pair<int, int> p: dirs) | ||||
|       if(top[y+p.first][x+p.second]) | ||||
|         nei++; | ||||
|     if(nei == 6) { | ||||
|       bot[y][x] = new data(top[y][x]->loc); | ||||
|       allpoints.push_back(bot[y][x]); | ||||
|       top[y][x]->side = 1; | ||||
|       bot[y][x]->side = -1; | ||||
|       } | ||||
|     else | ||||
|       bot[y][x] = top[y][x]; | ||||
|     } | ||||
|  | ||||
|   println(hlog, "all"); | ||||
|    | ||||
|   auto central = [] (array<data*, 3> arr) { | ||||
|     ld dist = hdist0(arr[0]->loc) + hdist0(arr[1]->loc) + hdist0(arr[2]->loc); | ||||
|     return dist <= 4; | ||||
|     }; | ||||
|  | ||||
|   for(int x=0; x<SIZE; x++) | ||||
|   for(int y=0; y<SIZE; y++) if(top[y][x]) { | ||||
|  | ||||
|     for(pair<int, int> p: dirs) | ||||
|       if(top[y+p.first][x+p.second]) { | ||||
|         println(hlog, "len = ", top[y][x]->loc -  top[y+p.first][x+p.second]->loc); | ||||
|         edges.emplace_back(top[y][x], top[y+p.first][x+p.second]); | ||||
|         if(top[y][x] != bot[y][x] || top[y+p.first][x+p.second] != bot[y+p.first][x+p.second]) | ||||
|           edges.emplace_back(bot[y][x], bot[y+p.first][x+p.second]); | ||||
|         } | ||||
|        | ||||
|     println(hlog, "point @ ", tie(x,y)); | ||||
|  | ||||
|     for(auto side: {top, bot}) { | ||||
|       array<data*, 3> arr; | ||||
|       arr[0] = side[y][x]; | ||||
|       arr[1] = side[y][x+1]; | ||||
|       if(side == bot) swap(arr[0], arr[1]); | ||||
|       arr[2] = side[y+1][x]; | ||||
|  | ||||
|       if(arr[0] && arr[1] && arr[2])  { | ||||
|         if(arr[0] == top[SIZE/2][SIZE/2]) startid = isize(allfaces); | ||||
|         allfaces.push_back(arr); | ||||
|         facecolor.push_back(central(arr) ? 0x8080FF : side == top ? 0xFFD500 : 0xC00000); | ||||
|         } | ||||
|  | ||||
|       swap(arr[0], arr[1]); | ||||
|       arr[2] = side[y-1][x+1]; | ||||
|       if(arr[0] && arr[1] && arr[2]) { | ||||
|         allfaces.push_back(arr); | ||||
|         facecolor.push_back(central(arr) ? 0x8080FF : side == top ? 0xFFFF00 : 0xC04000); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   for(auto& f: allfaces) for(int i: {0,1,2}) | ||||
|     f[i]->tris.emplace_back(f[(i+1)%3], f[(i+2)%3]); | ||||
|    | ||||
|   for(auto p: allpoints) p->loc[0] += (randd()-randd()) * noise; | ||||
|    | ||||
|   println(hlog, "points = ", isize(allpoints)); | ||||
|   println(hlog, "edges = ", isize(edges)); | ||||
|   println(hlog, "faces = ", isize(allfaces)); | ||||
|   } | ||||
|  | ||||
| void compute_intersections() { | ||||
|   intersections.clear(); | ||||
|   for(auto& f1: allfaces) | ||||
|   for(auto& f2: allfaces) { | ||||
|    | ||||
|     if(f1 == f2) break; | ||||
|    | ||||
|     bool adjacent = false; | ||||
|  | ||||
|     for(int i=0; i<3; i++) | ||||
|     for(int j=0; j<3; j++) | ||||
|       if(f1[i] == f2[j]) | ||||
|         adjacent = true; | ||||
|      | ||||
|     if(adjacent) continue; | ||||
|      | ||||
|     vector<hyperpoint> ix; | ||||
|      | ||||
|     for(int i=0; i<2; i++) { | ||||
|       auto& f = i ? f1 : f2; | ||||
|       auto& g = i ? f2 : f1; | ||||
|       hyperpoint cros = (f[1]->loc-f[0]->loc) ^ (f[2]->loc-f[0]->loc); | ||||
|       ld dotval = dot_d(3, f[1]->loc, cros); | ||||
|       transmatrix T; | ||||
|       for(int i=0; i<3; i++) | ||||
|         set_column(T, i, f[i]->loc); | ||||
|       set_column(T, 3, C0); | ||||
|       T = inverse(T); | ||||
|       for(int i=0; i<3; i++) { | ||||
|         hyperpoint g1 = g[i]->loc; | ||||
|         hyperpoint g2 = g[(i+1)%3]->loc; | ||||
|         ld dg1 = dot_d(3, g1, cros); | ||||
|         ld dg2 = dot_d(3, g2, cros); | ||||
|         if(dg1 == dg2) continue; | ||||
|         ld il = ilerp(dg1, dg2, dotval); | ||||
|         if(il < 0 || il > 1) continue; | ||||
|         hyperpoint cp = lerp(g1, g2, il); | ||||
|         hyperpoint res = T * cp; | ||||
|         if(res[0] >= 0 && res[1] >= 0 && res[2] >= 0) | ||||
|           ix.push_back(cp); | ||||
|         } | ||||
|       } | ||||
|     if(ix.empty()) continue; | ||||
|     if(isize(ix) != 2) { | ||||
|       println(hlog, "ix is: ", ix); | ||||
|       intersections.emplace_back(ix[0], ix[0] + hyperpoint(1,0,0,0)); | ||||
|       continue; | ||||
|       } | ||||
|     sort(ix.begin(), ix.end()); | ||||
|     intersections.emplace_back(ix[0], ix.back()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| hyperpoint lownoise() { | ||||
|   hyperpoint h; | ||||
|   h[3] = 1; | ||||
|   for(int i=0; i<3; i++) | ||||
|     h[i] = randd() * 1e-2; | ||||
|   return h; | ||||
|   } | ||||
|  | ||||
| void delocate_balloon() { | ||||
|   for(auto p: allpoints) | ||||
|     p->loc = lownoise(); | ||||
|   } | ||||
|  | ||||
| map<cell*, int> dist; | ||||
|  | ||||
| void current_balloon() { | ||||
|   auto ac = currentmap->allcells(); | ||||
|   map<cell*, data*> pts; | ||||
|    | ||||
|   for(auto c: ac) dist[c] = c->type != 6 ? 0 : 100; | ||||
|   for(int i=0; i<50; i++) | ||||
|   for(auto c: ac) forCellEx(c1, c)  | ||||
|     dist[c1] = min(dist[c1], dist[c]+1); | ||||
|    | ||||
|   int maxdist = 0; | ||||
|   for(auto c: ac) maxdist = max(maxdist, dist[c]); | ||||
|  | ||||
|   for(auto c: ac) { | ||||
|     pts[c] = new data(lownoise()); | ||||
|     allpoints.push_back(pts[c]); | ||||
|     } | ||||
|    | ||||
|   for(auto c: ac) forCellEx(c1, c) | ||||
|     edges.emplace_back(pts[c], pts[c1]); | ||||
|  | ||||
|   for(auto c: ac) for(int i=0; i<c->type; i++) { | ||||
|     cellwalker cw(c, i); | ||||
|     array<data*, 3> res; | ||||
|     int tdist = 0; | ||||
|     for(int i=0; i<3; i++) { | ||||
|       tdist += dist[cw.at]; | ||||
|       res[i] = pts[cw.at]; | ||||
|       cw += wstep; | ||||
|       cw++; | ||||
|       } | ||||
|     if(cw != cellwalker(c, i)) throw hr_exception("wrong!"); | ||||
|     if(res[0] > res[1] && res[0] > res[2]) { | ||||
|       allfaces.push_back(res); | ||||
|       facecolor.push_back(gradient(0xFF0000, 0x00FF00, 0, tdist, maxdist*3)); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   for(auto& f: allfaces) for(int i: {0,1,2}) | ||||
|     f[i]->tris.emplace_back(f[(i+1)%3], f[(i+2)%3]); | ||||
|  | ||||
|   rogueviz::rv_hook(hooks_drawcell, 50, [maxdist] (cell *c, const shiftmatrix& V) { | ||||
|     for(int i=0; i<c->type; i++) { | ||||
|       cellwalker cw(c, i); | ||||
|       array<cell*, 3> res; | ||||
|       int tdist = 0; | ||||
|       for(int i=0; i<3; i++) { | ||||
|         tdist += dist[cw.at]; | ||||
|         res[i] = cw.at; | ||||
|         cw += wstep; | ||||
|         cw++; | ||||
|         } | ||||
|       if(res[0] > res[1] && res[0] > res[2]) { | ||||
|         curvepoint(C0); | ||||
|         curvepoint(currentmap->adj(c, i) * C0); | ||||
|         curvepoint(currentmap->adj(c, gmod(i-1, c->type)) * C0); | ||||
|         queuecurve(V, (forecolor << 8) | 0xFF, gradient(0xFF0000FF, 0x00FF00FF, 0, tdist, maxdist*3), PPR::FLOOR); | ||||
|         } | ||||
|       } | ||||
|     return false; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| void init_balloon() { | ||||
|  | ||||
|   if(allpoints.empty()) { | ||||
|     create_balloon(); | ||||
|     } | ||||
|  | ||||
|   rogueviz::rv_hook(shmup::hooks_turn, 100, physics); | ||||
|  | ||||
|   rogueviz::rv_hook(hooks_frame, 100, [] { | ||||
|     shiftmatrix T = ggmatrix(currentmap->gamestart()); | ||||
|      | ||||
|     if(draw_intersections) { | ||||
|       for(auto p: intersections) | ||||
|         queueline(T*p.first, T*p.second, 0x0000FFFF).prio = PPR::SUPERLINE; | ||||
|       } | ||||
|      | ||||
|     shiftmatrix T1 = T; | ||||
|     if(pmodel == mdDisk) T1[2][3] -= 0.01; | ||||
|     for(auto e: edges) | ||||
|       queueline(T1*e.first->loc, T1*e.second->loc, (forecolor << 8) | 0xFF).prio = PPR::WALL; | ||||
|     int id = 0; | ||||
|     for(auto f: allfaces) { | ||||
|       curvepoint(f[0]->loc); | ||||
|       curvepoint(f[1]->loc); | ||||
|       curvepoint(f[2]->loc); | ||||
|       if(part) { | ||||
|         hyperpoint ctr = (f[0]->loc + f[1]->loc + f[2]->loc) / 3; | ||||
|         curvepoint(f[0]->loc); | ||||
|         curvepoint(lerp(ctr, f[0]->loc, part)); | ||||
|         curvepoint(lerp(ctr, f[1]->loc, part)); | ||||
|         curvepoint(lerp(ctr, f[2]->loc, part)); | ||||
|         curvepoint(lerp(ctr, f[0]->loc, part)); | ||||
|         } | ||||
|       if(!anyshiftclick) queuecurve(T, 0, (facecolor[id++] << 8) | 0xFF, PPR::WALL); | ||||
|       } | ||||
|     });   | ||||
|  | ||||
|   rogueviz::rv_hook(hooks_handleKey, 50, [] (int sym, int uni) { | ||||
|     if((cmode & sm::NORMAL) && uni == 'r') { | ||||
|       dialog::editNumber(req_volume, 100, 1000000000, .1, 1000000, "", ""); | ||||
|       dialog::scaleLog(); | ||||
|       return true; | ||||
|       } | ||||
|     if((cmode & sm::NORMAL) && uni == 'e') { | ||||
|       explore(); | ||||
|       return true; | ||||
|       } | ||||
|     if((cmode & sm::NORMAL) && uni == 'i') { | ||||
|       draw_intersections = !draw_intersections; | ||||
|       if(draw_intersections) compute_intersections(); | ||||
|       return true; | ||||
|       } | ||||
|     return false; | ||||
|     }); | ||||
|    | ||||
|   param_f(req_volume, "balloon_volume");   | ||||
|   } | ||||
|  | ||||
| int t = 3; | ||||
|  | ||||
| struct hrmap_arbi_full : hrmap { | ||||
|   vector<heptagon*> alls; | ||||
|   heptagon *getOrigin() override { return alls[startid]; } | ||||
|    | ||||
|   hrmap_arbi_full() { | ||||
|     auto& cur = arb::current; | ||||
|     int N = isize(allfaces); | ||||
|     alls.resize(N); | ||||
|      | ||||
|     println(hlog, "creating a map of size ", N); | ||||
|  | ||||
|     for(int i=0; i<N; i++) { | ||||
|       auto& h = alls[i]; | ||||
|       h = tailored_alloc<heptagon> (t); /* some compilerbug happens when we put 3 directly?? */ | ||||
|       h->zebraval = i; | ||||
|       h->c7 = newCell(3, h); | ||||
|       h->alt = nullptr; | ||||
|       h->cdata = nullptr; | ||||
|       h->emeraldval = 0; | ||||
|       h->distance = 0; | ||||
|       } | ||||
|  | ||||
|     for(int i=0; i<N; i++)  | ||||
|       for(int d=0; d<3; d++) { | ||||
|         auto& con = cur.shapes[i].connections[d]; | ||||
|         alls[i]->c.connect(d, alls[con.sid], con.eid, con.mirror); | ||||
|         } | ||||
|  | ||||
|     println(hlog, "finished, startid = ", startid); | ||||
|     } | ||||
|  | ||||
|   transmatrix adj(heptagon *h, int dl) override {  | ||||
|     return arb::get_adj(arb::current_or_slided(), arb::id_of(h), dl, h->c.move(dl) ? arb::id_of(h->c.move(dl)) : -1,  h->c.move(dl) ? h->c.spin(dl) : -1); | ||||
|     } | ||||
|  | ||||
|   ld spin_angle(cell *c, int d) override { return SPIN_NOT_AVAILABLE; } | ||||
|  | ||||
|   int shvid(cell *c) override { | ||||
|     return arb::id_of(c->master); | ||||
|     } | ||||
|  | ||||
|   hyperpoint get_corner(cell *c, int cid, ld cf) override { | ||||
|     auto& sh = arb::current_or_slided().shapes[arb::id_of(c->master)]; | ||||
|     int id = gmod(cid, c->type); | ||||
|     return normalize(C0 + (sh.vertices[id] - C0) * 3 / cf); | ||||
|     } | ||||
|  | ||||
|   ~hrmap_arbi_full() { | ||||
|     clearfrom(getOrigin()); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| void explore() { | ||||
|   auto& cur = arb::current; | ||||
|   int N = isize(allfaces); | ||||
|  | ||||
|   ginf[gArbitrary].g = giEuclid2; | ||||
|   ginf[gArbitrary].sides = 7; | ||||
|   set_flag(ginf[gArbitrary].flags, qBOUNDED, true); | ||||
|   set_flag(ginf[gArbitrary].flags, qAFFINE, false); | ||||
|   geom3::apply_always3(); | ||||
|  | ||||
|   set_geometry(gCubeTiling); | ||||
|    | ||||
|   map<pair<data*, data*>, arb::connection_t > adjacent; | ||||
|  | ||||
|   for(int i=0; i<N; i++) {    | ||||
|     auto& t = allfaces[i]; | ||||
|     for(int j=0; j<3; j++) | ||||
|       adjacent[make_pair(t[(j+1)%3], t[j])] = arb::connection_t{i, j, 0}; | ||||
|     } | ||||
|  | ||||
|   arb::set_defaults(cur, false, "balloon"); | ||||
|   cur.shapes.resize(N); | ||||
|   for(int i=0; i<N; i++) {    | ||||
|     auto& cc = cur.shapes[i]; | ||||
|     cc.id = i; | ||||
|     cc.vertices.resize(3); | ||||
|     cc.flags = 0; | ||||
|     cc.repeat_value = 1; | ||||
|     auto& t = allfaces[i]; | ||||
|     hyperpoint cros = (t[1]->loc - t[0]->loc) ^ (t[2]->loc - t[0]->loc); | ||||
|     cros /= hypot_d(3, cros); | ||||
|     transmatrix T; | ||||
|     if(1) { | ||||
|       dynamicval<eGeometry> g(geometry, gSphere); | ||||
|       T = gpushxto0(cros); | ||||
|       for(int i=0; i<4; i++) T[3][i] = T[i][3] = i==3; | ||||
|       } | ||||
|      | ||||
|     hyperpoint ctr = (t[0]->loc + t[1]->loc + t[2]->loc) / 3; | ||||
|     recompute: | ||||
|     for(int j=0; j<3; j++) { | ||||
|       cc.vertices[j] = T * (t[j]->loc - ctr); | ||||
|       // println(hlog, tie(i,j), " : ", cc.vertices[j]); | ||||
|       cc.vertices[j][2] = 1; | ||||
|       } | ||||
|      | ||||
|     cc.edges.resize(3); | ||||
|     for(int j=0; j<3; j++) { | ||||
|       cc.edges[j] = hdist(cc.vertices[j], cc.vertices[(j+1)%3]); | ||||
|       } | ||||
|     cc.angles.resize(3); | ||||
|     for(int j=0; j<3; j++) cc.angles[j] = 1; | ||||
|  | ||||
|     ld area = ((cc.vertices[1]-cc.vertices[0]) ^ (cc.vertices[2]-cc.vertices[0])) [2]; | ||||
|     println(hlog, "area = ", area); | ||||
|     if(area < 0) { | ||||
|       T = MirrorX * T; | ||||
|       println(hlog, "need to recompute triangle ", i); | ||||
|       goto recompute; | ||||
|       } | ||||
|      | ||||
|     cc.connections.resize(3); | ||||
|     for(int j=0; j<3; j++) | ||||
|       cc.connections[j] = adjacent.at(make_pair(t[j], t[(j+1)%3])); | ||||
|     cc.stretch_shear.resize(3, make_pair(1, 0)); | ||||
|     }     | ||||
|    | ||||
|   set_geometry(gArbitrary); | ||||
|    | ||||
|   rogueviz::rv_hook(hooks_newmap, 0, [] { | ||||
|     return new hrmap_arbi_full; | ||||
|     }); | ||||
|    | ||||
|   cur.cscale = 1; | ||||
|  | ||||
|   vid.cells_drawn_limit = 100000; | ||||
|   canvas_default_wall = waNone; | ||||
|   start_game();   | ||||
|   ginf[geometry].distlimit[0] = cgi.base_distlimit = 20; | ||||
|   pconf.scale = 1; | ||||
|    | ||||
|   hrmap_arbi_full *m = (hrmap_arbi_full*) currentmap; | ||||
|   for(int i=0; i<isize(allfaces); i++) { | ||||
|     setdist(m->alls[i]->c7, 0, nullptr); | ||||
|     m->alls[i]->c7->landparam = facecolor[i]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
| auto shot_hooks = arg::add3("-ibal", init_balloon) + arg::add3("-ibalc", current_balloon) + arg::add3("-ibale", explore); | ||||
|  | ||||
| } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue