From 32c6228319b179d69c42bf4290c318913c1d15d7 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 22 Mar 2020 11:27:06 +0100 Subject: [PATCH] arb:: utilities for making Archimedean tilings --- arbitrile.cpp | 5 +++++ archimedean.cpp | 19 ++++++++++++------- util.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/arbitrile.cpp b/arbitrile.cpp index 93d38125..3c4b0b03 100644 --- a/arbitrile.cpp +++ b/arbitrile.cpp @@ -107,6 +107,11 @@ EX void load(const string& fname) { ep.force_eat(")"); }; while(true) { + + ep.extra_params["distunit"] = distunit; + ep.extra_params["angleunit"] = angleunit; + ep.extra_params["angleofs"] = angleofs; + ep.skip_white(); if(ep.next() == 0) break; if(ep.eat("#")) { diff --git a/archimedean.cpp b/archimedean.cpp index 652fd226..14b6fbc4 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -42,6 +42,7 @@ struct archimedean_tiling { void make_match(int a, int i, int b, int j); void prepare(); + void compute_sum(); void compute_geometry(); void parse(); @@ -135,11 +136,20 @@ void archimedean_tiling::make_match(int a, int i, int b, int j) { /** mostly to protect the user from entering too large numbers */ const int MAX_EDGE_ARCM = FULL_EDGE; -void archimedean_tiling::prepare() { - +void archimedean_tiling::compute_sum() { + N = isize(faces); euclidean_angle_sum = 0; for(int f: faces) euclidean_angle_sum += (f-2.) / f; + real_faces = 0, real_face_type = 0; + for(int i=0; i 2) real_faces++, real_face_type += faces[i]; + real_face_type /= 2; + } + +void archimedean_tiling::prepare() { + + compute_sum(); + for(int i: faces) if(i > MAX_EDGE_ARCM) { errormsg = XLAT("currently no more than %1 edges", its(MAX_EDGE_ARCM)); errors++; @@ -161,10 +171,6 @@ void archimedean_tiling::prepare() { return; } - real_faces = 0, real_face_type = 0; - for(int i=0; i 2) real_faces++, real_face_type += faces[i]; - real_face_type /= 2; - if(real_faces) { for(int i=1; i vals; + vals.push_back(iparse(0)); + while(true) { + skip_white(); + if(eat(",")) vals.push_back(iparse(0)); + else break; + } + force_eat(")"); + arcm::archimedean_tiling test; + test.faces = vals; + test.compute_sum(); + test.compute_geometry(); + res = test.edgelength; + if(extra_params.count("distunit")) + res /= extra_params["distunit"]; + } + else if(eat("regangle(")) { + ld edgelen = rparse(0); + if(extra_params.count("distunit")) { + println(hlog, "got edgelen = ", edgelen); + println(hlog, "distunit = ", real(extra_params["distunit"])); + edgelen = real(edgelen * extra_params["distunit"]); + println(hlog, "got edgelen = ", edgelen); + } + + force_eat(","); + int edges = iparse(0); + force_eat(")"); + ld alpha = M_PI / edges; + ld c = asin_auto(sin_auto(edgelen/2) / sin(alpha)); + hyperpoint h = xpush(c) * spin(M_PI - 2*alpha) * xpush0(c); + res = 2 * atan2(h); + if(real(res) < 0) res = -res; + while(real(res) > 2 * M_PI) res -= 2 * M_PI; + if(real(res) > M_PI) res = 2 * M_PI - res; + res = M_PI - res; + + if(extra_params.count("angleofs")) + res -= extra_params["angleofs"]; + + if(extra_params.count("angleunit")) + res /= extra_params["angleunit"]; + } + else if(eat("test(")) { + res = parsepar(); + println(hlog, "res = ", make_pair(real(res), imag(res))); } else if(eat("ifp(")) { cld cond = parse(0);