mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-29 21:13:00 +00:00 
			
		
		
		
	Clifford torus embedding (needs to be configured manually and on a straight square for now)
This commit is contained in:
		
							
								
								
									
										14
									
								
								geometry.cpp
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								geometry.cpp
									
									
									
									
									
								
							| @@ -1080,7 +1080,7 @@ EX namespace geom3 { | |||||||
|     seProduct, |     seProduct, | ||||||
|     seNil, |     seNil, | ||||||
|     seSol, seNIH, seSolN, |     seSol, seNIH, seSolN, | ||||||
|     seNIH_inv |     seCliffordTorus | ||||||
|     }; |     }; | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
| @@ -1094,6 +1094,7 @@ EX namespace geom3 { | |||||||
|     {"Sol",              "Embed into Sol. Works only with Euclidean. You need to set the variation to Pure."}, |     {"Sol",              "Embed into Sol. Works only with Euclidean. You need to set the variation to Pure."}, | ||||||
|     {"stretched hyperbolic",              "Embed into stretched hyperbolic geometry. Works only with Euclidean. You need to set the variation to Pure."}, |     {"stretched hyperbolic",              "Embed into stretched hyperbolic geometry. Works only with Euclidean. You need to set the variation to Pure."}, | ||||||
|     {"stretched Sol",              "Embed into stretched Sol geometry. Works only with Euclidean. You need to set the variation to Pure."}, |     {"stretched Sol",              "Embed into stretched Sol geometry. Works only with Euclidean. You need to set the variation to Pure."}, | ||||||
|  |     {"Clifford Torus",              "Embed Euclidean torus into S3. You need to set the variation to Pure."}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   EX eSpatialEmbedding spatial_embedding = seDefault; |   EX eSpatialEmbedding spatial_embedding = seDefault; | ||||||
| @@ -1132,13 +1133,17 @@ EX namespace geom3 { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   EX bool euc_in_noniso() { |   EX bool euc_in_noniso() { | ||||||
|     return among(ggclass(), gcNil, gcSol, gcNIH, gcSolN) && mgclass() == gcEuclid; |     return among(ggclass(), gcNil, gcSol, gcNIH, gcSolN, gcSphere) && mgclass() == gcEuclid; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   EX bool sph_in_euc() { |   EX bool sph_in_euc() { | ||||||
|     return ggclass() == gcEuclid && mgclass() == gcSphere; |     return ggclass() == gcEuclid && mgclass() == gcSphere; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   EX bool euc_in_sph() { | ||||||
|  |     return ggclass() == gcSphere && mgclass() == gcEuclid; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   EX bool sph_in_hyp() { |   EX bool sph_in_hyp() { | ||||||
|     return ggclass() == gcHyperbolic && mgclass() == gcSphere; |     return ggclass() == gcHyperbolic && mgclass() == gcSphere; | ||||||
|     } |     } | ||||||
| @@ -1220,6 +1225,11 @@ EX namespace geom3 { | |||||||
|             g.gameplay_dimension = 2; |             g.gameplay_dimension = 2; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |           if(spatial_embedding == seCliffordTorus && ieuclid) { | ||||||
|  |             g = ginf[gCell120].g; | ||||||
|  |             g.gameplay_dimension = 2; | ||||||
|  |             } | ||||||
|  |  | ||||||
|           bool ieuc_or_binary = ieuclid || (gi.flags & qBINARY); |           bool ieuc_or_binary = ieuclid || (gi.flags & qBINARY); | ||||||
|  |  | ||||||
|           if(spatial_embedding == seSol && ieuc_or_binary) { |           if(spatial_embedding == seSol && ieuc_or_binary) { | ||||||
|   | |||||||
| @@ -442,7 +442,7 @@ EX bool no_easy_spin() { | |||||||
|   return NONSTDVAR || arcm::in() || WDIM == 3 || bt::in() || kite::in(); |   return NONSTDVAR || arcm::in() || WDIM == 3 || bt::in() || kite::in(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| EX bool dont_inverse() { return geometry == 1 && PURE && geom3::euc_in_noniso(); } | EX bool dont_inverse() { return meuclid && PURE && geom3::euc_in_noniso(); } | ||||||
|  |  | ||||||
| ld hrmap_standard::spin_angle(cell *c, int d) { | ld hrmap_standard::spin_angle(cell *c, int d) { | ||||||
|   if(WDIM == 3) return SPIN_NOT_AVAILABLE; |   if(WDIM == 3) return SPIN_NOT_AVAILABLE; | ||||||
|   | |||||||
| @@ -572,6 +572,15 @@ EX hyperpoint normalize_flat(hyperpoint h) { | |||||||
|   if(geom3::euc_in_nil()) h[1] = 0; |   if(geom3::euc_in_nil()) h[1] = 0; | ||||||
|   if(geom3::euc_in_solnih()) h[2] = 0; |   if(geom3::euc_in_solnih()) h[2] = 0; | ||||||
|   if(geom3::hyp_in_solnih()) h[0] = 0; |   if(geom3::hyp_in_solnih()) h[0] = 0; | ||||||
|  |   if(geom3::euc_in_sph()) { | ||||||
|  |     ld tx = hypot(h[0], h[2]); | ||||||
|  |     ld ty = hypot(h[1], h[3]); | ||||||
|  |     h[0] = h[0] / tx * sin(1); | ||||||
|  |     h[1] = h[1] / ty * cos(1); | ||||||
|  |     h[2] = h[2] / tx * sin(1); | ||||||
|  |     h[3] = h[3] / ty * cos(1); | ||||||
|  |     return h; | ||||||
|  |     } | ||||||
|   if(geom3::euc_in_hyp()) { |   if(geom3::euc_in_hyp()) { | ||||||
|     h = normalize(h); |     h = normalize(h); | ||||||
|     auto h1 = deparabolic13(h); |     auto h1 = deparabolic13(h); | ||||||
| @@ -837,6 +846,19 @@ EX hyperpoint orthogonal_move(const hyperpoint& h, ld z) { | |||||||
|     hf[3] = cosh(z0 + z); |     hf[3] = cosh(z0 + z); | ||||||
|     return hf; |     return hf; | ||||||
|     } |     } | ||||||
|  |   if(geom3::euc_in_sph()) { | ||||||
|  |     // cspin(0,2,x) * cspin(1,3,y) * cspin0(2, 3, z) | ||||||
|  |     ld tx = hypot(h[0], h[2]); | ||||||
|  |     ld ty = hypot(h[1], h[3]); | ||||||
|  |     ld z0 = atan2(ty, tx); | ||||||
|  |     z0 -= z; | ||||||
|  |     hyperpoint hf; | ||||||
|  |     hf[0] = h[0] / tx * cos(z0); | ||||||
|  |     hf[1] = h[1] / ty * sin(z0); | ||||||
|  |     hf[2] = h[2] / tx * cos(z0); | ||||||
|  |     hf[3] = h[3] / ty * sin(z0); | ||||||
|  |     return hf; | ||||||
|  |     } | ||||||
|   if(GDIM == 2) return scale_point(h, geom3::scale_at_lev(z)); |   if(GDIM == 2) return scale_point(h, geom3::scale_at_lev(z)); | ||||||
|   if(gproduct) return scale_point(h, exp(z)); |   if(gproduct) return scale_point(h, exp(z)); | ||||||
|   if(sl2) return slr::translate(h) * cpush0(2, z); |   if(sl2) return slr::translate(h) * cpush0(2, z); | ||||||
| @@ -874,6 +896,11 @@ EX transmatrix matrix4(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i, ld | |||||||
|   #endif |   #endif | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | EX void euc_in_sph_rescale(hyperpoint& h) { | ||||||
|  |   h[0] *= TAU * geom3::euclid_embed_scale; | ||||||
|  |   h[1] *= TAU * geom3::euclid_embed_scale; | ||||||
|  |   } | ||||||
|  |  | ||||||
| #if MAXMDIM >= 4 | #if MAXMDIM >= 4 | ||||||
| /** Transform a matrix between the 'embedded_plane' and underlying representation. Switches to the current variant. */ | /** Transform a matrix between the 'embedded_plane' and underlying representation. Switches to the current variant. */ | ||||||
| EX void swapmatrix(transmatrix& T) { | EX void swapmatrix(transmatrix& T) { | ||||||
| @@ -916,6 +943,11 @@ EX void swapmatrix(transmatrix& T) { | |||||||
|   else if(geom3::in_product()) { |   else if(geom3::in_product()) { | ||||||
|     /* just do nothing */ |     /* just do nothing */ | ||||||
|     } |     } | ||||||
|  |   else if(geom3::euc_in_sph()) { | ||||||
|  |     hyperpoint h1 = get_column(T, 2); | ||||||
|  |     euc_in_sph_rescale(h1); | ||||||
|  |     T = cspin(0, 2, h1[0]) * cspin(1, 3, h1[1]); | ||||||
|  |     } | ||||||
|   else { |   else { | ||||||
|     for(int i=0; i<4; i++) swap(T[i][2], T[i][3]); |     for(int i=0; i<4; i++) swap(T[i][2], T[i][3]); | ||||||
|     for(int i=0; i<4; i++) swap(T[2][i], T[3][i]); |     for(int i=0; i<4; i++) swap(T[2][i], T[3][i]); | ||||||
| @@ -934,6 +966,10 @@ EX void swapmatrix(hyperpoint& h) { | |||||||
|   if(geom3::sph_in_euc()) { h[3] = 1; return; } |   if(geom3::sph_in_euc()) { h[3] = 1; return; } | ||||||
|   if(geom3::sph_in_hyp()) { h[0] *= sinh(1); h[1] *= sinh(1); h[2] *= sinh(1); h[3] = cosh(1); return; } |   if(geom3::sph_in_hyp()) { h[0] *= sinh(1); h[1] *= sinh(1); h[2] *= sinh(1); h[3] = cosh(1); return; } | ||||||
|   if(geom3::euc_in_nil()) { h[3] = 1; h[2] = h[1] * geom3::euclid_embed_scale; h[1] = 0; h[0] *= geom3::euclid_embed_scale; return; } |   if(geom3::euc_in_nil()) { h[3] = 1; h[2] = h[1] * geom3::euclid_embed_scale; h[1] = 0; h[0] *= geom3::euclid_embed_scale; return; } | ||||||
|  |   if(geom3::euc_in_sph()) { | ||||||
|  |     euc_in_sph_rescale(h); h = cspin(0, 2, h[0]) * cspin(1, 3, h[1]) * lzpush(1) * C0; | ||||||
|  |     return; | ||||||
|  |     } | ||||||
|   if(geom3::euc_in_solnih()) { h[3] = 1; h[1] = h[1] * geom3::euclid_embed_scale; h[2] = 0; h[0] *= geom3::euclid_embed_scale; return; } |   if(geom3::euc_in_solnih()) { h[3] = 1; h[1] = h[1] * geom3::euclid_embed_scale; h[2] = 0; h[0] *= geom3::euclid_embed_scale; return; } | ||||||
|   if(geom3::hyp_in_solnih()) { |   if(geom3::hyp_in_solnih()) { | ||||||
|     // copied from deparabolic13 |     // copied from deparabolic13 | ||||||
| @@ -1524,12 +1560,14 @@ EX hyperpoint scale_point(const hyperpoint& h, ld scale_factor) { | |||||||
| EX bool moved_center() { | EX bool moved_center() { | ||||||
|   if(geom3::sph_in_euc()) return true; |   if(geom3::sph_in_euc()) return true; | ||||||
|   if(geom3::sph_in_hyp()) return true; |   if(geom3::sph_in_hyp()) return true; | ||||||
|  |   if(geom3::euc_in_sph()) return true; | ||||||
|   return false; |   return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| /** Returns the intended center of the tile, relative to its local matrix. Usually C0 but may be different, e.g. when embedding a sphere in E3 or H3. */ | /** Returns the intended center of the tile, relative to its local matrix. Usually C0 but may be different, e.g. when embedding a sphere in E3 or H3. */ | ||||||
| EX hyperpoint tile_center() { | EX hyperpoint tile_center() { | ||||||
|   if(geom3::sph_in_euc()) return C02 + C03; |   if(geom3::sph_in_euc()) return C02 + C03; | ||||||
|  |   if(geom3::euc_in_sph()) return zpush0(1); | ||||||
|   if(geom3::sph_in_hyp()) return zpush0(1); |   if(geom3::sph_in_hyp()) return zpush0(1); | ||||||
|   return C0; |   return C0; | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								hypgraph.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								hypgraph.cpp
									
									
									
									
									
								
							| @@ -2028,7 +2028,7 @@ EX void adjust_eye(transmatrix& T, cell *c, ld sign) { | |||||||
|   geom3::do_auto_eye(); |   geom3::do_auto_eye(); | ||||||
|   int sl = snakelevel(c); |   int sl = snakelevel(c); | ||||||
|   if(isWorm(c->monst) && sl < 3) sl++; |   if(isWorm(c->monst) && sl < 3) sl++; | ||||||
|   int i = geom3::sph_in_low() ? 1 : 0; |   int i = moved_center() ? 1 : 0; | ||||||
|   if(sl || vid.eye || i) |   if(sl || vid.eye || i) | ||||||
|     T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i)); |     T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i)); | ||||||
|   } |   } | ||||||
| @@ -2917,7 +2917,7 @@ EX namespace dq { | |||||||
|   EX set<unsigned> visited_by_matrix; |   EX set<unsigned> visited_by_matrix; | ||||||
|   EX void enqueue_by_matrix(heptagon *h, const shiftmatrix& T) { |   EX void enqueue_by_matrix(heptagon *h, const shiftmatrix& T) { | ||||||
|     if(!h) return; |     if(!h) return; | ||||||
|     unsigned b = bucketer(tC0(T)); |     unsigned b = bucketer(T * tile_center()); | ||||||
|     if(visited_by_matrix.count(b)) { return; } |     if(visited_by_matrix.count(b)) { return; } | ||||||
|     visited_by_matrix.insert(b); |     visited_by_matrix.insert(b); | ||||||
|     drawqueue.emplace(h, T); |     drawqueue.emplace(h, T); | ||||||
| @@ -2934,7 +2934,7 @@ EX namespace dq { | |||||||
|  |  | ||||||
|   EX void enqueue_by_matrix_c(cell *c, const shiftmatrix& T) { |   EX void enqueue_by_matrix_c(cell *c, const shiftmatrix& T) { | ||||||
|     if(!c) return; |     if(!c) return; | ||||||
|     unsigned b = bucketer(tC0(T)); |     unsigned b = bucketer(T * tile_center()); | ||||||
|     if(visited_by_matrix.count(b)) { return; } |     if(visited_by_matrix.count(b)) { return; } | ||||||
|     visited_by_matrix.insert(b); |     visited_by_matrix.insert(b); | ||||||
|     drawqueue_c.emplace(c, T); |     drawqueue_c.emplace(c, T); | ||||||
| @@ -3368,6 +3368,11 @@ EX transmatrix map_relative_push(hyperpoint h) { | |||||||
|     geom3::light_flip(false); |     geom3::light_flip(false); | ||||||
|     return T * zpush(z); |     return T * zpush(z); | ||||||
|     } |     } | ||||||
|  |   if(geom3::euc_in_sph()) { | ||||||
|  |     ld tx = hypot(h[0], h[2]); | ||||||
|  |     ld ty = hypot(h[1], h[3]); | ||||||
|  |     return cspin(0, 2, atan2(h[0], h[2])) * cspin(1, 3, atan2(h[1], h[3])) * cspin(2, 3, atan2(tx, ty)); | ||||||
|  |     } | ||||||
|   return rgpushxto0(h); |   return rgpushxto0(h); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue