diff --git a/aperiodic-hat.cpp b/aperiodic-hat.cpp index d1415a9d..3b3b4b18 100644 --- a/aperiodic-hat.cpp +++ b/aperiodic-hat.cpp @@ -382,6 +382,8 @@ vector rules_recursive = { {6, 6, 31, 31, 14}, }; +EX ld hat_param = 1; + struct hrmap_hat : hrmap { // always generate the same way @@ -402,17 +404,18 @@ struct hrmap_hat : hrmap { void init() { transmatrix T = Id; - hatcorners[0].clear(); + auto& hc = hatcorners[0]; + hc.clear(); hatcorners[1].clear(); auto move = [&] (ld angle, ld dist) { - hatcorners[0].push_back(T * C0); + hc.push_back(T * C0); T = T * spin(angle * degree); T = T * xpush(dist); }; ld q = 6; - ld eshort = 0.5; + ld eshort = 0.3; ld elong = sqrt(3) * eshort; if(fake::in()) q = fake::around; @@ -420,6 +423,13 @@ struct hrmap_hat : hrmap { eshort = edge_of_triangle_with_angles(M_PI / q, 60._deg, 90._deg); elong = edge_of_triangle_with_angles(60._deg, M_PI / q, 90._deg); } + else { + eshort *= hat_param; + elong *= 2 - hat_param; + // 0-length edges cause problems... + if(eshort == 0) eshort = .0001; + if(elong == 0) elong = .0001; + } ld i60 = (M_PI - TAU*2/q)/degree; ld n60 = (M_PI - TAU*4/q)/degree; @@ -430,13 +440,22 @@ struct hrmap_hat : hrmap { move(i60, elong); move(-90, eshort); move( 60, eshort); move( 90, elong); move(i60, elong); - hyperpoint ctr = Hypc; - for(auto h: hatcorners[0]) ctr += h; - ctr /= isize(hatcorners[0]); - ctr = normalize(ctr); - for(auto& h: hatcorners[0]) h = gpushxto0(ctr) * h; + if(q == 6) { + ld area = 0; + for(int i=0; i<14; i++) area += (hc[(i+1)%14] ^ hc[i]) [2]; + println(hlog, "area = ", area); + area = abs(area); + ld scale = sqrt(2.5 / area); + for(auto& h: hc) h = h * scale + (C0) * (1-scale); + } - hatcorners[1] = hatcorners[0]; + hyperpoint ctr = Hypc; + for(auto h: hc) ctr += h; + ctr /= isize(hc); + ctr = normalize(ctr); + for(auto& h: hc) h = gpushxto0(ctr) * h; + + hatcorners[1] = hc; for(auto& h: hatcorners[1]) h = MirrorX * h; reverse(hatcorners[1].begin(), hatcorners[1].end()); } @@ -608,6 +627,7 @@ EX int get_hat_id(cell *c) { EX void reshape() { hrmap_hat *hatmap; hatmap = FPIU( hat_map() ); + if(!hatmap) return; hatmap->init(); } diff --git a/config.cpp b/config.cpp index 6463fe4d..3f03ee1c 100644 --- a/config.cpp +++ b/config.cpp @@ -822,7 +822,14 @@ EX void initConfig() { param_f(vid.binary_width, "bwidth", "binary-tiling-width", 1); param_custom(vid.binary_width, "binary tiling width", menuitem_binary_width, 'v'); - + + param_f(hat::hat_param, "hat_param", "hat_param", 1) + -> editable(0, 2, 1, "Hat parameter", + "Apeirodic hat tiling based on: https://arxiv.org/pdf/2303.10798.pdf\n\n" + "This controls the parameter discussed in Section 6.", 'v' + ) + -> set_reaction(hat::reshape); + addsaver(vid.particles, "extra effects", 1); param_i(vid.framelimit, "frame limit", 999); diff --git a/geom-exp.cpp b/geom-exp.cpp index c3de4a3e..1b565fc2 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -1022,6 +1022,9 @@ EX void showEuclideanMenu() { menuitem_binary_width('v'); add_edit_wall_quality('W'); } + else if(hat::in()) { + add_edit(hat::hat_param); + } else if(nil) { menuitem_nilwidth('v'); } diff --git a/geometry.cpp b/geometry.cpp index eade3c9d..5a85a23c 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -720,7 +720,6 @@ void geometry_information::prepare_basics() { #if CAP_BT if(bt::in()) hexvdist = rhexf = 1, tessf = 1, scalefactor = 1, crossf = hcrossf7; if(geometry == gHoroRec || kite::in() || sol || nil || nih) hexvdist = rhexf = .5, tessf = .5, scalefactor = .5, crossf = hcrossf7/2; - if(hat::in()) scalefactor *= 1.5, crossf *= 1.5, tessf *= 1.5, hexvdist *= 1.5, rhexf *= 1.5; if(bt::in()) scalefactor *= min(vid.binary_width, 1), crossf *= min(vid.binary_width, 1); #endif #if MAXMDIM >= 4 @@ -1262,6 +1261,7 @@ EX string cgi_string() { if(nil) V("NIL", its(S7)); if(bt::in()) V("BT", fts(vid.binary_width)); + if(hat::in()) V("H", fts(hat::hat_param)); if(nil) V("NILW", fts(nilv::nilwidth));