From 2a7e1f26031c62863bee5540ed3efc35a05c5734 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 10 Mar 2019 14:35:30 +0100 Subject: [PATCH] 3d:: horotris: correct distances --- binary-tiling.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++ goldberg.cpp | 8 ++++---- hyper.h | 1 + 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/binary-tiling.cpp b/binary-tiling.cpp index a9964ed2..796691af 100644 --- a/binary-tiling.cpp +++ b/binary-tiling.cpp @@ -445,7 +445,55 @@ bool pseudohept(cell *c) { return (c->master->zebraval == 1) && (c->master->distance & 1); } +pair gpvalue(heptagon *h) { + int d = h->c.spin(S7-1); + if(d == 0) return make_pair(gp::loc(0,0), gp::loc(-1,0)); + else return make_pair(gp::eudir((d-1)*2), gp::loc(1,0)); + } + +// distance in a triangular grid +int tridist(gp::loc v) { + using namespace gp; + int d = v.first - v.second; + int d0 = d % 3; + if(d0 == 1 || d0 == -2) return 1 + min(tridist(v - eudir(0)), min(tridist(v - eudir(2)), tridist(v - eudir(4)))); + if(d0 == 2 || d0 == -1) return 1 + min(tridist(v + eudir(0)), min(tridist(v + eudir(2)), tridist(v + eudir(4)))); + return length(v * loc(1,1)) * 2 / 3; + } + +int celldistance3_tri(heptagon *c1, heptagon *c2) { + using namespace gp; + int steps = 0; + int d1 = c1->distance; + int d2 = c2->distance; + while(d1 > d2) c1 = c1->cmove(S7-1), steps++, d1--; + while(d2 > d1) c2 = c2->cmove(S7-1), steps++, d2--; + vector > m1, m2; + while(c1 != c2) { + m2.push_back(gpvalue(c2)); + m1.push_back(gpvalue(c1)); + c1 = c1->cmove(S7-1); + c2 = c2->cmove(S7-1); + steps += 2; + } + loc T1(0,0), T2(0,0), inv1(1,0), inv2(1,0); + int xsteps = steps; + while(isize(m1)) { + xsteps -= 2; + inv1 = inv1 * m1.back().second; + inv2 = inv2 * m2.back().second; + T1 = T1 + T1 + m1.back().first * inv1; + T2 = T2 + T2 + m2.back().first * inv2; + m1.pop_back(); m2.pop_back(); + loc T0 = T2 - T1; + if(T0.first > 3 || T0.second > 3 || T0.first < -3 || T0.second < -3) break; + steps = min(steps, xsteps + tridist(T0)); + } + return steps; + } + int celldistance3(heptagon *c1, heptagon *c2) { + if(geometry == gHoroTris) return celldistance3_tri(c1, c2); int steps = 0; int d1 = c1->distance; int d2 = c2->distance; diff --git a/goldberg.cpp b/goldberg.cpp index d2687725..82f515a0 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -38,6 +38,10 @@ namespace hr { namespace gp { } } + int length(loc p) { + return eudist(p.first, p.second); + } + #if CAP_GP loc param(1, 0); @@ -45,10 +49,6 @@ namespace hr { namespace gp { ld alpha; int area; - int length(loc p) { - return eudist(p.first, p.second); - } - struct goldberg_mapping_t { cellwalker cw; signed char rdir; diff --git a/hyper.h b/hyper.h index 3241498d..a95707b9 100644 --- a/hyper.h +++ b/hyper.h @@ -3686,6 +3686,7 @@ namespace gp { loc operator-(loc e1, loc e2); loc operator*(loc e1, loc e2); extern loc eudir(int dir); + int length(loc p); #if CAP_GP void compute_geometry();