mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 18:00:34 +00:00
synt:: replaced the combinatorial building process with floating-point-based one for hyperbolic geometry too
This commit is contained in:
parent
b186b9d1bb
commit
7bae01c168
@ -208,7 +208,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
|
|||||||
alt->s = firststate;
|
alt->s = firststate;
|
||||||
alt->emeraldval = 0;
|
alt->emeraldval = 0;
|
||||||
alt->zebraval = 0;
|
alt->zebraval = 0;
|
||||||
for(int i=0; i<MAX_EDGE; i++) alt->move(i) = NULL;
|
alt->c.clear();
|
||||||
alt->distance = 0;
|
alt->distance = 0;
|
||||||
alt->c7 = NULL;
|
alt->c7 = NULL;
|
||||||
alt->alt = alt;
|
alt->alt = alt;
|
||||||
|
3
cell.cpp
3
cell.cpp
@ -349,9 +349,6 @@ namespace torusconfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int decodeId(heptagon* h);
|
|
||||||
heptagon* encodeId(int id);
|
|
||||||
|
|
||||||
int euclid_getvec(int dx, int dy) {
|
int euclid_getvec(int dx, int dy) {
|
||||||
if(torus) return torusconfig::getvec(dx, dy);
|
if(torus) return torusconfig::getvec(dx, dy);
|
||||||
else return pair_to_vec(dx, dy);
|
else return pair_to_vec(dx, dy);
|
||||||
|
@ -52,12 +52,10 @@ void precalc() {
|
|||||||
int vertexdegree = S6/2;
|
int vertexdegree = S6/2;
|
||||||
ld fmin, fmax;
|
ld fmin, fmax;
|
||||||
|
|
||||||
if(syntetic) {
|
if(syntetic)
|
||||||
synt::prepare();
|
ginf[gSyntetic].cclass = gcHyperbolic;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(euclid) {
|
if(euclid) {
|
||||||
// dynamicval<eGeometry> g(geometry, gNormal);
|
// dynamicval<eGeometry> g(geometry, gNormal);
|
||||||
// precalc(); }
|
// precalc(); }
|
||||||
// for(int i=0; i<S84; i++) spinmatrix[i] = spin(i * M_PI / S42);
|
// for(int i=0; i<S84; i++) spinmatrix[i] = spin(i * M_PI / S42);
|
||||||
@ -175,6 +173,7 @@ void precalc() {
|
|||||||
|
|
||||||
gp::compute_geometry();
|
gp::compute_geometry();
|
||||||
irr::compute_geometry();
|
irr::compute_geometry();
|
||||||
|
if(syntetic) synt::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
transmatrix ddi(ld dir, ld dist) {
|
transmatrix ddi(ld dir, ld dist) {
|
||||||
|
@ -307,6 +307,41 @@ void virtualRebase(cell*& base, hyperpoint& h, bool tohex) {
|
|||||||
virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return h; });
|
virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return h; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// works only in geometries similar to the standard one, and only on heptagons
|
||||||
|
void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
|
||||||
|
double currz = at[2][2];
|
||||||
|
|
||||||
|
heptagon *h = base;
|
||||||
|
|
||||||
|
heptagon *newbase = NULL;
|
||||||
|
|
||||||
|
transmatrix bestV;
|
||||||
|
|
||||||
|
for(int d=0; d<S7; d++) {
|
||||||
|
heptspin hs(h, d, false);
|
||||||
|
heptspin hs2 = hs + wstep;
|
||||||
|
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * invheptmove[d] * at;
|
||||||
|
double newz = V2[2][2];
|
||||||
|
if(newz < currz) {
|
||||||
|
currz = newz;
|
||||||
|
bestV = V2;
|
||||||
|
newbase = hs2.at;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newbase) {
|
||||||
|
base = newbase;
|
||||||
|
at = bestV;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double cellgfxdist(cell *c, int i) {
|
double cellgfxdist(cell *c, int i) {
|
||||||
if(gp::on || irr::on) return hdist0(tC0(calc_relative_matrix(c->move(i), c, i)));
|
if(gp::on || irr::on) return hdist0(tC0(calc_relative_matrix(c->move(i), c, i)));
|
||||||
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
|
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
|
||||||
|
5
hyper.h
5
hyper.h
@ -3840,5 +3840,10 @@ namespace synt {
|
|||||||
hyperpoint get_warp_corner(cell *c, int cid);
|
hyperpoint get_warp_corner(cell *c, int cid);
|
||||||
hyperpoint get_corner_position(cell *c, int cid, ld cf = 3);
|
hyperpoint get_corner_position(cell *c, int cid, ld cf = 3);
|
||||||
|
|
||||||
|
int decodeId(heptagon* h);
|
||||||
|
heptagon* encodeId(int id);
|
||||||
|
|
||||||
|
void virtualRebaseSimple(heptagon*& base, transmatrix& at);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
454
syntetic.cpp
454
syntetic.cpp
@ -2,42 +2,13 @@ namespace hr {
|
|||||||
|
|
||||||
namespace synt {
|
namespace synt {
|
||||||
|
|
||||||
int indent;
|
#define SDEBUG(x) if(debug_geometry) { doindent(); x; fflush(stdout); }
|
||||||
|
|
||||||
struct indenter {
|
|
||||||
indenter() { indent += 2; }
|
|
||||||
~indenter() { indent -= 2; }
|
|
||||||
};
|
|
||||||
|
|
||||||
void doindent() { fflush(stdout); for(int i=0; i<indent; i++) printf(" "); }
|
|
||||||
|
|
||||||
bool do_sdebug = false;
|
|
||||||
|
|
||||||
#define SDEBUG(x) if(do_sdebug) { doindent(); x; fflush(stdout); }
|
|
||||||
|
|
||||||
// Marek-snub
|
// Marek-snub
|
||||||
vector<int> faces = {3, 6, 6, 6};
|
vector<int> faces = {3, 6, 6, 6};
|
||||||
vector<int> adj = {1, 0, 2, 3};
|
vector<int> adj = {1, 0, 2, 3};
|
||||||
vector<bool> invert = {false, false, true, false};
|
vector<bool> invert = {false, false, true, false};
|
||||||
|
|
||||||
/*
|
|
||||||
vector<int> faces = {3, 6, 6, 6};
|
|
||||||
vector<int> adj = {1, 0, 2, 3};
|
|
||||||
vector<bool> invert = {false, false, false, false};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
vector<int> faces = {7, 6, 6};
|
|
||||||
vector<int> adj = {1, 0, 2};
|
|
||||||
vector<bool> invert = {false, false, false};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
vector<int> faces = {8, 8, 8};
|
|
||||||
vector<int> adj = {0, 1, 2};
|
|
||||||
vector<bool> invert = {false, false, false};
|
|
||||||
*/
|
|
||||||
|
|
||||||
int repetition = 1;
|
int repetition = 1;
|
||||||
int N;
|
int N;
|
||||||
|
|
||||||
@ -50,14 +21,6 @@ vector<vector<pair<ld, ld>>> triangles;
|
|||||||
// 0, 2, ..., 2(N-1) = as in the symbol
|
// 0, 2, ..., 2(N-1) = as in the symbol
|
||||||
// 2N = bitruncated tile
|
// 2N = bitruncated tile
|
||||||
|
|
||||||
map<heptagon*, int> create_order;
|
|
||||||
|
|
||||||
map<heptagon*, transmatrix> syntetic_gmatrix;
|
|
||||||
|
|
||||||
int nextorder = 1;
|
|
||||||
|
|
||||||
static const int PRUNED = 100;
|
|
||||||
|
|
||||||
short& id_of(heptagon *h) {
|
short& id_of(heptagon *h) {
|
||||||
return h->zebraval;
|
return h->zebraval;
|
||||||
}
|
}
|
||||||
@ -74,27 +37,9 @@ int neighbors_of(heptagon *h) {
|
|||||||
return isize(triangles[id_of(h)]);
|
return isize(triangles[id_of(h)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// right_sibling_of(h) has the same distance ('right sibling'), then we have some at smaller or equal distance,
|
|
||||||
// parents_of(h) has the same distance again ('left sibling'), and then we have vertices at bigger distance,
|
|
||||||
// who are our 'children' except the rightmost one which is typically a child of the right sibling
|
|
||||||
|
|
||||||
short& right_sibling_of(heptagon *h) {
|
|
||||||
return h->fiftyval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int parents_of(heptagon *h) {
|
|
||||||
return h->s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int children_of(heptagon *h) {
|
|
||||||
return right_sibling_of(h) - 1 - parents_of(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
ld edgelength;
|
ld edgelength;
|
||||||
vector<ld> inradius, circumradius, alphas;
|
|
||||||
|
|
||||||
extern void draw_debug_map(heptagon *h);
|
vector<ld> inradius, circumradius, alphas;
|
||||||
void draw_debug_map_exit(heptagon *h) { draw_debug_map(h); exit(1); }
|
|
||||||
|
|
||||||
void prepare() {
|
void prepare() {
|
||||||
|
|
||||||
@ -248,6 +193,10 @@ void prepare() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map<heptagon*, vector<pair<heptagon*, transmatrix> > > altmap;
|
||||||
|
|
||||||
|
map<heptagon*, pair<heptagon*, transmatrix>> syntetic_gmatrix;
|
||||||
|
|
||||||
void initialize(heptagon *h) {
|
void initialize(heptagon *h) {
|
||||||
|
|
||||||
/* initialize the root */
|
/* initialize the root */
|
||||||
@ -256,336 +205,111 @@ void initialize(heptagon *h) {
|
|||||||
id_of(h) = 0;
|
id_of(h) = 0;
|
||||||
h->c7 = newCell(isize(adjacent[0]), h);
|
h->c7 = newCell(isize(adjacent[0]), h);
|
||||||
|
|
||||||
if(!hyperbolic) syntetic_gmatrix[h] = Id;
|
heptagon *alt = NULL;
|
||||||
|
|
||||||
if(sphere) celllister cl(h->c7, 1000, 1000000, NULL);
|
if(hyperbolic) {
|
||||||
|
dynamicval<eGeometry> g(geometry, gNormal);
|
||||||
|
alt = new heptagon;
|
||||||
|
alt->s = hsOrigin;
|
||||||
|
alt->emeraldval = 0;
|
||||||
|
alt->zebraval = 0;
|
||||||
|
alt->c.clear();
|
||||||
|
alt->distance = 0;
|
||||||
|
alt->c7 = NULL;
|
||||||
|
alt->alt = alt;
|
||||||
|
alt->cdata = NULL;
|
||||||
|
newAltMap(alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * Id;
|
||||||
|
syntetic_gmatrix[h] = make_pair(alt, T);
|
||||||
|
altmap[alt].emplace_back(h, T);
|
||||||
|
|
||||||
|
base_distlimit = 0;
|
||||||
|
celllister cl(h->c7, 1000, 200, NULL);
|
||||||
|
base_distlimit = cl.dists.back();
|
||||||
};
|
};
|
||||||
|
|
||||||
void verify_distance_delta(heptagon *h, int d, int delta) {
|
|
||||||
if(!h->move(d)) return;
|
|
||||||
if(h->move(d)->distance != h->distance + delta) {
|
|
||||||
SDEBUG( printf("ERROR: delta H%d.%d (%d/%d)\n", create_order[h], d, h->move(d)->distance, h->distance + delta); )
|
|
||||||
// exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void debug(heptagon *h) {
|
|
||||||
if(id_of(h) == PRUNED) return;
|
|
||||||
auto& p = adjacent[id_of(h)];
|
|
||||||
if(h->s == hsOrigin) {
|
|
||||||
for(int i=0; i<isize(p); i++) verify_distance_delta(h, i, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int first = h->s + 1;
|
|
||||||
verify_distance_delta(h, 0, -1);
|
|
||||||
verify_distance_delta(h, first-2, -1);
|
|
||||||
verify_distance_delta(h, first-1, 0);
|
|
||||||
verify_distance_delta(h, isize(p)-1, 0);
|
|
||||||
for(int d=first; d<isize(p)-1; d++) verify_distance_delta(h, d, 1);
|
|
||||||
for(int d=0; d<isize(p); d++) if(h->move(d)) {
|
|
||||||
auto& p = adjacent[id_of(h)];
|
|
||||||
auto uv = p[(parent_index_of(h) + d) % isize(p)];
|
|
||||||
if(neighbors_of(h->move(d)) != isize(adjacent[uv.first])) {
|
|
||||||
SDEBUG( printf("neighbors mismatch at H%d.%d->H%d: is %d expected %d\n", create_order[h], d, create_order[h->move(d)], neighbors_of(h->move(d)), isize(adjacent[uv.first])); )
|
|
||||||
draw_debug_map_exit(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transmatrix adjcell_matrix(heptagon *h, int d);
|
transmatrix adjcell_matrix(heptagon *h, int d);
|
||||||
|
|
||||||
heptagon *build_child(heptagon *parent, int d, int id, int pindex) {
|
heptagon *build_child(heptagon *parent, int d, int id, int pindex) {
|
||||||
indenter ind;
|
indenter ind;
|
||||||
auto h = buildHeptagon1(new heptagon, parent, d, hstate(1), 0);
|
auto h = buildHeptagon1(new heptagon, parent, d, hstate(1), 0);
|
||||||
create_order[h] = nextorder++;
|
SDEBUG( printf("NEW %p.%d ~ %p.0\n", parent, d, h); )
|
||||||
id_of(h) = id;
|
id_of(h) = id;
|
||||||
parent_index_of(h) = pindex;
|
parent_index_of(h) = pindex;
|
||||||
int nei = neighbors_of(h);
|
int nei = neighbors_of(h);
|
||||||
right_sibling_of(h) = nei - 1;
|
|
||||||
h->distance = parent->distance + 1;
|
|
||||||
h->c7 = newCell(nei, h);
|
h->c7 = newCell(nei, h);
|
||||||
SDEBUG( printf("H%d.%d/%d ~ H%d.0/%d (state=1/NEW,id=%d,pindex=%d,distance=%d)\n", create_order[parent], d, neighbors_of(parent), create_order[h], neighbors_of(h), id, pindex, h->distance); )
|
h->distance = parent->distance + 1;
|
||||||
if(!hyperbolic) syntetic_gmatrix[h] = syntetic_gmatrix[parent] * adjcell_matrix(parent, d);
|
|
||||||
else { debug(h); debug(parent); }
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connectHeptagons(heptagon *h, int i, heptspin hs) {
|
void connectHeptagons(heptagon *h, int i, heptspin hs) {
|
||||||
if(id_of(h) == PRUNED) { h->move(i) = h; return; }
|
SDEBUG( printf("OLD %p.%d ~ %p.%d\n", h, i, hs.at, hs.spin); )
|
||||||
if(id_of(hs.at) == PRUNED) { hs.at->move(i) = hs.at; return; }
|
|
||||||
indenter ind;
|
|
||||||
SDEBUG( printf("H%d.%d/%d ~ H%d.%d/%d (state=%d,id=%d,pindex=%d,distance=%d)\n", create_order[h], i, neighbors_of(h), create_order[hs.at], hs.spin, neighbors_of(hs.at),
|
|
||||||
hs.at->s, id_of(hs.at), parent_index_of(hs.at), hs.at->distance); )
|
|
||||||
if(h->move(i) == hs.at && h->c.spin(i) == hs.spin) {
|
if(h->move(i) == hs.at && h->c.spin(i) == hs.spin) {
|
||||||
SDEBUG( printf("WARNING: already connected\n"); )
|
SDEBUG( printf("WARNING: already connected\n"); )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(h->move(i)) {
|
if(h->move(i)) {
|
||||||
SDEBUG( printf("ERROR: already connected left to: H%d not H%d\n", create_order[h->move(i)], create_order[hs.at]); )
|
SDEBUG( printf("ERROR: already connected left\n"); )
|
||||||
draw_debug_map_exit(h);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(hs.peek()) {
|
if(hs.peek()) {
|
||||||
SDEBUG( printf("ERROR: already connected right to: H%d not H%d\n", create_order[hs.peek()], create_order[h]); )
|
SDEBUG( printf("ERROR: already connected right\n"); )
|
||||||
draw_debug_map_exit(h);
|
exit(1);
|
||||||
// exit(1);
|
|
||||||
}
|
}
|
||||||
h->c.connect(i, hs);
|
h->c.connect(i, hs);
|
||||||
if(hyperbolic) {
|
|
||||||
debug(h);
|
|
||||||
debug(hs.at);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int prune(heptagon*& h) {
|
|
||||||
if(!h) return 0;
|
|
||||||
int result = 1;
|
|
||||||
int n = neighbors_of(h);
|
|
||||||
auto h0 = h;
|
|
||||||
SDEBUG( printf("pruning: H%d\n", create_order[h0]); )
|
|
||||||
for(int i=0; i<n; i++)
|
|
||||||
if(h0->move(i)) {
|
|
||||||
if(h0->c.spin(i) == 0)
|
|
||||||
result += prune(h0->move(i));
|
|
||||||
else {
|
|
||||||
h0->move(i)->move(h0->c.spin(i)) = NULL;
|
|
||||||
h0->move(i) = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
id_of(h0) = PRUNED;
|
|
||||||
/*
|
|
||||||
delete h0->c7;
|
|
||||||
delete h0;
|
|
||||||
*/
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mayprune(heptagon *hleft, heptagon *hright) {
|
|
||||||
if(children_of(hleft) >= 1 && children_of(hright) >= 1)
|
|
||||||
if(hleft->move(right_sibling_of(hleft) - 1) != hright->move(parents_of(hright)+1)) {
|
|
||||||
SDEBUG( printf("pruning extra children after contraction\n"); )
|
|
||||||
prune(hleft->move(right_sibling_of(hleft) - 1));
|
|
||||||
prune(hright->move(parents_of(hright)+1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void contract(heptagon *h) {
|
|
||||||
if(id_of(h) == PRUNED) return;
|
|
||||||
switch(children_of(h)) {
|
|
||||||
case 0: {
|
|
||||||
SDEBUG( printf("handling contraction (0) at H%d\n", create_order[h]); )
|
|
||||||
heptspin right = heptspin(h, right_sibling_of(h)) + wstep + 1;
|
|
||||||
heptspin left = heptspin(h, parents_of(h)) + wstep - 1;
|
|
||||||
connectHeptagons(right.at, right.spin, left);
|
|
||||||
right.at->s++;
|
|
||||||
right_sibling_of(left.at)--;
|
|
||||||
mayprune(left.at, right.at);
|
|
||||||
contract(right.at);
|
|
||||||
contract(left.at);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case -1: {
|
|
||||||
SDEBUG( printf("handling contraction (-1) at H%d\n", create_order[h]); )
|
|
||||||
indenter ind2;
|
|
||||||
heptspin hs0(h, neighbors_of(h)-1);
|
|
||||||
heptspin hs = hs0;
|
|
||||||
hs = hs + 1 + wstep + 1;
|
|
||||||
while(hs.spin == neighbors_of(hs.at) - 1) {
|
|
||||||
SDEBUG( printf("hsr at H%d.%d/%d (%d parents)\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); )
|
|
||||||
hs = hs + wstep + 1;
|
|
||||||
}
|
|
||||||
SDEBUG( printf("hsr at H%d.%d/%d (%d parents)\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); )
|
|
||||||
heptspin correct = hs + wstep;
|
|
||||||
SDEBUG( printf("correct is: H%d.%d/%d (%d parents)\n", create_order[correct.at], correct.spin, neighbors_of(correct.at), parents_of(correct.at)); )
|
|
||||||
heptspin hsl = hs0;
|
|
||||||
correct = correct+1; correct.at->s++;
|
|
||||||
connectHeptagons(hsl.at, hsl.spin, correct);
|
|
||||||
hsl = hsl - 1 + wstep - 1;
|
|
||||||
while(true) {
|
|
||||||
SDEBUG( printf("hsl at %d.%d/%d (%d parents)\n", create_order[hsl.at], hsl.spin, neighbors_of(hsl.at), parents_of(hsl.at)); )
|
|
||||||
if(hsl.spin == parents_of(hsl.at)) {
|
|
||||||
SDEBUG(printf("go left\n"))
|
|
||||||
hsl = hsl + wstep - 1;
|
|
||||||
}
|
|
||||||
else if(hsl.peek() && hsl.peek() != correct.at) {
|
|
||||||
SDEBUG(printf("prune\n");)
|
|
||||||
if(neighbors_of(hsl.peek()) != neighbors_of(correct.at)) {
|
|
||||||
SDEBUG(printf("neighbors mismatch while pruning %d -> %d\n",
|
|
||||||
neighbors_of(hsl.peek()),
|
|
||||||
neighbors_of(correct.at)
|
|
||||||
);)
|
|
||||||
draw_debug_map_exit(correct.at);
|
|
||||||
}
|
|
||||||
prune(hsl.peek());
|
|
||||||
}
|
|
||||||
else if(hsl.peek() == NULL) {
|
|
||||||
correct = correct+1; correct.at->s++;
|
|
||||||
SDEBUG( printf("connect\n") )
|
|
||||||
connectHeptagons(hsl.at, hsl.spin, correct);
|
|
||||||
}
|
|
||||||
else if(hsl.spin == parents_of(hsl.at)+1) {
|
|
||||||
SDEBUG( printf("single child so go left\n") )
|
|
||||||
hsl = hsl - 1 + wstep - 1;
|
|
||||||
}
|
|
||||||
else { SDEBUG( printf("ready\n"); ) break; }
|
|
||||||
}
|
|
||||||
contract(correct.at);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case -2: {
|
|
||||||
SDEBUG( printf("ERROR: contraction (-2) not handled\n"); )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!sphere) for(int i=0; i<neighbors_of(h); i++) if(!h->move(i)) {
|
|
||||||
auto uv = adjacent[id_of(h)][(parent_index_of(h) + i) % neighbors_of(h)];
|
|
||||||
if(isize(adjacent[uv.first]) < 5 && hyperbolic) {
|
|
||||||
SDEBUG( printf("prebuilding weak neighbor\n") )
|
|
||||||
createStep(h, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void build_siblings(heptagon *h, int x) {
|
|
||||||
for(int i=right_sibling_of(h); i<neighbors_of(h); i++) createStep(h, i);
|
|
||||||
for(int i=0; i<=parents_of(h); i++) createStep(h, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<int, int>& get_adj(heptagon *h, int cid);
|
pair<int, int>& get_adj(heptagon *h, int cid);
|
||||||
pair<ld, ld>& get_triangle(heptagon *h, int cid);
|
pair<ld, ld>& get_triangle(heptagon *h, int cid);
|
||||||
|
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0);
|
||||||
|
|
||||||
void create_adjacent(heptagon *h, int d) {
|
void create_adjacent(heptagon *h, int d) {
|
||||||
|
|
||||||
if(!hyperbolic) {
|
SDEBUG( printf("%p.%d ~ ?\n", h, d); )
|
||||||
|
|
||||||
SDEBUG( printf("h=%d dist=%d d=%d/%d s=%d id=%d pindex=%d\n",
|
auto& t1 = get_triangle(h, d);
|
||||||
create_order[h], h->distance, d, neighbors_of(h), h->s, id_of(h), parent_index_of(h)); )
|
|
||||||
indenter ind2;
|
|
||||||
|
|
||||||
auto& t1 = get_triangle(h, d);
|
// * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first)
|
||||||
|
|
||||||
// * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first)
|
auto& p = syntetic_gmatrix[h];
|
||||||
|
|
||||||
transmatrix T = syntetic_gmatrix[h] * spin(-t1.first) * xpush(t1.second);
|
heptagon *alt = p.first;
|
||||||
|
|
||||||
for(auto gm: syntetic_gmatrix) if(intval(gm.second * C0, T * C0) < 1e-6) {
|
transmatrix T = p.second * spin(-t1.first) * xpush(t1.second);
|
||||||
SDEBUG( printf("cell found\n"); )
|
|
||||||
for(int d2=0; d2<gm.first->c7->type; d2++) {
|
|
||||||
auto& t2 = get_triangle(gm.first, d2);
|
|
||||||
transmatrix T1 = T * spin(M_PI + t2.first);
|
|
||||||
if(intval(T1 * xpush(1) * C0, gm.second * xpush(1) * C0) < 1e-6) {
|
|
||||||
connectHeptagons(h, d, heptspin(gm.first, d2));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDEBUG( printf("but rotation not found\n"));
|
|
||||||
}
|
|
||||||
build_child(h, d, get_adj(h, d).first, get_adj(h, d).second);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id_of(h) == PRUNED) { h->move(d) = h; return; }
|
|
||||||
if(indent >= 200) draw_debug_map_exit(h);
|
|
||||||
indenter ind;
|
|
||||||
int nei = neighbors_of(h);
|
|
||||||
|
|
||||||
if(h->s == 0) {
|
if(hyperbolic) {
|
||||||
auto& p = adjacent[id_of(h)];
|
dynamicval<eGeometry> g(geometry, gNormal);
|
||||||
for(int i=0; i<nei; i++)
|
virtualRebaseSimple(alt, T);
|
||||||
build_child(h, i, p[i].first, p[i].second);
|
|
||||||
for(int i=0; i<nei; i++) {
|
|
||||||
heptagon *h1 = h->move(i);
|
|
||||||
heptagon *h2 = h->move((i+nei-1)%nei);
|
|
||||||
connectHeptagons(h1, 1, heptspin(h2, isize(adjacent[id_of(h2)])-1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
if(euclid)
|
||||||
int first = h->s + 1;
|
alt = encodeId(pair_to_vec(int(T[0][2]), int(T[1][2])));
|
||||||
SDEBUG( printf("h=%d dist=%d d=%d/%d s=%d id=%d pindex=%d\n",
|
|
||||||
create_order[h], h->distance, d, nei, h->s, id_of(h), parent_index_of(h)); )
|
SDEBUG( printf("look for: %p / %s\n", alt, display(T * C0)); )
|
||||||
indenter ind2;
|
|
||||||
|
for(auto& p: altmap[alt]) if(intval(p.second * C0, T * C0) < 1e-6) {
|
||||||
// these vertices are not children (or possibly contractions)
|
SDEBUG( printf("cell found: %p\n", p.first); )
|
||||||
if(d < first || d > right_sibling_of(h))
|
for(int d2=0; d2<p.first->c7->type; d2++) {
|
||||||
connectHeptagons(h, d, heptspin(h, d-1) + wstep - 1 + wstep - 1);
|
auto& t2 = get_triangle(p.first, d2);
|
||||||
else if(d == right_sibling_of(h)) {
|
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||||
connectHeptagons(h, d, heptspin(h, 0) + wstep + 1 + wstep + 1);
|
SDEBUG( printf("compare: %s", display(T1 * xpush(1) * C0)); )
|
||||||
}
|
SDEBUG( printf(":: %s\n", display(p.second * xpush(1) * C0)); )
|
||||||
else {
|
if(intval(T1 * xpush(1) * C0, p.second * xpush(1) * C0) < 1e-6) {
|
||||||
build_siblings(h, 10);
|
connectHeptagons(h, d, heptspin(p.first, d2));
|
||||||
build_siblings(h, -10);
|
|
||||||
if(h->move(d)) return;
|
|
||||||
heptspin hs(h, d);
|
|
||||||
// make sure no contractions on the left
|
|
||||||
heptspin hsl(h, d);
|
|
||||||
int steps = 0;
|
|
||||||
while(hsl.spin == parents_of(hsl.at) + 1 && steps < 100) {
|
|
||||||
hsl = hsl - 1 + wstep - 1;
|
|
||||||
steps++;
|
|
||||||
}
|
|
||||||
if(steps == 100) {
|
|
||||||
SDEBUG( printf("generating top\n"); )
|
|
||||||
auto uv = adjacent[id_of(hs.at)][(parent_index_of(hs.at) + hs.spin) % neighbors_of(hs.at)];
|
|
||||||
heptagon *newchild = build_child(hs.at, hs.spin, uv.first, uv.second);
|
|
||||||
hs = hs - 1 + wstep - 1;
|
|
||||||
while(hs.at != h) {
|
|
||||||
newchild->s++;
|
|
||||||
connectHeptagons(hs.at, hs.spin, heptspin(newchild, newchild->s-1));
|
|
||||||
hs = hs - 1 + wstep - 1;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// while trying to generate the last child, go right
|
|
||||||
while(true) {
|
|
||||||
if(h->move(d)) {
|
|
||||||
SDEBUG( printf("solved itself\n"); )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SDEBUG( printf("going right at H%d.%d/%d parents = %d\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); )
|
|
||||||
if(id_of(hs.at) == PRUNED) { create_adjacent(h, d); return; }
|
|
||||||
// rightmost child
|
|
||||||
if(hs.spin == right_sibling_of(hs.at) - 1)
|
|
||||||
hs = hs + 1 + wstep + 1;
|
|
||||||
else if(children_of(hs.at) <= 0) {
|
|
||||||
SDEBUG( printf("unexpected situation\n"); )
|
|
||||||
create_adjacent(h, d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
auto uv = adjacent[id_of(hs.at)][(parent_index_of(hs.at) + hs.spin) % neighbors_of(hs.at)];
|
|
||||||
heptagon *newchild = build_child(hs.at, hs.spin, uv.first, uv.second);
|
|
||||||
bool add_parent = false;
|
|
||||||
while(true) {
|
|
||||||
if(id_of(hs.at) == PRUNED) { create_adjacent(h, d); return; }
|
|
||||||
SDEBUG( printf("going left at H%d.%d/%d parents = %d\n", create_order[hs.at], hs.spin, neighbors_of(hs.at), parents_of(hs.at)); )
|
|
||||||
// add parent
|
|
||||||
if(hs.spin > parents_of(hs.at) && add_parent) {
|
|
||||||
SDEBUG( printf("add parent\n"); )
|
|
||||||
newchild->s++;
|
|
||||||
connectHeptagons(hs.at, hs.spin, heptspin(newchild, newchild->s-1));
|
|
||||||
add_parent = false;
|
|
||||||
}
|
|
||||||
// childless
|
|
||||||
if(children_of(hs.at) <= 0) {
|
|
||||||
SDEBUG( printf("unexpected situation v2\n"); )
|
|
||||||
create_adjacent(h, d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// lefmost child
|
|
||||||
else if(hs.spin == parents_of(hs.at)+1) {
|
|
||||||
SDEBUG( printf("(leftmost child)\n"); )
|
|
||||||
hs = hs - 1 + wstep - 1;
|
|
||||||
add_parent = true;
|
|
||||||
}
|
|
||||||
// no more parents
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
contract(newchild);
|
|
||||||
}
|
}
|
||||||
|
SDEBUG( printf("but rotation not found\n"));
|
||||||
}
|
}
|
||||||
debug(h);
|
|
||||||
|
auto& t2 = get_triangle(get_adj(h, d));
|
||||||
|
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||||
|
|
||||||
|
heptagon *hnew = build_child(h, d, get_adj(h, d).first, get_adj(h, d).second);
|
||||||
|
altmap[alt].emplace_back(hnew, T1);
|
||||||
|
syntetic_gmatrix[hnew] = make_pair(alt, T1);
|
||||||
}
|
}
|
||||||
|
|
||||||
set<heptagon*> visited;
|
set<heptagon*> visited;
|
||||||
@ -613,6 +337,10 @@ pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0) {
|
|||||||
return adjacent[p.first][(p.second + delta) % isize(adjacent[p.first])];
|
return adjacent[p.first][(p.second + delta) % isize(adjacent[p.first])];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta) {
|
||||||
|
return triangles[p.first][(p.second + delta) % isize(adjacent[p.first])];
|
||||||
|
}
|
||||||
|
|
||||||
transmatrix adjcell_matrix(heptagon *h, int d) {
|
transmatrix adjcell_matrix(heptagon *h, int d) {
|
||||||
auto& t1 = get_triangle(h, d);
|
auto& t1 = get_triangle(h, d);
|
||||||
|
|
||||||
@ -621,8 +349,6 @@ transmatrix adjcell_matrix(heptagon *h, int d) {
|
|||||||
int d2 = h->c.spin(d);
|
int d2 = h->c.spin(d);
|
||||||
auto& t2 = get_triangle(h2, d2);
|
auto& t2 = get_triangle(h2, d2);
|
||||||
|
|
||||||
// * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first)
|
|
||||||
|
|
||||||
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first);
|
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,53 +452,17 @@ int readArgs() {
|
|||||||
showstartmenu = false;
|
showstartmenu = false;
|
||||||
shift(); parse_symbol(args());
|
shift(); parse_symbol(args());
|
||||||
}
|
}
|
||||||
else if(argis("-sd")) do_sdebug = true;
|
else if(argis("-dgeom")) debug_geometry = true;
|
||||||
else if(argis("-sdeb")) { PHASE(3); draw_debug_map(cwt.at->master); }
|
|
||||||
else return 1;
|
else return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
map<heptagon*, transmatrix> debugmap;
|
|
||||||
|
|
||||||
void add_to_debug(heptagon *h, transmatrix T) {
|
|
||||||
debugmap[h] = T;
|
|
||||||
for(int i=0; i<neighbors_of(h); i++)
|
|
||||||
if(h->move(i) && h->c.spin(i) == 0 && h->move(i)->s != hsOrigin)
|
|
||||||
add_to_debug(h->move(i), T * adjcell_matrix(h, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_debug_map(heptagon *h) {
|
|
||||||
debugmap.clear();
|
|
||||||
while(h->s != hsOrigin) h = h->move(0);
|
|
||||||
add_to_debug(h, Id);
|
|
||||||
svg::render("syntetic-debug.svg", [] () {
|
|
||||||
ptds.clear();
|
|
||||||
for(auto p: debugmap) {
|
|
||||||
heptagon *h = p.first;
|
|
||||||
queuestr(p.second*C0, vid.yres/50, its(create_order[h]) + "/" + its(h->c7->mpdist), 0xFF000000);
|
|
||||||
for(int i=0; i<neighbors_of(h); i++) {
|
|
||||||
if(h->move(i))
|
|
||||||
queueline(p.second*C0, debugmap[h->move(i)]*C0,
|
|
||||||
i == parents_of(h) ? 0xFF0000FF :
|
|
||||||
i == right_sibling_of(h) ? 0x800000FF :
|
|
||||||
i == 0 ? 0x008000FF :
|
|
||||||
0x000000FF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hr::drawqueue();
|
|
||||||
});
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CAP_COMMANDLINE
|
#if CAP_COMMANDLINE
|
||||||
auto hook =
|
auto hook =
|
||||||
addHook(hooks_args, 100, readArgs);
|
addHook(hooks_args, 100, readArgs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
11
util.cpp
11
util.cpp
@ -133,4 +133,15 @@ bool appears(const string& haystack, const string& needle) {
|
|||||||
return haystack.find(needle) != string::npos;
|
return haystack.find(needle) != string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* indenter */
|
||||||
|
|
||||||
|
int current_indentation;
|
||||||
|
|
||||||
|
struct indenter {
|
||||||
|
indenter() { current_indentation += 2; }
|
||||||
|
~indenter() { current_indentation -= 2; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void doindent() { for(int i=0; i<current_indentation; i++) printf(" "); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user