mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	Arcmedge now accepts a^:b which means that a is repeated b times. Also the computations now work for real a, b
This commit is contained in:
		| @@ -152,6 +152,29 @@ void archimedean_tiling::make_match(int a, int i, int b, int j) { | |||||||
| /** mostly to protect the user from entering too large numbers */ | /** mostly to protect the user from entering too large numbers */ | ||||||
| const int MAX_EDGE_ARCM = FULL_EDGE; | const int MAX_EDGE_ARCM = FULL_EDGE; | ||||||
|  |  | ||||||
|  | /** compute the edge length of an Archimedean tiling. Each element of facemul is (face sides, multiplicity) */ | ||||||
|  | EX ld compute_edgelength(vector<pair<ld, ld>> facemul, ld halftotal IS(M_PI)) { | ||||||
|  |   ld elmin = 0, elmax = hyperbolic ? 10 : sphere ? M_PI : 2 * euclidean_edge_length; | ||||||
|  |   ld edgelength; | ||||||
|  |   for(int p=0; p<100; p++) { | ||||||
|  |     edgelength = (elmin + elmax) / 2; | ||||||
|  |     ld alpha_total = 0; | ||||||
|  |     for(auto fm: facemul) { | ||||||
|  |       ld gamma = M_PI / fm.first; | ||||||
|  |       auto c = asin_auto(sin_auto(edgelength/2) / sin(gamma)); | ||||||
|  |       hyperpoint h = xpush(c) * spin(M_PI - 2*gamma) * xpush0(c); | ||||||
|  |       ld a = atan2(h); | ||||||
|  |       cyclefix(a, 0); | ||||||
|  |       if(a < 0) a = -a; | ||||||
|  |       alpha_total += a * fm.second; | ||||||
|  |       } | ||||||
|  |     if(isnan(alpha_total)) elmax = edgelength; | ||||||
|  |     else if(sphere ^ (alpha_total > halftotal)) elmin = edgelength; | ||||||
|  |     else elmax = edgelength; | ||||||
|  |     } | ||||||
|  |   return edgelength; | ||||||
|  |   } | ||||||
|  |  | ||||||
| void archimedean_tiling::compute_sum() { | void archimedean_tiling::compute_sum() { | ||||||
|   N = isize(faces); |   N = isize(faces); | ||||||
|   euclidean_angle_sum = 0; |   euclidean_angle_sum = 0; | ||||||
| @@ -436,6 +459,7 @@ void archimedean_tiling::compute_geometry() { | |||||||
|       inradius[i] = 0; |       inradius[i] = 0; | ||||||
|     } |     } | ||||||
|   else for(int p=0; p<100; p++) { |   else for(int p=0; p<100; p++) { | ||||||
|  |     /* unfortunately we cannot just use compute_edgelength because we need to set other values */ | ||||||
|     edgelength = (elmin + elmax) / 2; |     edgelength = (elmin + elmax) / 2; | ||||||
|      |      | ||||||
|     ld alpha_total = 0; |     ld alpha_total = 0; | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								util.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								util.cpp
									
									
									
									
									
								
							| @@ -240,19 +240,21 @@ cld exp_parser::parse(int prio) { | |||||||
|     } |     } | ||||||
|   #if CAP_ARCM |   #if CAP_ARCM | ||||||
|   else if(eat("arcmedge(")) { |   else if(eat("arcmedge(")) { | ||||||
|     vector<int> vals; |     if(!hyperbolic && !sphere) throw hr_parse_exception("arcmedge works only in hyperbolic and spherical geometry"); | ||||||
|     vals.push_back(iparse(0)); |     vector<pair<ld, ld>> vals; | ||||||
|  |     vals.emplace_back(rparse(0), 1); | ||||||
|     while(true) { |     while(true) { | ||||||
|       skip_white(); |       skip_white(); | ||||||
|       if(eat(",")) vals.push_back(iparse(0)); |       if(eat(":^")) { | ||||||
|  |         ld rep = rparse(0); | ||||||
|  |         vals.back().second *= rep; | ||||||
|  |         } | ||||||
|  |       if(eat(",")) vals.emplace_back(rparse(0), 1); | ||||||
|       else break; |       else break; | ||||||
|       } |       } | ||||||
|     force_eat(")"); |     force_eat(")"); | ||||||
|     arcm::archimedean_tiling test; |     res = arcm::compute_edgelength(vals); | ||||||
|     test.faces = vals; |     if(real(res) < 1e-10) throw hr_parse_exception("wrong geometry for this arcmedge"); | ||||||
|     test.compute_sum(); |  | ||||||
|     test.compute_geometry(); |  | ||||||
|     res = test.edgelength; |  | ||||||
|     if (auto *distunit = hr::at_or_null(extra_params, "distunit")) |     if (auto *distunit = hr::at_or_null(extra_params, "distunit")) | ||||||
|       res /= *distunit; |       res /= *distunit; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue