diff --git a/bigstuff.cpp b/bigstuff.cpp index f8134976..f8257ad5 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -956,10 +956,9 @@ bool mouse_reachability_test(cell *c) { } bool horo_ok() { - if(!hyperbolic) return false; - if(!gp::on) return true; - if(gp::param.second) return false; - return true; + // do the horocycles work in the current geometry? + // (they work in ALL hyperbolic geometries currently!) + return hyperbolic; } void buildBigStuff(cell *c, cell *from) { diff --git a/goldberg.cpp b/goldberg.cpp index c4badaee..c66bd439 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -354,7 +354,10 @@ namespace gp { } } + map, loc> center_locs; + void compute_geometry() { + center_locs.clear(); if(on) { int x = param.first; int y = param.second; @@ -495,13 +498,15 @@ namespace gp { }; } + loc univ_param() { + if(on) return param; + else if(nonbitrunc) return loc(1,0); + else return loc(1,1); + } + void configure(bool texture_remap = false) { - if(gp::on) - config_x = param.first, config_y = param.second; - else if(nonbitrunc) - config_x = 1, config_y = 0; - else - config_x = 1, config_y = 1; + auto l = univ_param(); + config_x = l.first, config_y = l.second; param = loc(config_x, config_y); pushScreen([texture_remap] () { gp::show(texture_remap); }); } @@ -530,9 +535,40 @@ namespace gp { } } + int length(loc p) { + return eudist(p.first, p.second); + } + + // from some point X, (0,0) is in distance dmain, param is in distance d0, and param*z is in distance d1 + // what is the distance of at from X? + + int solve_triangle(int dmain, int d0, int d1, loc at) { + loc centerloc(0, 0); + auto rel = make_pair(d0-dmain, d1-dmain); + if(center_locs.count(rel)) + centerloc = center_locs[rel]; + else { + bool found = false; + for(int y=-20; y<=20; y++) + for(int x=-20; x<=20; x++) { + loc c(x, y); + int cc = length(c); + int c0 = length(c - param); + int c1 = length(c - param*loc(0,1)); + if(c0-cc == d0-dmain && c1-cc == d1-dmain) + found = true, centerloc = c; + } + if(!found) + printf("Warning: centerloc not found: %d,%d,%d\n", dmain, d0, d1); + center_locs[rel] = centerloc; + } + + return dmain + length(centerloc-at) - length(centerloc); + } + int compute_dist(cell *c, int master_function(cell*)) { auto li = get_local_info(c); - be_in_triangle(li); + be_in_triangle2(li); cell *cm = c->master->c7; @@ -542,25 +578,21 @@ namespace gp { auto dmain = master_function(cm); auto d0 = master_function(createStep(cm->master, i)->c7); auto d1 = master_function(createStep(cm->master, fixdir(i+1, cm))->c7); - - int w = param.first; - while(true) { - if(dmain < d0 && dmain < d1) - return dmain + at.first + at.second; - if(dmain > d0 && dmain > d1) - return dmain - at.first - at.second; - if(dmain == d0 && dmain == d1) - return dmain; - // main ~ (0,0) - // d0 ~ (w,0) - // d1 ~ (0,w) - tie(dmain, d0, d1) = make_tuple(d0, d1, dmain); - // (0,0) -> (0,w) - // (w,0) -> (0,0) - // (0,w) -> (w,0) - at = loc(at.second, w - at.first - at.second); - } + return solve_triangle(dmain, d0, d1, at); } + + int dist_2() { + return length(univ_param()); + } + + int dist_3() { + return length(univ_param() * loc(1,1)); + } + + int dist_1() { + return dist_3() - dist_2(); + } + } diff --git a/heptagon.cpp b/heptagon.cpp index 3a2278c4..599db911 100644 --- a/heptagon.cpp +++ b/heptagon.cpp @@ -96,10 +96,7 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix if(pard == 0) { h->dm4 = parent->dm4+1; if(fixdistance != COMPUTE) h->distance = fixdistance; - else if(gp::on) h->distance = parent->distance + gp::param.first; - else if(nonbitrunc) h->distance = parent->distance + 1; - else if(parent->s == hsOrigin) h->distance = parent->distance + 2; - else if(S3 == 4) { + else if(S3 == 4 && !nonbitrunc) { h->distance = parent->distance + 2; if(h->spin(0) == 2 || (h->spin(0) == 3 && S7 <= 5)) h->distance = min(h->distance, createStep(h->move[0], 0)->distance + 3); @@ -122,14 +119,32 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix createStep(h, S7-1)->distance + 1 ); } - else if(h->spin(0) == S7-2) - h->distance = parent->distance + 1; - else if(h->spin(0) == S7-3 && h->move[0]->s == hsB) - h->distance = createStep(h->move[0], (h->spin(0)+2)%S7)->distance + 3; - else h->distance = parent->distance + 2; + else if(parent->s == hsOrigin) h->distance = parent->distance + gp::dist_2(); + else if(h->spin(0) == S7-2) { + if(!gp::on) + h->distance = parent->distance + gp::dist_1(); + else { + int d0 = parent->distance; + int d1 = createStep(parent, S7-1)->distance; + int dm = createStep(parent, 0)->distance; + h->distance = gp::solve_triangle(dm, d0, d1, gp::operator* (gp::param, gp::loc(1,1))); + } + } + else if(h->spin(0) == S7-3 && h->move[0]->s == hsB) { + if(!gp::on) { + h->distance = createStep(h->move[0], (h->spin(0)+2)%S7)->distance + gp::dist_3(); + } + else { + int d0 = parent->distance; + int d1 = createStep(parent, S7-2)->distance; + int dm = createStep(parent, S7-1)->distance; + h->distance = gp::solve_triangle(dm, d0, d1, gp::operator* (gp::param, gp::loc(1,1))); + } + } + else h->distance = parent->distance + gp::dist_2(); } else { - h->distance = parent->distance - (gp::on?gp::param.first:nonbitrunc?1:2); + h->distance = parent->distance - gp::dist_2(); if(S3 == 4 && S7 == 5) { if(h->s == hsOrigin) { printf("had to cheat!\n"); diff --git a/hyper.h b/hyper.h index a7ed21cf..2af41fea 100644 --- a/hyper.h +++ b/hyper.h @@ -3009,6 +3009,10 @@ namespace gp { void be_in_triangle2(local_info& li); int compute_dist(cell *c, int master_function(cell*)); + + int dist_1(), dist_2(), dist_3(); + + int solve_triangle(int dmain, int d0, int d1, loc at); } int get_sightrange(); @@ -3233,3 +3237,6 @@ bool ishex1(cell *c); namespace fieldpattern { int fieldval_uniq(cell *c); int fieldval_uniq_rand(cell *c, int d); } bool warptype(cell *c); bool horo_ok(); + +ld master_to_c7_angle(); + diff --git a/hypgraph.cpp b/hypgraph.cpp index d3222e76..c5a15339 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -452,8 +452,12 @@ bool confusingGeometry() { return elliptic || quotient == 1 || torus; } +ld master_to_c7_angle() { + return nonbitrunc ? M_PI + gp::alpha : 0; + } + transmatrix actualV(const heptspin& hs, const transmatrix& V) { - return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + (nonbitrunc ? M_PI:0) + gp::alpha) : V; + return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V; } transmatrix applyspin(const heptspin& hs, const transmatrix& V) { diff --git a/pattern2.cpp b/pattern2.cpp index 34e06222..3b95f6e3 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -1633,6 +1633,11 @@ namespace patterns { } } +bool is_master(cell *c) { + if(euclid) return pseudohept(c); + else return c->master->c7 == c; + } + namespace linepatterns { int lessalpha(int col, int m) {