diff --git a/cell.cpp b/cell.cpp index ceb80519..3055d9a6 100644 --- a/cell.cpp +++ b/cell.cpp @@ -1783,6 +1783,49 @@ int celldistance(cell *c1, cell *c2) { return hyperbolic_celldistance(c1, c2); } +vector build_shortest_path(cell *c1, cell *c2) { + if(geometry == gCrystal) return crystal::build_shortest_path(c1, c2); + vector p; + if(euclid) { + using namespace hyperpoint_vec; + p.push_back(c1); + hyperpoint h = tC0(calc_relative_matrix(c2, c1, C0)) - C0; + cell *x = c1; + hyperpoint h1 = C0; + int d = celldistance(c1, c2); + for(int i=0; i<=d * 10; i++) { + h1 += h / d / 10.; + virtualRebase(x, h1, true); + if(x != p.back()) p.push_back(x); + } + if(isize(p) != d + 1) + println(hlog, "warning: path size ", isize(p), " should be ", d+1); + } + else if(c2 == currentmap->gamestart()) { + while(c1 != c2) { + p.push_back(c1); + forCellCM(c, c1) if(celldist(c) < celldist(c1)) { c1 = c; goto next1; } + println(hlog, "could not build_shortest_path"); exit(1); + next1: ; + } + p.push_back(c1); + } + else if(c1 == currentmap->gamestart()) { + p = build_shortest_path(c2, c1); + reverse(p.begin(), p.end()); + } + else { + while(c1 != c2) { + p.push_back(c1); + forCellCM(c, c1) if(celldistance(c, c2) < celldistance(c1, c2)) { c1 = c; goto next; } + println(hlog, "could not build_shortest_path"); exit(1); + next: ; + } + p.push_back(c1); + } + return p; + } + void clearCellMemory() { for(int i=0; i build_shortest_path(cell *c1, cell *c2) { + auto m = crystal_map(); + ldcoord co1 = m->get_coord(c1); + ldcoord co2 = m->get_coord(c2) - co1; + + // draw a cylinder from co1 to co2, and find the solution by going through that cylinder + + ldcoord mul = co2 / sqrt(co2|co2); + + ld mmax = (co2|mul); + + vector p; + vector parent_id; + + manual_celllister cl; + cl.add(c2); + parent_id.push_back(-1); + + int steps = 0; + int nextsteps = 1; + + for(int i=0; iget_coord(c3) - co1; + ld dot = (h|mul); + if(dot > mmax + PERIOD/2 + .1) continue; + + for(int k=0; kcs.dim; k++) if(abs(h[k] - dot * mul[k]) > PERIOD + .1) goto next3; + cl.add(c3); + parent_id.push_back(i); + next3: ; + } + } + + println(hlog, "Error: path not found"); + return p; + } + int precise_distance(cell *c1, cell *c2) { if(c1 == c2) return 0; auto m = crystal_map(); diff --git a/hyper.h b/hyper.h index f1f35c4f..50055c11 100644 --- a/hyper.h +++ b/hyper.h @@ -4166,6 +4166,7 @@ namespace crystal { string compass_help(); void may_place_compass(cell *c); void centerrug(ld aspd); + vector build_shortest_path(cell *c1, cell *c2); } hyperpoint get_warp_corner(cell *c, int cid);