From 378d21b509b31bd7c5a4a38587e8dba10310f870 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 17 Mar 2019 04:08:17 +0100 Subject: [PATCH] findbaseAround for all binary tilings --- binary-tiling.cpp | 10 ++++++++++ shmup.cpp | 37 ++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/binary-tiling.cpp b/binary-tiling.cpp index c80b050d..d4dc1b16 100644 --- a/binary-tiling.cpp +++ b/binary-tiling.cpp @@ -525,6 +525,16 @@ namespace binary { ld co = vid.binary_width / log(2) / 4; return hr::parabolic13(y * co, z * co); } + + // on which horocycle are we + ld horo_level(hyperpoint h) { + using namespace hyperpoint_vec; + h /= (1 + h[DIM]); + h[0] -= 1; + h /= sqhypot_d(DIM, h); + h[0] += .5; + return log(2) + log(-h[0]); + } hyperpoint deparabolic3(hyperpoint h) { using namespace hyperpoint_vec; diff --git a/shmup.cpp b/shmup.cpp index 5cd5562c..668c1b1e 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -1035,26 +1035,33 @@ typedef multimap::iterator mit; vector active, nonvirtual, additional; -cell *findbaseAround(hyperpoint p, cell *around) { - #if MAXMDIM == 4 && CAP_BT - // this needs a more precise algorithm because the cells have curved faces - if(DIM == 3 && binarytiling) { - hyperpoint h = binary::deparabolic3(inverse(ggmatrix(around)) * p); - if(h[0] < -log(2)/2) return around->cmove((h[1] > 0 ? 1 : 0) + (h[2] > 0 ? 2 : 0)); - if(h[1] < -1) return around->cmove(4); - if(h[1] > +1) return around->cmove(5); - if(h[2] < -1) return around->cmove(6); - if(h[2] > +1) return around->cmove(7); - if(h[0] > +log(2)/2) return around->cmove(8); - return around; +struct horo_distance { + ld a, b; + horo_distance(hyperpoint h1, cell *c) { + if(binarytiling) { + hyperpoint ih1 = inverse(ggmatrix(c)) * h1; + b = intval(ih1, C0); + a = abs(binary::horo_level(ih1)); + } + else + b = intval(h1, tC0(ggmatrix(c))); } - #endif + bool operator < (const horo_distance z) { + if(binarytiling) { + if(a < z.a-1e-6) return true; + if(a > z.a+1e-6) return false; + } + return b < z.b; + } + }; + +cell *findbaseAround(hyperpoint p, cell *around) { cell *best = around; - double d0 = intval(p, ggmatrix(around) * C0); + horo_distance d0(p, around); for(int i=0; itype; i++) { cell *c2 = around->move(i); if(c2) { - double d1 = intval(p, ggmatrix(c2) * C0); + horo_distance d1(p, c2); if(d1 < d0) { best = c2; d0 = d1; } } }