mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 09:00:34 +00:00
improved in the OO fashion: draw, relative_matrix, create_step, and several minor functions are now virtual in hrmap
This commit is contained in:
parent
d8428f2ec3
commit
78d88b5909
265
archimedean.cpp
265
archimedean.cpp
@ -357,11 +357,18 @@ hrmap *current_altmap;
|
|||||||
|
|
||||||
heptagon *build_child(heptspin p, pair<int, int> adj);
|
heptagon *build_child(heptspin p, pair<int, int> adj);
|
||||||
|
|
||||||
|
bool skip_digons(heptspin hs, int step);
|
||||||
|
void connect_digons_too(heptspin h1, heptspin h2);
|
||||||
|
void fixup_matrix(transmatrix& T, const transmatrix& X, ld step);
|
||||||
|
void connectHeptagons(heptspin hi, heptspin hs);
|
||||||
|
transmatrix adjcell_matrix(heptagon *h, int d);
|
||||||
|
|
||||||
struct hrmap_archimedean : hrmap {
|
struct hrmap_archimedean : hrmap {
|
||||||
heptagon *origin;
|
heptagon *origin;
|
||||||
heptagon *getOrigin() { return origin; }
|
heptagon *getOrigin() { return origin; }
|
||||||
|
|
||||||
hrmap_archimedean() {
|
hrmap_archimedean() {
|
||||||
|
dynamicval<hrmap*> curmap(currentmap, this);
|
||||||
int id = DUAL ? current.N * 2 : 0;;
|
int id = DUAL ? current.N * 2 : 0;;
|
||||||
int N0 = isize(current.adjacent[id]);
|
int N0 = isize(current.adjacent[id]);
|
||||||
origin = tailored_alloc<heptagon> (N0);
|
origin = tailored_alloc<heptagon> (N0);
|
||||||
@ -405,9 +412,9 @@ struct hrmap_archimedean : hrmap {
|
|||||||
origin->c.connect(s, hnew, s, false);
|
origin->c.connect(s, hnew, s, false);
|
||||||
}
|
}
|
||||||
else if(current.real_faces == 0) {
|
else if(current.real_faces == 0) {
|
||||||
create_adjacent(origin, 0);
|
may_create_step(origin, 0);
|
||||||
heptagon *o0 = origin->move(0);
|
heptagon *o0 = origin->move(0);
|
||||||
create_adjacent(origin, 1);
|
may_create_step(origin, 1);
|
||||||
heptagon *o1 = origin->move(1);
|
heptagon *o1 = origin->move(1);
|
||||||
for(int s=1; s<2*current.N; s+=2)
|
for(int s=1; s<2*current.N; s+=2)
|
||||||
o0->c.connect(s, o1, 2*current.N-s, false);
|
o0->c.connect(s, o1, 2*current.N-s, false);
|
||||||
@ -420,8 +427,8 @@ struct hrmap_archimedean : hrmap {
|
|||||||
o1->c.connect(1, o0, 2*current.N-1, false);
|
o1->c.connect(1, o0, 2*current.N-1, false);
|
||||||
}
|
}
|
||||||
else if(origin->degree() == 2) {
|
else if(origin->degree() == 2) {
|
||||||
create_adjacent(origin, 0);
|
may_create_step(origin, 0);
|
||||||
create_adjacent(origin, 1);
|
may_create_step(origin, 1);
|
||||||
origin->move(0)->c.connect(1, origin->move(1), 2*current.N-1, false);
|
origin->move(0)->c.connect(1, origin->move(1), 2*current.N-1, false);
|
||||||
origin->move(1)->c.connect(1, origin->move(0), 2*current.N-1, false);
|
origin->move(1)->c.connect(1, origin->move(0), 2*current.N-1, false);
|
||||||
}
|
}
|
||||||
@ -443,12 +450,136 @@ struct hrmap_archimedean : hrmap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void verify() { }
|
void verify() { }
|
||||||
|
|
||||||
|
heptagon *create_step(heptagon *h, int d) {
|
||||||
|
|
||||||
|
SDEBUG( printf("%p.%d ~ ?\n", h, d); )
|
||||||
|
|
||||||
|
heptspin hi(h, d);
|
||||||
|
|
||||||
|
while(skip_digons(hi, 1)) hi++;
|
||||||
|
|
||||||
|
auto& t1 = current.get_triangle(hi);
|
||||||
|
|
||||||
|
// * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first)
|
||||||
|
|
||||||
|
auto& p1 = archimedean_gmatrix[h];
|
||||||
|
|
||||||
|
heptagon *alt = p1.first;
|
||||||
|
|
||||||
|
transmatrix T = p1.second * spin(-t1.first) * xpush(t1.second);
|
||||||
|
transmatrix U = Id;
|
||||||
|
|
||||||
|
if(hyperbolic) {
|
||||||
|
dynamicval<eGeometry> g(geometry, gNormal);
|
||||||
|
dynamicval<hrmap*> cm(currentmap, current_altmap);
|
||||||
|
U = T;
|
||||||
|
virtualRebaseSimple(alt, T);
|
||||||
|
U = U * inverse(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(euclid)
|
||||||
|
alt = encodeId(pair_to_vec(int(T[0][2]), int(T[1][2])));
|
||||||
|
|
||||||
|
SDEBUG( println(hlog, "look for: ", alt, " / ", T * C0); )
|
||||||
|
|
||||||
|
for(auto& p2: altmap[alt]) if(intval(p2.second * C0, T * C0) < 1e-4) {
|
||||||
|
SDEBUG( println(hlog, "cell found: ", p2.first); )
|
||||||
|
for(int d2=0; d2<p2.first->degree(); d2++) {
|
||||||
|
heptspin hs(p2.first, d2);
|
||||||
|
auto& t2 = current.get_triangle(p2.first, d2);
|
||||||
|
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||||
|
SDEBUG( print(hlog, "compare: ", T1 * xpush0(1)); )
|
||||||
|
SDEBUG( println(hlog, ":: ", p2.second * xpush0(1)); )
|
||||||
|
if(intval(T1 * xpush0(1), p2.second * xpush0(1)) < 1e-4) {
|
||||||
|
|
||||||
|
// T1 = p2.second
|
||||||
|
// T * spin(pi+t2.first) == p2.second
|
||||||
|
// p1.second * spinm(-t1.first) * xpush(t1.second) * spin(pi+t2.first) == p2.second
|
||||||
|
|
||||||
|
// bring p1 and p2 closer, to prevent floating point errors
|
||||||
|
if(hyperbolic) {
|
||||||
|
fixup_matrix(p1.second, U * p2.second * spin(-M_PI - t2.first) * xpush(-t1.second) * spin(t1.first), 0.25);
|
||||||
|
fixup_matrix(p2.second, T1, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(skip_digons(hs, -1)) hs--;
|
||||||
|
connectHeptagons(hi, hs);
|
||||||
|
connect_digons_too(hi, hs);
|
||||||
|
return h->move(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDEBUG( println(hlog, "but rotation not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& t2 = current.get_triangle(current.get_adj(hi));
|
||||||
|
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||||
|
fixmatrix(T1);
|
||||||
|
|
||||||
|
heptagon *hnew = build_child(hi, current.get_adj(hi));
|
||||||
|
altmap[alt].emplace_back(hnew, T1);
|
||||||
|
archimedean_gmatrix[hnew] = make_pair(alt, T1);
|
||||||
|
connect_digons_too(hi, heptspin(hnew, 0));
|
||||||
|
|
||||||
|
return hnew;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
dq::visited.clear();
|
||||||
|
dq::enqueue(viewctr.at, cview());
|
||||||
|
|
||||||
|
while(!dq::drawqueue.empty()) {
|
||||||
|
auto& p = dq::drawqueue.front();
|
||||||
|
heptagon *h = get<0>(p);
|
||||||
|
transmatrix V = get<1>(p);
|
||||||
|
dynamicval<ld> b(band_shift, get<2>(p));
|
||||||
|
dq::drawqueue.pop();
|
||||||
|
|
||||||
|
int id = id_of(h);
|
||||||
|
int S = isize(current.triangles[id]);
|
||||||
|
|
||||||
|
if(id < 2*current.N ? !DUAL : !PURE) {
|
||||||
|
if(!do_draw(h->c7, V)) continue;
|
||||||
|
drawcell(h->c7, V, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<S; i++) {
|
||||||
|
if(DUAL && (i&1)) continue;
|
||||||
|
h->cmove(i);
|
||||||
|
if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue;
|
||||||
|
transmatrix V1 = V * adjcell_matrix(h, i);
|
||||||
|
bandfixer bf(V1);
|
||||||
|
dq::enqueue(h->move(i), V1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
|
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
||||||
|
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
|
||||||
|
transmatrix gm = Id, where = Id;
|
||||||
|
while(h1 != h2) {
|
||||||
|
for(int i=0; i<neighbors_of(h1); i++) {
|
||||||
|
if(h1->move(i) == h2) {
|
||||||
|
return gm * adjcell_matrix(h1, i) * where;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(h1->distance > h2->distance) {
|
||||||
|
gm = gm * adjcell_matrix(h1, 0);
|
||||||
|
h1 = h1->move(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
where = inverse(adjcell_matrix(h2, 0)) * where;
|
||||||
|
h2 = h2->move(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gm * where;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hrmap *new_map() { return new hrmap_archimedean; }
|
hrmap *new_map() { return new hrmap_archimedean; }
|
||||||
|
|
||||||
transmatrix adjcell_matrix(heptagon *h, int d);
|
|
||||||
|
|
||||||
heptagon *build_child(heptspin p, pair<int, int> adj) {
|
heptagon *build_child(heptspin p, pair<int, int> adj) {
|
||||||
indenter ind;
|
indenter ind;
|
||||||
auto h = buildHeptagon1(tailored_alloc<heptagon> (isize(current.adjacent[adj.first])), p.at, p.spin, hstate(1), 0);
|
auto h = buildHeptagon1(tailored_alloc<heptagon> (isize(current.adjacent[adj.first])), p.at, p.spin, hstate(1), 0);
|
||||||
@ -540,76 +671,6 @@ void fixup_matrix(transmatrix& T, const transmatrix& X, ld step) {
|
|||||||
fixmatrix(T);
|
fixmatrix(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_adjacent(heptagon *h, int d) {
|
|
||||||
|
|
||||||
SDEBUG( printf("%p.%d ~ ?\n", h, d); )
|
|
||||||
|
|
||||||
heptspin hi(h, d);
|
|
||||||
|
|
||||||
while(skip_digons(hi, 1)) hi++;
|
|
||||||
|
|
||||||
auto& t1 = current.get_triangle(hi);
|
|
||||||
|
|
||||||
// * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first)
|
|
||||||
|
|
||||||
auto& p1 = archimedean_gmatrix[h];
|
|
||||||
|
|
||||||
heptagon *alt = p1.first;
|
|
||||||
|
|
||||||
transmatrix T = p1.second * spin(-t1.first) * xpush(t1.second);
|
|
||||||
transmatrix U = Id;
|
|
||||||
|
|
||||||
if(hyperbolic) {
|
|
||||||
dynamicval<eGeometry> g(geometry, gNormal);
|
|
||||||
U = T;
|
|
||||||
virtualRebaseSimple(alt, T);
|
|
||||||
U = U * inverse(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(euclid)
|
|
||||||
alt = encodeId(pair_to_vec(int(T[0][2]), int(T[1][2])));
|
|
||||||
|
|
||||||
SDEBUG( println(hlog, "look for: ", alt, " / ", T * C0); )
|
|
||||||
|
|
||||||
for(auto& p2: altmap[alt]) if(intval(p2.second * C0, T * C0) < 1e-4) {
|
|
||||||
SDEBUG( println(hlog, "cell found: ", p2.first); )
|
|
||||||
for(int d2=0; d2<p2.first->degree(); d2++) {
|
|
||||||
heptspin hs(p2.first, d2);
|
|
||||||
auto& t2 = current.get_triangle(p2.first, d2);
|
|
||||||
transmatrix T1 = T * spin(M_PI + t2.first);
|
|
||||||
SDEBUG( print(hlog, "compare: ", T1 * xpush0(1)); )
|
|
||||||
SDEBUG( println(hlog, ":: ", p2.second * xpush0(1)); )
|
|
||||||
if(intval(T1 * xpush0(1), p2.second * xpush0(1)) < 1e-4) {
|
|
||||||
|
|
||||||
// T1 = p2.second
|
|
||||||
// T * spin(pi+t2.first) == p2.second
|
|
||||||
// p1.second * spinm(-t1.first) * xpush(t1.second) * spin(pi+t2.first) == p2.second
|
|
||||||
|
|
||||||
// bring p1 and p2 closer, to prevent floating point errors
|
|
||||||
if(hyperbolic) {
|
|
||||||
fixup_matrix(p1.second, U * p2.second * spin(-M_PI - t2.first) * xpush(-t1.second) * spin(t1.first), 0.25);
|
|
||||||
fixup_matrix(p2.second, T1, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(skip_digons(hs, -1)) hs--;
|
|
||||||
connectHeptagons(hi, hs);
|
|
||||||
connect_digons_too(hi, hs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDEBUG( println(hlog, "but rotation not found"));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& t2 = current.get_triangle(current.get_adj(hi));
|
|
||||||
transmatrix T1 = T * spin(M_PI + t2.first);
|
|
||||||
fixmatrix(T1);
|
|
||||||
|
|
||||||
heptagon *hnew = build_child(hi, current.get_adj(hi));
|
|
||||||
altmap[alt].emplace_back(hnew, T1);
|
|
||||||
archimedean_gmatrix[hnew] = make_pair(alt, T1);
|
|
||||||
connect_digons_too(hi, heptspin(hnew, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<ld, ld>& archimedean_tiling::get_triangle(heptagon *h, int cid) {
|
pair<ld, ld>& archimedean_tiling::get_triangle(heptagon *h, int cid) {
|
||||||
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||||
}
|
}
|
||||||
@ -637,58 +698,6 @@ transmatrix adjcell_matrix(heptagon *h, int d) {
|
|||||||
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first);
|
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw() {
|
|
||||||
dq::visited.clear();
|
|
||||||
dq::enqueue(viewctr.at, cview());
|
|
||||||
|
|
||||||
while(!dq::drawqueue.empty()) {
|
|
||||||
auto& p = dq::drawqueue.front();
|
|
||||||
heptagon *h = get<0>(p);
|
|
||||||
transmatrix V = get<1>(p);
|
|
||||||
dynamicval<ld> b(band_shift, get<2>(p));
|
|
||||||
dq::drawqueue.pop();
|
|
||||||
|
|
||||||
int id = id_of(h);
|
|
||||||
int S = isize(current.triangles[id]);
|
|
||||||
|
|
||||||
if(id < 2*current.N ? !DUAL : !PURE) {
|
|
||||||
if(!do_draw(h->c7, V)) continue;
|
|
||||||
drawcell(h->c7, V, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0; i<S; i++) {
|
|
||||||
if(DUAL && (i&1)) continue;
|
|
||||||
h->cmove(i);
|
|
||||||
if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue;
|
|
||||||
transmatrix V1 = V * adjcell_matrix(h, i);
|
|
||||||
bandfixer bf(V1);
|
|
||||||
dq::enqueue(h->move(i), V1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
|
||||||
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
|
||||||
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
|
|
||||||
transmatrix gm = Id, where = Id;
|
|
||||||
while(h1 != h2) {
|
|
||||||
for(int i=0; i<neighbors_of(h1); i++) {
|
|
||||||
if(h1->move(i) == h2) {
|
|
||||||
return gm * adjcell_matrix(h1, i) * where;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(h1->distance > h2->distance) {
|
|
||||||
gm = gm * adjcell_matrix(h1, 0);
|
|
||||||
h1 = h1->move(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
where = inverse(adjcell_matrix(h2, 0)) * where;
|
|
||||||
h2 = h2->move(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gm * where;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fix(heptagon *h, int spin) {
|
int fix(heptagon *h, int spin) {
|
||||||
int type = isize(current.adjacent[id_of(h)]);
|
int type = isize(current.adjacent[id_of(h)]);
|
||||||
spin %= type;
|
spin %= type;
|
||||||
|
36
bigstuff.cpp
36
bigstuff.cpp
@ -102,7 +102,7 @@ cell *findcompass(cell *c) {
|
|||||||
|
|
||||||
while(inscreenrange(c)) {
|
while(inscreenrange(c)) {
|
||||||
if(!eubinary && !sphere && !quotient)
|
if(!eubinary && !sphere && !quotient)
|
||||||
generateAlts(c->master);
|
currentmap->generateAlts(c->master);
|
||||||
forCellEx(c2, c) if(compassDist(c2) < d) {
|
forCellEx(c2, c) if(compassDist(c2) < d) {
|
||||||
c = c2;
|
c = c2;
|
||||||
d = compassDist(c2);
|
d = compassDist(c2);
|
||||||
@ -120,7 +120,7 @@ bool grailWasFound(cell *c) {
|
|||||||
return c->master->alt->alt->emeraldval & GRAIL_FOUND;
|
return c->master->alt->alt->emeraldval & GRAIL_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateAlts(heptagon *h, int levs, bool link_cdata) {
|
void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) {
|
||||||
if(!h->alt) return;
|
if(!h->alt) return;
|
||||||
preventbarriers(h->c7);
|
preventbarriers(h->c7);
|
||||||
if(h->c7) forCellEx(c2, h->c7) preventbarriers(c2);
|
if(h->c7) forCellEx(c2, h->c7) preventbarriers(c2);
|
||||||
@ -165,7 +165,7 @@ void generateAlts(heptagon *h, int levs, bool link_cdata) {
|
|||||||
}
|
}
|
||||||
ho->alt = hm;
|
ho->alt = hm;
|
||||||
if(link_cdata) hm->cdata = (cdata*) ho;
|
if(link_cdata) hm->cdata = (cdata*) ho;
|
||||||
if(levs) generateAlts(ho, levs-1, link_cdata);
|
if(levs) currentmap->generateAlts(ho, levs-1, link_cdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
|
|||||||
alt->cdata = (cdata*) h;
|
alt->cdata = (cdata*) h;
|
||||||
|
|
||||||
for(int d=rad; d>=0; d--) {
|
for(int d=rad; d>=0; d--) {
|
||||||
generateAlts(cx[d]->master);
|
currentmap->generateAlts(cx[d]->master);
|
||||||
preventbarriers(cx[d]);
|
preventbarriers(cx[d]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ void beCIsland(cell *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generateTreasureIsland(cell *c) {
|
void generateTreasureIsland(cell *c) {
|
||||||
if(!eubinary) generateAlts(c->master);
|
if(!eubinary) currentmap->generateAlts(c->master);
|
||||||
if(isOnCIsland(c)) return;
|
if(isOnCIsland(c)) return;
|
||||||
|
|
||||||
bool src = hrand(100) < 10;
|
bool src = hrand(100) < 10;
|
||||||
@ -277,7 +277,7 @@ void generateTreasureIsland(cell *c) {
|
|||||||
int qc = 0, qlo, qhi;
|
int qc = 0, qlo, qhi;
|
||||||
for(int i=0; i<c->type; i++) {
|
for(int i=0; i<c->type; i++) {
|
||||||
cell *c2 = createMov(c, i);
|
cell *c2 = createMov(c, i);
|
||||||
if(!eubinary) generateAlts(c2->master);
|
if(!eubinary) currentmap->generateAlts(c2->master);
|
||||||
if((eubinary || (c->master->alt && c2->master->alt)) && celldistAlt(c2) < celldistAlt(c)) {
|
if((eubinary || (c->master->alt && c2->master->alt)) && celldistAlt(c2) < celldistAlt(c)) {
|
||||||
ctab[qc++] = c2;
|
ctab[qc++] = c2;
|
||||||
qlo = i; qhi = i;
|
qlo = i; qhi = i;
|
||||||
@ -1174,7 +1174,7 @@ void buildBigStuff(cell *c, cell *from) {
|
|||||||
(princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on && !racing::on) {
|
(princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on && !racing::on) {
|
||||||
createAlternateMap(c, PRADIUS0, hsOrigin, waPalace);
|
createAlternateMap(c, PRADIUS0, hsOrigin, waPalace);
|
||||||
celllister cl(c, 5, 1000000, NULL);
|
celllister cl(c, 5, 1000000, NULL);
|
||||||
for(cell *c: cl.lst) if(c->master->alt) generateAlts(c->master);
|
for(cell *c: cl.lst) if(c->master->alt) currentmap->generateAlts(c->master);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1225,12 +1225,12 @@ bool no_barriers_in_radius(cell *c, int rad) {
|
|||||||
void buildCamelot(cell *c) {
|
void buildCamelot(cell *c) {
|
||||||
int d = celldistAltRelative(c);
|
int d = celldistAltRelative(c);
|
||||||
if(tactic::on || (d <= 14 && roundTableRadius(c) > 20)) {
|
if(tactic::on || (d <= 14 && roundTableRadius(c) > 20)) {
|
||||||
if(!eubinary) generateAlts(c->master);
|
if(!eubinary) currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
if(d == 10) {
|
if(d == 10) {
|
||||||
if(weirdhyperbolic ? hrand(100) < 50 : pseudohept(c)) buildCamelotWall(c);
|
if(weirdhyperbolic ? hrand(100) < 50 : pseudohept(c)) buildCamelotWall(c);
|
||||||
else {
|
else {
|
||||||
if(!eubinary) for(int i=0; i<S7; i++) generateAlts(c->master->move(i));
|
if(!eubinary) for(int i=0; i<S7; i++) currentmap->generateAlts(c->master->move(i));
|
||||||
int q = 0;
|
int q = 0;
|
||||||
if(weirdhyperbolic) {
|
if(weirdhyperbolic) {
|
||||||
for(int t=0; t<c->type; t++) createMov(c, t);
|
for(int t=0; t<c->type; t++) createMov(c, t);
|
||||||
@ -1277,7 +1277,7 @@ void buildCamelot(cell *c) {
|
|||||||
// roughly as many knights as table cells
|
// roughly as many knights as table cells
|
||||||
if(hrand(1000000) < 1000000 / expansion.get_growth())
|
if(hrand(1000000) < 1000000 / expansion.get_growth())
|
||||||
c->monst = moKnight;
|
c->monst = moKnight;
|
||||||
if(!eubinary) for(int i=0; i<S7; i++) generateAlts(c->master->move(i));
|
if(!eubinary) for(int i=0; i<S7; i++) currentmap->generateAlts(c->master->move(i));
|
||||||
for(int i=0; i<c->type; i++)
|
for(int i=0; i<c->type; i++)
|
||||||
if(c->move(i) && celldistAltRelative(c->move(i)) < d)
|
if(c->move(i) && celldistAltRelative(c->move(i)) < d)
|
||||||
c->mondir = (i+3) % 6;
|
c->mondir = (i+3) % 6;
|
||||||
@ -1304,16 +1304,16 @@ void moreBigStuff(cell *c) {
|
|||||||
|
|
||||||
if(c->land == laPalace && !eubinary && c->master->alt) {
|
if(c->land == laPalace && !eubinary && c->master->alt) {
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
if(d <= PRADIUS1) generateAlts(c->master);
|
if(d <= PRADIUS1) currentmap->generateAlts(c->master);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(c->land == laCanvas && !eubinary && c->master->alt && !quotient)
|
if(c->land == laCanvas && !eubinary && c->master->alt && !quotient)
|
||||||
generateAlts(c->master);
|
currentmap->generateAlts(c->master);
|
||||||
|
|
||||||
if(c->land == laStorms)
|
if(c->land == laStorms)
|
||||||
if(!eubinary && !quotient && !sphere) {
|
if(!eubinary && !quotient && !sphere) {
|
||||||
if(c->master->alt && c->master->alt->distance <= 2) {
|
if(c->master->alt && c->master->alt->distance <= 2) {
|
||||||
generateAlts(c->master);
|
currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
if(d <= -2) {
|
if(d <= -2) {
|
||||||
@ -1336,7 +1336,7 @@ void moreBigStuff(cell *c) {
|
|||||||
|
|
||||||
else if((c->land == laRlyeh && !euclid) || c->land == laTemple) if(!(binarytiling && specialland != laTemple)) {
|
else if((c->land == laRlyeh && !euclid) || c->land == laTemple) if(!(binarytiling && specialland != laTemple)) {
|
||||||
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
|
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
|
||||||
if(!eubinary && !chaosmode) generateAlts(c->master);
|
if(!eubinary && !chaosmode) currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
if(d <= 0) {
|
if(d <= 0) {
|
||||||
@ -1352,7 +1352,7 @@ void moreBigStuff(cell *c) {
|
|||||||
else if(pseudohept(c))
|
else if(pseudohept(c))
|
||||||
c->wall = waColumn;
|
c->wall = waColumn;
|
||||||
else {
|
else {
|
||||||
if(!eubinary) for(int i=0; i<S7; i++) generateAlts(c->master->move(i));
|
if(!eubinary) for(int i=0; i<S7; i++) currentmap->generateAlts(c->master->move(i));
|
||||||
int q = 0;
|
int q = 0;
|
||||||
for(int t=0; t<c->type; t++) {
|
for(int t=0; t<c->type; t++) {
|
||||||
createMov(c, t);
|
createMov(c, t);
|
||||||
@ -1366,7 +1366,7 @@ void moreBigStuff(cell *c) {
|
|||||||
|
|
||||||
if((c->land == laOvergrown && !euclid) || c->land == laClearing) if(!(binarytiling && specialland != laClearing)) {
|
if((c->land == laOvergrown && !euclid) || c->land == laClearing) if(!(binarytiling && specialland != laClearing)) {
|
||||||
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
|
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
|
||||||
if(!eubinary) generateAlts(c->master);
|
if(!eubinary) currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
if(d <= 0) {
|
if(d <= 0) {
|
||||||
@ -1379,7 +1379,7 @@ void moreBigStuff(cell *c) {
|
|||||||
|
|
||||||
if((c->land == laJungle && !euclid) || c->land == laMountain) if(!(binarytiling && specialland != laMountain)) {
|
if((c->land == laJungle && !euclid) || c->land == laMountain) if(!(binarytiling && specialland != laMountain)) {
|
||||||
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
|
if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) {
|
||||||
if(!eubinary) generateAlts(c->master);
|
if(!eubinary) currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
if(d <= 0 || (firstland == laMountain && tactic::on)) {
|
if(d <= 0 || (firstland == laMountain && tactic::on)) {
|
||||||
@ -1395,7 +1395,7 @@ void moreBigStuff(cell *c) {
|
|||||||
if(yendor::on && yendor::clev().l == laWhirlpool)
|
if(yendor::on && yendor::clev().l == laWhirlpool)
|
||||||
fullwhirlpool = true;
|
fullwhirlpool = true;
|
||||||
if(eubinary || (c->master->alt && (fullwhirlpool || c->master->alt->distance <= 2))) {
|
if(eubinary || (c->master->alt && (fullwhirlpool || c->master->alt->distance <= 2))) {
|
||||||
if(!eubinary) generateAlts(c->master);
|
if(!eubinary) currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int dd = celldistAlt(c);
|
int dd = celldistAlt(c);
|
||||||
if(dd <= 0 || fullwhirlpool) {
|
if(dd <= 0 || fullwhirlpool) {
|
||||||
|
@ -45,6 +45,9 @@ namespace binary {
|
|||||||
void breakhere() {
|
void breakhere() {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transmatrix& tmatrix(heptagon *h, int dir);
|
||||||
|
const transmatrix& itmatrix(heptagon *h, int dir);
|
||||||
|
|
||||||
heptagon *path(heptagon *h, int d, int d1, std::initializer_list<int> p) {
|
heptagon *path(heptagon *h, int d, int d1, std::initializer_list<int> p) {
|
||||||
static int rec = 0;
|
static int rec = 0;
|
||||||
@ -53,7 +56,7 @@ namespace binary {
|
|||||||
heptagon *h1 = h;
|
heptagon *h1 = h;
|
||||||
for(int d0: p) {
|
for(int d0: p) {
|
||||||
// printf(" [%d]", d0);
|
// printf(" [%d]", d0);
|
||||||
h1 = hr::createStep(h1, d0);
|
h1 = currentmap->may_create_step(h1, d0);
|
||||||
// printf(" %p", h1);
|
// printf(" %p", h1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,113 +107,205 @@ namespace binary {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
heptagon *createStep(heptagon *parent, int d) {
|
struct hrmap_binary : hrmap_hyperbolic {
|
||||||
auto h = parent;
|
|
||||||
switch(d) {
|
|
||||||
case bd_right: {
|
|
||||||
if(mapside(h) > 0 && type_of(h) == 7)
|
|
||||||
return path(h, d, bd_left, {bd_left, bd_down, bd_right, bd_up});
|
|
||||||
else if(mapside(h) >= 0)
|
|
||||||
return build(parent, bd_right, bd_left, type_of(parent) ^ 1, 1, 0);
|
|
||||||
else if(type_of(h) == 6)
|
|
||||||
return path(h, d, bd_left, {bd_down, bd_right, bd_up, bd_left});
|
|
||||||
else
|
|
||||||
return path(h, d, bd_left, {bd_down_right, bd_up});
|
|
||||||
}
|
|
||||||
case bd_left: {
|
|
||||||
if(mapside(h) < 0 && type_of(h) == 7)
|
|
||||||
return path(h, d, bd_right, {bd_right, bd_down, bd_left, bd_up});
|
|
||||||
else if(mapside(h) <= 0)
|
|
||||||
return build(parent, bd_left, bd_right, type_of(parent) ^ 1, -1, 0);
|
|
||||||
else if(type_of(h) == 6)
|
|
||||||
return path(h, d, bd_right, {bd_down, bd_left, bd_up, bd_right});
|
|
||||||
else
|
|
||||||
return path(h, d, bd_right, {bd_down_left, bd_up});
|
|
||||||
}
|
|
||||||
case bd_up_right: {
|
|
||||||
return path(h, d, bd_down_left, {bd_up, bd_right});
|
|
||||||
}
|
|
||||||
case bd_up_left: {
|
|
||||||
return path(h, d, bd_down_right, {bd_up, bd_left});
|
|
||||||
}
|
|
||||||
case bd_up:
|
|
||||||
return build(parent, bd_up, bd_down, 6, mapside(parent), 1);
|
|
||||||
default:
|
|
||||||
/* bd_down */
|
|
||||||
if(type_of(h) == 6) {
|
|
||||||
if(mapside(h) == 0)
|
|
||||||
return build(parent, bd_down, bd_up, 6, 0, -1);
|
|
||||||
else if(mapside(h) == 1)
|
|
||||||
return path(h, d, bd_up, {bd_left, bd_left, bd_down, bd_right});
|
|
||||||
else if(mapside(h) == -1)
|
|
||||||
return path(h, d, bd_up, {bd_right, bd_right, bd_down, bd_left});
|
|
||||||
}
|
|
||||||
/* bd_down_left */
|
|
||||||
else if(d == bd_down_left) {
|
|
||||||
return path(h, d, bd_up_right, {bd_left, bd_down});
|
|
||||||
}
|
|
||||||
else if(d == bd_down_right) {
|
|
||||||
return path(h, d, bd_up_left, {bd_right, bd_down});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("error: case not handled in binary tiling\n");
|
|
||||||
breakhere();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MAXMDIM==4
|
|
||||||
heptagon *createStep3(heptagon *parent, int d) {
|
|
||||||
auto h = parent;
|
|
||||||
if(geometry == gBinary3)
|
|
||||||
switch(d) {
|
|
||||||
case 0: case 1:
|
|
||||||
case 2: case 3:
|
|
||||||
return build3(parent, d, 8, 1);
|
|
||||||
case 8:
|
|
||||||
return build3(parent, 8, hrand(4), -1);
|
|
||||||
case 4:
|
|
||||||
parent->cmove(8);
|
|
||||||
if(parent->c.spin(8) & 1)
|
|
||||||
return path(h, 4, 5, {8, parent->c.spin(8) ^ 1});
|
|
||||||
else
|
|
||||||
return path(h, 4, 5, {8, 4, parent->c.spin(8) ^ 1});
|
|
||||||
case 5:
|
|
||||||
parent->cmove(8);
|
|
||||||
if(!(parent->c.spin(8) & 1))
|
|
||||||
return path(h, 5, 4, {8, parent->c.spin(8) ^ 1});
|
|
||||||
else
|
|
||||||
return path(h, 5, 4, {8, 5, parent->c.spin(8) ^ 1});
|
|
||||||
case 6:
|
|
||||||
parent->cmove(8);
|
|
||||||
if(parent->c.spin(8) & 2)
|
|
||||||
return path(h, 6, 7, {8, parent->c.spin(8) ^ 2});
|
|
||||||
else
|
|
||||||
return path(h, 6, 7, {8, 6, parent->c.spin(8) ^ 2});
|
|
||||||
case 7:
|
|
||||||
parent->cmove(8);
|
|
||||||
if(!(parent->c.spin(8) & 2))
|
|
||||||
return path(h, 7, 6, {8, parent->c.spin(8) ^ 2});
|
|
||||||
else
|
|
||||||
return path(h, 7, 6, {8, 7, parent->c.spin(8) ^ 2});
|
|
||||||
}
|
|
||||||
if(geometry == gHoroTris) switch(d) {
|
|
||||||
case 0: case 1: case 2: case 3:
|
|
||||||
return build3(parent, d, 7, 1);
|
|
||||||
case 7:
|
|
||||||
return build3(parent, 7, hrand(3), -1);
|
|
||||||
case 4: case 5: case 6:
|
|
||||||
parent->cmove(7);
|
|
||||||
int s = parent->c.spin(7);
|
|
||||||
if(s == 0) return path(h, d, d, {7, d-3});
|
|
||||||
else if(s == d-3) return path(h, d, d, {7, 0});
|
|
||||||
else return path(h, d, d, {7, d, 9-d-s});
|
|
||||||
}
|
|
||||||
printf("error: case not handled in binary tiling\n");
|
|
||||||
breakhere();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
hrmap_binary(heptagon *o) : hrmap_hyperbolic(o) {}
|
||||||
|
|
||||||
|
hrmap_binary() : hrmap_hyperbolic() {}
|
||||||
|
|
||||||
|
heptagon *create_step(heptagon *parent, int d) {
|
||||||
|
auto h = parent;
|
||||||
|
switch(geometry) {
|
||||||
|
case gBinaryTiling: {
|
||||||
|
switch(d) {
|
||||||
|
case bd_right: {
|
||||||
|
if(mapside(h) > 0 && type_of(h) == 7)
|
||||||
|
return path(h, d, bd_left, {bd_left, bd_down, bd_right, bd_up});
|
||||||
|
else if(mapside(h) >= 0)
|
||||||
|
return build(parent, bd_right, bd_left, type_of(parent) ^ 1, 1, 0);
|
||||||
|
else if(type_of(h) == 6)
|
||||||
|
return path(h, d, bd_left, {bd_down, bd_right, bd_up, bd_left});
|
||||||
|
else
|
||||||
|
return path(h, d, bd_left, {bd_down_right, bd_up});
|
||||||
|
}
|
||||||
|
case bd_left: {
|
||||||
|
if(mapside(h) < 0 && type_of(h) == 7)
|
||||||
|
return path(h, d, bd_right, {bd_right, bd_down, bd_left, bd_up});
|
||||||
|
else if(mapside(h) <= 0)
|
||||||
|
return build(parent, bd_left, bd_right, type_of(parent) ^ 1, -1, 0);
|
||||||
|
else if(type_of(h) == 6)
|
||||||
|
return path(h, d, bd_right, {bd_down, bd_left, bd_up, bd_right});
|
||||||
|
else
|
||||||
|
return path(h, d, bd_right, {bd_down_left, bd_up});
|
||||||
|
}
|
||||||
|
case bd_up_right: {
|
||||||
|
return path(h, d, bd_down_left, {bd_up, bd_right});
|
||||||
|
}
|
||||||
|
case bd_up_left: {
|
||||||
|
return path(h, d, bd_down_right, {bd_up, bd_left});
|
||||||
|
}
|
||||||
|
case bd_up:
|
||||||
|
return build(parent, bd_up, bd_down, 6, mapside(parent), 1);
|
||||||
|
default:
|
||||||
|
/* bd_down */
|
||||||
|
if(type_of(h) == 6) {
|
||||||
|
if(mapside(h) == 0)
|
||||||
|
return build(parent, bd_down, bd_up, 6, 0, -1);
|
||||||
|
else if(mapside(h) == 1)
|
||||||
|
return path(h, d, bd_up, {bd_left, bd_left, bd_down, bd_right});
|
||||||
|
else if(mapside(h) == -1)
|
||||||
|
return path(h, d, bd_up, {bd_right, bd_right, bd_down, bd_left});
|
||||||
|
}
|
||||||
|
/* bd_down_left */
|
||||||
|
else if(d == bd_down_left) {
|
||||||
|
return path(h, d, bd_up_right, {bd_left, bd_down});
|
||||||
|
}
|
||||||
|
else if(d == bd_down_right) {
|
||||||
|
return path(h, d, bd_up_left, {bd_right, bd_down});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("error: case not handled in binary tiling\n");
|
||||||
|
breakhere();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
case gBinary3: {
|
||||||
|
switch(d) {
|
||||||
|
case 0: case 1:
|
||||||
|
case 2: case 3:
|
||||||
|
return build3(parent, d, 8, 1);
|
||||||
|
case 8:
|
||||||
|
return build3(parent, 8, hrand(4), -1);
|
||||||
|
case 4:
|
||||||
|
parent->cmove(8);
|
||||||
|
if(parent->c.spin(8) & 1)
|
||||||
|
return path(h, 4, 5, {8, parent->c.spin(8) ^ 1});
|
||||||
|
else
|
||||||
|
return path(h, 4, 5, {8, 4, parent->c.spin(8) ^ 1});
|
||||||
|
case 5:
|
||||||
|
parent->cmove(8);
|
||||||
|
if(!(parent->c.spin(8) & 1))
|
||||||
|
return path(h, 5, 4, {8, parent->c.spin(8) ^ 1});
|
||||||
|
else
|
||||||
|
return path(h, 5, 4, {8, 5, parent->c.spin(8) ^ 1});
|
||||||
|
case 6:
|
||||||
|
parent->cmove(8);
|
||||||
|
if(parent->c.spin(8) & 2)
|
||||||
|
return path(h, 6, 7, {8, parent->c.spin(8) ^ 2});
|
||||||
|
else
|
||||||
|
return path(h, 6, 7, {8, 6, parent->c.spin(8) ^ 2});
|
||||||
|
case 7:
|
||||||
|
parent->cmove(8);
|
||||||
|
if(!(parent->c.spin(8) & 2))
|
||||||
|
return path(h, 7, 6, {8, parent->c.spin(8) ^ 2});
|
||||||
|
else
|
||||||
|
return path(h, 7, 6, {8, 7, parent->c.spin(8) ^ 2});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case gHoroTris: {
|
||||||
|
switch(d) {
|
||||||
|
case 0: case 1: case 2: case 3:
|
||||||
|
return build3(parent, d, 7, 1);
|
||||||
|
case 7:
|
||||||
|
return build3(parent, 7, hrand(3), -1);
|
||||||
|
case 4: case 5: case 6:
|
||||||
|
parent->cmove(7);
|
||||||
|
int s = parent->c.spin(7);
|
||||||
|
if(s == 0) return path(h, d, d, {7, d-3});
|
||||||
|
else if(s == d-3) return path(h, d, d, {7, 0});
|
||||||
|
else return path(h, d, d, {7, d, 9-d-s});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
printf("error: case not handled in binary tiling\n");
|
||||||
|
breakhere();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
dq::visited.clear();
|
||||||
|
dq::enqueue(viewctr.at, cview());
|
||||||
|
{
|
||||||
|
dynamicval<color_t> d(poly_outline, 0xFFFFFFFF);
|
||||||
|
for(int i=0; i<S7; i++) queuepolyat(cview(), shWall3D[i], 0, PPR::SUPERLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!dq::drawqueue.empty()) {
|
||||||
|
auto& p = dq::drawqueue.front();
|
||||||
|
heptagon *h = get<0>(p);
|
||||||
|
transmatrix V = get<1>(p);
|
||||||
|
dynamicval<ld> b(band_shift, get<2>(p));
|
||||||
|
bandfixer bf(V);
|
||||||
|
dq::drawqueue.pop();
|
||||||
|
|
||||||
|
|
||||||
|
cell *c = h->c7;
|
||||||
|
if(!do_draw(c, V)) continue;
|
||||||
|
drawcell(c, V, 0, false);
|
||||||
|
|
||||||
|
if(DIM == 2) {
|
||||||
|
dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
|
||||||
|
dq::enqueue(h->move(bd_right), V * parabolic(1));
|
||||||
|
dq::enqueue(h->move(bd_left), V * parabolic(-1));
|
||||||
|
if(c->type == 6)
|
||||||
|
dq::enqueue(h->move(bd_down), V * xpush(log(2)));
|
||||||
|
if(c->type == 7) {
|
||||||
|
dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2)));
|
||||||
|
dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(int i=0; i<S7; i++)
|
||||||
|
dq::enqueue(h->move(i), V * tmatrix(h, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
|
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
||||||
|
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
|
||||||
|
transmatrix gm = Id, where = Id;
|
||||||
|
while(h1 != h2) {
|
||||||
|
if(h1->distance <= h2->distance) {
|
||||||
|
if(DIM == 3)
|
||||||
|
where = itmatrix(h2, S7-1) * where, h2 = may_create_step(h2, S7-1);
|
||||||
|
else {
|
||||||
|
if(type_of(h2) == 6)
|
||||||
|
h2 = may_create_step(h2, bd_down), where = xpush(-log(2)) * where;
|
||||||
|
else if(mapside(h2) == 1)
|
||||||
|
h2 = may_create_step(h2, bd_left), where = parabolic(+1) * where;
|
||||||
|
else if(mapside(h2) == -1)
|
||||||
|
h2 = may_create_step(h2, bd_right), where = parabolic(-1) * where;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(DIM == 3)
|
||||||
|
gm = gm * tmatrix(h1, S7-1), h1 = may_create_step(h1, S7-1);
|
||||||
|
else {
|
||||||
|
if(type_of(h1) == 6)
|
||||||
|
h1 = may_create_step(h1, bd_down), gm = gm * xpush(log(2));
|
||||||
|
else if(mapside(h1) == 1)
|
||||||
|
h1 = may_create_step(h1, bd_left), gm = gm * parabolic(-1);
|
||||||
|
else if(mapside(h1) == -1)
|
||||||
|
h1 = may_create_step(h1, bd_right), gm = gm * parabolic(+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gm * where;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hrmap *new_map() { return new hrmap_binary; }
|
||||||
|
|
||||||
|
struct hrmap_alternate_binary : hrmap_binary {
|
||||||
|
heptagon *origin;
|
||||||
|
hrmap_alternate_binary(heptagon *o) { origin = o; }
|
||||||
|
~hrmap_alternate_binary() { clearfrom(origin); }
|
||||||
|
};
|
||||||
|
|
||||||
|
hrmap *new_alt_map(heptagon *o) { return new hrmap_binary(o); }
|
||||||
|
|
||||||
transmatrix direct_tmatrix[8];
|
transmatrix direct_tmatrix[8];
|
||||||
transmatrix inverse_tmatrix[8];
|
transmatrix inverse_tmatrix[8];
|
||||||
|
|
||||||
@ -312,74 +407,6 @@ namespace binary {
|
|||||||
return point3(log(2) + log(-h[0]), h[1] / co, h[2] / co);
|
return point3(log(2) + log(-h[0]), h[1] / co, h[2] / co);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw() {
|
|
||||||
dq::visited.clear();
|
|
||||||
dq::enqueue(viewctr.at, cview());
|
|
||||||
|
|
||||||
while(!dq::drawqueue.empty()) {
|
|
||||||
auto& p = dq::drawqueue.front();
|
|
||||||
heptagon *h = get<0>(p);
|
|
||||||
transmatrix V = get<1>(p);
|
|
||||||
dynamicval<ld> b(band_shift, get<2>(p));
|
|
||||||
bandfixer bf(V);
|
|
||||||
dq::drawqueue.pop();
|
|
||||||
|
|
||||||
|
|
||||||
cell *c = h->c7;
|
|
||||||
if(!do_draw(c, V)) continue;
|
|
||||||
drawcell(c, V, 0, false);
|
|
||||||
|
|
||||||
if(DIM == 2) {
|
|
||||||
dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
|
|
||||||
dq::enqueue(h->move(bd_right), V * parabolic(1));
|
|
||||||
dq::enqueue(h->move(bd_left), V * parabolic(-1));
|
|
||||||
if(c->type == 6)
|
|
||||||
dq::enqueue(h->move(bd_down), V * xpush(log(2)));
|
|
||||||
if(c->type == 7) {
|
|
||||||
dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2)));
|
|
||||||
dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for(int i=0; i<S7; i++)
|
|
||||||
dq::enqueue(h->move(i), V * tmatrix(h, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
|
||||||
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
|
||||||
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
|
|
||||||
transmatrix gm = Id, where = Id;
|
|
||||||
while(h1 != h2) {
|
|
||||||
if(h1->distance <= h2->distance) {
|
|
||||||
if(DIM == 3)
|
|
||||||
where = itmatrix(h2, S7-1) * where, h2 = hr::createStep(h2, S7-1);
|
|
||||||
else {
|
|
||||||
if(type_of(h2) == 6)
|
|
||||||
h2 = hr::createStep(h2, bd_down), where = xpush(-log(2)) * where;
|
|
||||||
else if(mapside(h2) == 1)
|
|
||||||
h2 = hr::createStep(h2, bd_left), where = parabolic(+1) * where;
|
|
||||||
else if(mapside(h2) == -1)
|
|
||||||
h2 = hr::createStep(h2, bd_right), where = parabolic(-1) * where;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(DIM == 3)
|
|
||||||
gm = gm * tmatrix(h1, S7-1), h1 = hr::createStep(h1, S7-1);
|
|
||||||
else {
|
|
||||||
if(type_of(h1) == 6)
|
|
||||||
h1 = hr::createStep(h1, bd_down), gm = gm * xpush(log(2));
|
|
||||||
else if(mapside(h1) == 1)
|
|
||||||
h1 = hr::createStep(h1, bd_left), gm = gm * parabolic(-1);
|
|
||||||
else if(mapside(h1) == -1)
|
|
||||||
h1 = hr::createStep(h1, bd_right), gm = gm * parabolic(+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gm * where;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CAP_COMMANDLINE
|
#if CAP_COMMANDLINE
|
||||||
auto bt_config = addHook(hooks_args, 0, [] () {
|
auto bt_config = addHook(hooks_args, 0, [] () {
|
||||||
using namespace arg;
|
using namespace arg;
|
||||||
|
12
cell.cpp
12
cell.cpp
@ -39,16 +39,11 @@ struct cdata {
|
|||||||
hrmap *currentmap;
|
hrmap *currentmap;
|
||||||
vector<hrmap*> allmaps;
|
vector<hrmap*> allmaps;
|
||||||
|
|
||||||
// --- auxiliary hyperbolic map for horocycles ---
|
hrmap *newAltMap(heptagon *o) { return new hrmap_hyperbolic(o); }
|
||||||
struct hrmap_alternate : hrmap {
|
|
||||||
heptagon *origin;
|
|
||||||
hrmap_alternate(heptagon *o) { origin = o; }
|
|
||||||
~hrmap_alternate() { clearfrom(origin); }
|
|
||||||
};
|
|
||||||
|
|
||||||
hrmap *newAltMap(heptagon *o) { return new hrmap_alternate(o); }
|
|
||||||
// --- hyperbolic geometry ---
|
// --- hyperbolic geometry ---
|
||||||
|
|
||||||
|
hrmap_hyperbolic::hrmap_hyperbolic(heptagon *o) { origin = o; }
|
||||||
|
|
||||||
hrmap_hyperbolic::hrmap_hyperbolic() {
|
hrmap_hyperbolic::hrmap_hyperbolic() {
|
||||||
// printf("Creating hyperbolic map: %p\n", this);
|
// printf("Creating hyperbolic map: %p\n", this);
|
||||||
origin = tailored_alloc<heptagon> (S7);
|
origin = tailored_alloc<heptagon> (S7);
|
||||||
@ -235,6 +230,7 @@ void initcells() {
|
|||||||
else if(DIM == 3 && !binarytiling) currentmap = reg3::new_map();
|
else if(DIM == 3 && !binarytiling) currentmap = reg3::new_map();
|
||||||
else if(sphere) currentmap = new hrmap_spherical;
|
else if(sphere) currentmap = new hrmap_spherical;
|
||||||
else if(quotient) currentmap = new quotientspace::hrmap_quotient;
|
else if(quotient) currentmap = new quotientspace::hrmap_quotient;
|
||||||
|
else if(binarytiling) currentmap = binary::new_map();
|
||||||
else currentmap = new hrmap_hyperbolic;
|
else currentmap = new hrmap_hyperbolic;
|
||||||
|
|
||||||
allmaps.push_back(currentmap);
|
allmaps.push_back(currentmap);
|
||||||
|
@ -765,9 +765,9 @@ namespace clearing {
|
|||||||
|
|
||||||
int plantdir(cell *c) {
|
int plantdir(cell *c) {
|
||||||
if(!quotient) {
|
if(!quotient) {
|
||||||
generateAlts(c->master);
|
currentmap->generateAlts(c->master);
|
||||||
for(int i=0; i<S7; i++)
|
for(int i=0; i<S7; i++)
|
||||||
generateAlts(c->master->move(i));
|
currentmap->generateAlts(c->master->move(i));
|
||||||
}
|
}
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
|
|
||||||
@ -848,7 +848,7 @@ namespace clearing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cell *oc = c;
|
// cell *oc = c;
|
||||||
if(!euclid) generateAlts(c->master);
|
if(!euclid) currentmap->generateAlts(c->master);
|
||||||
if(pseudohept(c)) return;
|
if(pseudohept(c)) return;
|
||||||
heptagon *a = euclid ? NULL : c->master->alt->alt;
|
heptagon *a = euclid ? NULL : c->master->alt->alt;
|
||||||
clearingdata& bd(bpdata[a]);
|
clearingdata& bd(bpdata[a]);
|
||||||
|
80
crystal.cpp
80
crystal.cpp
@ -352,7 +352,9 @@ int fiftyrule(coord c) {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hrmap_crystal : hrmap {
|
bool is_bi(crystal_structure& cs, coord co);
|
||||||
|
|
||||||
|
struct hrmap_crystal : hrmap_standard {
|
||||||
heptagon *getOrigin() { return get_heptagon_at(c0, S7); }
|
heptagon *getOrigin() { return get_heptagon_at(c0, S7); }
|
||||||
|
|
||||||
map<heptagon*, coord> hcoords;
|
map<heptagon*, coord> hcoords;
|
||||||
@ -435,6 +437,44 @@ struct hrmap_crystal : hrmap {
|
|||||||
void verify() { }
|
void verify() { }
|
||||||
|
|
||||||
void prepare_east();
|
void prepare_east();
|
||||||
|
|
||||||
|
heptagon *create_step(heptagon *h, int d) {
|
||||||
|
if(!hcoords.count(h)) {
|
||||||
|
printf("not found\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
auto co = hcoords[h];
|
||||||
|
|
||||||
|
if(is_bi(cs, co)) {
|
||||||
|
heptspin hs(h, d);
|
||||||
|
(hs + 1 + wstep + 1).cpeek();
|
||||||
|
return h->move(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lw = makewalker(co, d);
|
||||||
|
|
||||||
|
if(ginf[gCrystal].vertex == 4) {
|
||||||
|
auto c1 = add(co, lw, FULLSTEP);
|
||||||
|
auto lw1 = lw+wstep;
|
||||||
|
|
||||||
|
h->c.connect(d, heptspin(get_heptagon_at(c1, S7), lw1.spin));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto coc = add(add(co, lw, HALFSTEP), lw+1, HALFSTEP);
|
||||||
|
auto hc = get_heptagon_at(coc, 8);
|
||||||
|
for(int a=0; a<8; a+=2) {
|
||||||
|
hc->c.connect(a, heptspin(h, lw.spin));
|
||||||
|
if(h->modmove(lw.spin-1)) {
|
||||||
|
hc->c.connect(a+1, heptspin(h, lw.spin) - 1 + wstep - 1);
|
||||||
|
}
|
||||||
|
co = add(co, lw, FULLSTEP);
|
||||||
|
lw = lw + wstep + (-1);
|
||||||
|
h = get_heptagon_at(co, S7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return h->move(d);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hrmap_crystal *crystal_map() {
|
hrmap_crystal *crystal_map() {
|
||||||
@ -450,44 +490,6 @@ bool is_bi(crystal_structure& cs, coord co) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_step(heptagon *h, int d) {
|
|
||||||
auto m = crystal_map();
|
|
||||||
if(geometry != gCrystal) return;
|
|
||||||
if(!m->hcoords.count(h)) {
|
|
||||||
printf("not found\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto co = m->hcoords[h];
|
|
||||||
|
|
||||||
if(is_bi(m->cs, co)) {
|
|
||||||
heptspin hs(h, d);
|
|
||||||
(hs + 1 + wstep + 1).cpeek();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lw = m->makewalker(co, d);
|
|
||||||
|
|
||||||
if(ginf[gCrystal].vertex == 4) {
|
|
||||||
auto c1 = add(co, lw, FULLSTEP);
|
|
||||||
auto lw1 = lw+wstep;
|
|
||||||
|
|
||||||
h->c.connect(d, heptspin(m->get_heptagon_at(c1, S7), lw1.spin));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto coc = add(add(co, lw, HALFSTEP), lw+1, HALFSTEP);
|
|
||||||
auto hc = m->get_heptagon_at(coc, 8);
|
|
||||||
for(int a=0; a<8; a+=2) {
|
|
||||||
hc->c.connect(a, heptspin(h, lw.spin));
|
|
||||||
if(h->modmove(lw.spin-1)) {
|
|
||||||
hc->c.connect(a+1, heptspin(h, lw.spin) - 1 + wstep - 1);
|
|
||||||
}
|
|
||||||
co = add(co, lw, FULLSTEP);
|
|
||||||
lw = lw + wstep + (-1);
|
|
||||||
h = m->get_heptagon_at(co, S7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
array<array<int,2>, MAX_EDGE> distlimit_table = {{
|
array<array<int,2>, MAX_EDGE> distlimit_table = {{
|
||||||
{{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{15, 10}},
|
{{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{15, 10}},
|
||||||
{{6, 4}}, {{5, 3}}, {{4, 3}}, {{4, 3}}, {{3, 2}}, {{3, 2}}, {{3, 2}}, {{3, 2}}, {{3, 2}}
|
{{6, 4}}, {{5, 3}}, {{4, 3}}, {{4, 3}}, {{3, 2}}, {{3, 2}}, {{3, 2}}, {{3, 2}}, {{3, 2}}
|
||||||
|
145
euclid.cpp
145
euclid.cpp
@ -10,6 +10,8 @@ namespace hr {
|
|||||||
// NOTE: patterns assume that pair_to_vec(0,1) % 3 == 2!
|
// NOTE: patterns assume that pair_to_vec(0,1) % 3 == 2!
|
||||||
// Thus, pair_to_vec(0,1) must not be e.g. a power of four
|
// Thus, pair_to_vec(0,1) must not be e.g. a power of four
|
||||||
|
|
||||||
|
int cell_to_vec(cell *c);
|
||||||
|
|
||||||
int pair_to_vec(int x, int y) {
|
int pair_to_vec(int x, int y) {
|
||||||
return x + (y << 15);
|
return x + (y << 15);
|
||||||
}
|
}
|
||||||
@ -299,7 +301,11 @@ template<class T> void build_euclidean_moves(cell *c, int vec, const T& builder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hrmap_torus : hrmap {
|
struct hrmap_euclid_any : hrmap {
|
||||||
|
void draw() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hrmap_torus : hrmap_euclid_any {
|
||||||
|
|
||||||
vector<cell*> all;
|
vector<cell*> all;
|
||||||
vector<int> dists;
|
vector<int> dists;
|
||||||
@ -340,6 +346,27 @@ struct hrmap_torus : hrmap {
|
|||||||
~hrmap_torus() {
|
~hrmap_torus() {
|
||||||
for(cell *c: all) tailored_delete(c);
|
for(cell *c: all) tailored_delete(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||||
|
transmatrix t = Id;
|
||||||
|
// if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));
|
||||||
|
int d = celldistance(c2, c1);
|
||||||
|
while(d) {
|
||||||
|
forCellIdEx(cc, i, c1) {
|
||||||
|
int d1 = celldistance(cc, c2);
|
||||||
|
if(d1 < d) {
|
||||||
|
t = t * cellrelmatrix(c1, i);
|
||||||
|
c1 = cc;
|
||||||
|
d = d1;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("ERROR not reached\n");
|
||||||
|
break;
|
||||||
|
again: ;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
hrmap_torus *torusmap() {
|
hrmap_torus *torusmap() {
|
||||||
@ -352,7 +379,7 @@ hrmap_torus *torusmap() {
|
|||||||
return cur->all[id];
|
return cur->all[id];
|
||||||
} */
|
} */
|
||||||
|
|
||||||
struct hrmap_euclidean : hrmap {
|
struct hrmap_euclidean : hrmap_euclid_any {
|
||||||
|
|
||||||
cell *gamestart() {
|
cell *gamestart() {
|
||||||
return *(euclideanAtCreate(0).first);
|
return *(euclideanAtCreate(0).first);
|
||||||
@ -400,6 +427,10 @@ struct hrmap_euclidean : hrmap {
|
|||||||
}
|
}
|
||||||
eucdata.clear();
|
eucdata.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||||
|
return eumove(cell_to_vec(c2) - cell_to_vec(c1));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cellwalker vec_to_cellwalker(int vec) {
|
cellwalker vec_to_cellwalker(int vec) {
|
||||||
@ -558,9 +589,36 @@ namespace euclid3 {
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *createStep(heptagon *parent, int d) {
|
heptagon *create_step(heptagon *parent, int d) {
|
||||||
return build(parent, d, ispacemap[parent] + shifttable[d]);
|
return build(parent, d, ispacemap[parent] + shifttable[d]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
dq::visited.clear();
|
||||||
|
dq::enqueue(viewctr.at, cview());
|
||||||
|
|
||||||
|
while(!dq::drawqueue.empty()) {
|
||||||
|
auto& p = dq::drawqueue.front();
|
||||||
|
heptagon *h = get<0>(p);
|
||||||
|
transmatrix V = get<1>(p);
|
||||||
|
dynamicval<ld> b(band_shift, get<2>(p));
|
||||||
|
bandfixer bf(V);
|
||||||
|
dq::drawqueue.pop();
|
||||||
|
|
||||||
|
cell *c = h->c7;
|
||||||
|
if(!do_draw(c, V)) continue;
|
||||||
|
drawcell(c, V, 0, false);
|
||||||
|
|
||||||
|
for(int i=0; i<S7; i++)
|
||||||
|
dq::enqueue(h->move(i), V * tmatrix[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
|
auto v = getcoord(ispacemap[h2] - ispacemap[h1]);
|
||||||
|
return eupush3(v[0], v[1], v[2]);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hrmap_euclid3* cubemap() {
|
hrmap_euclid3* cubemap() {
|
||||||
@ -571,10 +629,6 @@ namespace euclid3 {
|
|||||||
return new hrmap_euclid3;
|
return new hrmap_euclid3;
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *createStep(heptagon *parent, int d) {
|
|
||||||
return cubemap()->createStep(parent, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pseudohept(cell *c) {
|
bool pseudohept(cell *c) {
|
||||||
coord co = cubemap()->ispacemap[c->master];
|
coord co = cubemap()->ispacemap[c->master];
|
||||||
auto v = getcoord(co);
|
auto v = getcoord(co);
|
||||||
@ -595,34 +649,6 @@ namespace euclid3 {
|
|||||||
else return v[2]/2;
|
else return v[2]/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw() {
|
|
||||||
dq::visited.clear();
|
|
||||||
dq::enqueue(viewctr.at, cview());
|
|
||||||
auto cm = cubemap();
|
|
||||||
|
|
||||||
while(!dq::drawqueue.empty()) {
|
|
||||||
auto& p = dq::drawqueue.front();
|
|
||||||
heptagon *h = get<0>(p);
|
|
||||||
transmatrix V = get<1>(p);
|
|
||||||
dynamicval<ld> b(band_shift, get<2>(p));
|
|
||||||
bandfixer bf(V);
|
|
||||||
dq::drawqueue.pop();
|
|
||||||
|
|
||||||
cell *c = h->c7;
|
|
||||||
if(!do_draw(c, V)) continue;
|
|
||||||
drawcell(c, V, 0, false);
|
|
||||||
|
|
||||||
for(int i=0; i<S7; i++)
|
|
||||||
dq::enqueue(h->move(i), V * cm->tmatrix[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
|
||||||
auto cm = cubemap();
|
|
||||||
auto v = getcoord(cm->ispacemap[h2] - cm->ispacemap[h1]);
|
|
||||||
return eupush3(v[0], v[1], v[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get_emerald(cell *c) {
|
bool get_emerald(cell *c) {
|
||||||
auto v = getcoord(cubemap()->ispacemap[c->master]);
|
auto v = getcoord(cubemap()->ispacemap[c->master]);
|
||||||
int s0 = 0, s1 = 0;
|
int s0 = 0, s1 = 0;
|
||||||
@ -665,4 +691,53 @@ namespace euclid3 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ld matrixnorm(const transmatrix& Mat) {
|
||||||
|
return Mat[0][2] * Mat[0][2] + Mat[1][2] * Mat[1][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void hrmap_euclid_any::draw() {
|
||||||
|
DEBB(DF_GRAPH, (debugfile,"drawEuclidean\n"));
|
||||||
|
sphereflip = Id;
|
||||||
|
if(!centerover.at) centerover = cwt;
|
||||||
|
// printf("centerover = %p player = %p [%d,%d]-[%d,%d]\n", lcenterover, cwt.c,
|
||||||
|
// mindx, mindy, maxdx, maxdy);
|
||||||
|
int pvec = cellwalker_to_vec(centerover);
|
||||||
|
|
||||||
|
typedef pair<int, int> euspot;
|
||||||
|
|
||||||
|
const euspot zero = {0,0};
|
||||||
|
|
||||||
|
set<euspot> visited = {zero};
|
||||||
|
vector<euspot> dfs = {zero};
|
||||||
|
|
||||||
|
ld centerd = matrixnorm(View);
|
||||||
|
auto View0 = View;
|
||||||
|
|
||||||
|
for(int i=0; i<isize(dfs); i++) {
|
||||||
|
int dx, dy;
|
||||||
|
tie(dx, dy) = dfs[i];
|
||||||
|
|
||||||
|
cellwalker cw = vec_to_cellwalker(pvec + euclid_getvec(dx, dy));
|
||||||
|
if(!cw.at) continue;
|
||||||
|
transmatrix Mat = View0 * eumove(dx, dy);
|
||||||
|
torusconfig::torus_cx = dx;
|
||||||
|
torusconfig::torus_cy = dy;
|
||||||
|
|
||||||
|
if(true) {
|
||||||
|
ld locald = matrixnorm(Mat);
|
||||||
|
if(locald < centerd) centerd = locald, centerover = cw, View = Mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(do_draw(cw.at, Mat)) {
|
||||||
|
drawcell(cw.at, cw.mirrored ? Mat * spin(-2*M_PI*cw.spin / cw.at->type) * Mirror : Mat, cw.spin, cw.mirrored);
|
||||||
|
for(int x=-1; x<=+1; x++)
|
||||||
|
for(int y=-1; y<=+1; y++) {
|
||||||
|
euspot p(dx+x, dy+y);
|
||||||
|
if(!visited.count(p)) visited.insert(p), dfs.push_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -535,7 +535,6 @@ void generate_floorshapes() {
|
|||||||
namespace gp {
|
namespace gp {
|
||||||
int pshid[3][8][32][32][8];
|
int pshid[3][8][32][32][8];
|
||||||
int nextid;
|
int nextid;
|
||||||
extern gp::local_info draw_li;
|
|
||||||
|
|
||||||
void clear_plainshapes() {
|
void clear_plainshapes() {
|
||||||
for(int m=0; m<3; m++)
|
for(int m=0; m<3; m++)
|
||||||
|
@ -56,75 +56,17 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, int direction_hint) {
|
|||||||
return calc_relative_matrix(c2, c1, ddspin(c1, direction_hint) * xpush0(1e-2));
|
return calc_relative_matrix(c2, c1, ddspin(c1, direction_hint) * xpush0(1e-2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||||
|
return currentmap->relative_matrix(c2, c1, point_hint);
|
||||||
|
}
|
||||||
|
|
||||||
// target, source, direction from source to target
|
// target, source, direction from source to target
|
||||||
|
|
||||||
#if CAP_GP
|
#if CAP_GP
|
||||||
namespace gp { extern gp::local_info draw_li; }
|
namespace gp { extern gp::local_info draw_li; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||||
|
|
||||||
if(sphere_narcm && DIM == 2) {
|
|
||||||
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
|
|
||||||
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
|
|
||||||
#if CAP_GP
|
|
||||||
auto bak = gp::draw_li;
|
|
||||||
#endif
|
|
||||||
swap(gmatrix, gmatrix0);
|
|
||||||
just_gmatrix = true;
|
|
||||||
drawStandard();
|
|
||||||
just_gmatrix = false;
|
|
||||||
swap(gmatrix, gmatrix0);
|
|
||||||
#if CAP_GP
|
|
||||||
gp::draw_li = bak;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if(gmatrix0.count(c2) && gmatrix0.count(c1)) {
|
|
||||||
transmatrix T = inverse(gmatrix0[c1]) * gmatrix0[c2];
|
|
||||||
if(elliptic && T[2][2] < 0)
|
|
||||||
T = centralsym * T;
|
|
||||||
return T;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("error: gmatrix0 not known\n");
|
|
||||||
return Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CAP_BT
|
|
||||||
if(binarytiling) return binary::relative_matrix(c2->master, c1->master);
|
|
||||||
#endif
|
|
||||||
#if MAXMDIM == 4
|
|
||||||
if(euclid && DIM == 3) return euclid3::relative_matrix(c2->master, c1->master);
|
|
||||||
if(DIM == 3) return reg3::relative_matrix(c2->master, c1->master);
|
|
||||||
#endif
|
|
||||||
#if CAP_ARCM
|
|
||||||
if(archimedean) return arcm::relative_matrix(c2->master, c1->master);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(euwrap) {
|
|
||||||
transmatrix t = Id;
|
|
||||||
// if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));
|
|
||||||
int d = celldistance(c2, c1);
|
|
||||||
while(d) {
|
|
||||||
forCellIdEx(cc, i, c1) {
|
|
||||||
int d1 = celldistance(cc, c2);
|
|
||||||
if(d1 < d) {
|
|
||||||
t = t * cellrelmatrix(c1, i);
|
|
||||||
c1 = cc;
|
|
||||||
d = d1;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("ERROR not reached\n");
|
|
||||||
break;
|
|
||||||
again: ;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(euclid)
|
|
||||||
return eumove(cell_to_vec(c2) - cell_to_vec(c1));
|
|
||||||
|
|
||||||
heptagon *h1 = c1->master;
|
heptagon *h1 = c1->master;
|
||||||
transmatrix gm = master_relative(c1, true);
|
transmatrix gm = master_relative(c1, true);
|
||||||
|
19
graph.cpp
19
graph.cpp
@ -5912,24 +5912,7 @@ void drawthemap() {
|
|||||||
arrowtraps.clear();
|
arrowtraps.clear();
|
||||||
|
|
||||||
profile_start(1);
|
profile_start(1);
|
||||||
if(masterless)
|
currentmap->draw();
|
||||||
drawEuclidean();
|
|
||||||
#if CAP_BT
|
|
||||||
else if(binarytiling)
|
|
||||||
binary::draw();
|
|
||||||
#endif
|
|
||||||
#if CAP_ARCM
|
|
||||||
else if(archimedean)
|
|
||||||
arcm::draw();
|
|
||||||
#endif
|
|
||||||
#if MAXMDIM == 4
|
|
||||||
else if(euclid && DIM == 3)
|
|
||||||
euclid3::draw();
|
|
||||||
else if(DIM == 3)
|
|
||||||
reg3::draw();
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
drawStandard();
|
|
||||||
drawWormSegments();
|
drawWormSegments();
|
||||||
drawBlizzards();
|
drawBlizzards();
|
||||||
drawArrowTraps();
|
drawArrowTraps();
|
||||||
|
32
heptagon.cpp
32
heptagon.cpp
@ -217,32 +217,12 @@ hookset<void(heptagon*, int)> *hooks_createStep;
|
|||||||
|
|
||||||
heptagon *createStep(heptagon *h, int d) {
|
heptagon *createStep(heptagon *h, int d) {
|
||||||
d = h->c.fix(d);
|
d = h->c.fix(d);
|
||||||
if(!h->move(d))
|
if(h->move(d)) return h->move(d);
|
||||||
callhooks(hooks_createStep, h, d);
|
callhooks(hooks_createStep, h, d);
|
||||||
#if CAP_CRYSTAL
|
return currentmap->create_step(h, d);
|
||||||
if(!h->move(d) && geometry == gCrystal)
|
}
|
||||||
crystal::create_step(h, d);
|
|
||||||
#endif
|
heptagon *hrmap_standard::create_step(heptagon *h, int d) {
|
||||||
#if CAP_BT
|
|
||||||
if(!h->move(d) && binarytiling && DIM == 2)
|
|
||||||
return binary::createStep(h, d);
|
|
||||||
#endif
|
|
||||||
#if CAP_BT && MAXMDIM == 4
|
|
||||||
if(!h->move(d) && binarytiling && DIM == 3)
|
|
||||||
return binary::createStep3(h, d);
|
|
||||||
#endif
|
|
||||||
#if MAXMDIM == 4
|
|
||||||
if(!h->move(d) && euclid && DIM == 3)
|
|
||||||
return euclid3::createStep(h, d);
|
|
||||||
if(!h->move(d) && DIM == 3)
|
|
||||||
return reg3::createStep(h, d);
|
|
||||||
#endif
|
|
||||||
#if CAP_ARCM
|
|
||||||
if(!h->move(d) && archimedean) {
|
|
||||||
arcm::create_adjacent(h, d);
|
|
||||||
return h->move(d);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(!h->move(0) && h->s != hsOrigin && !binarytiling && (geometry != gCrystal)) {
|
if(!h->move(0) && h->s != hsOrigin && !binarytiling && (geometry != gCrystal)) {
|
||||||
// cheating:
|
// cheating:
|
||||||
int pard=0;
|
int pard=0;
|
||||||
|
57
hyper.h
57
hyper.h
@ -3032,8 +3032,6 @@ namespace princess {
|
|||||||
|
|
||||||
int eudist(int sx, int sy);
|
int eudist(int sx, int sy);
|
||||||
|
|
||||||
heptagon *createStep(heptagon *h, int d);
|
|
||||||
|
|
||||||
cell *createMovR(cell *c, int d);
|
cell *createMovR(cell *c, int d);
|
||||||
|
|
||||||
bool ishept(cell *c);
|
bool ishept(cell *c);
|
||||||
@ -3050,20 +3048,48 @@ struct hrmap {
|
|||||||
virtual ~hrmap() { };
|
virtual ~hrmap() { };
|
||||||
virtual vector<cell*>& allcells() { return dcal; }
|
virtual vector<cell*>& allcells() { return dcal; }
|
||||||
virtual void verify() { }
|
virtual void verify() { }
|
||||||
|
virtual void link_alt(const cellwalker& hs) { }
|
||||||
|
virtual void generateAlts(heptagon *h, int levs = IRREGULAR ? 1 : S3-3, bool link_cdata = true);
|
||||||
|
heptagon *may_create_step(heptagon *h, int direction) {
|
||||||
|
if(h->move(direction)) return h->move(direction);
|
||||||
|
return create_step(h, direction);
|
||||||
|
}
|
||||||
|
virtual heptagon *create_step(heptagon *h, int direction) {
|
||||||
|
printf("create_step called unexpectedly\n"); exit(1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
virtual transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
|
printf("relative_matrix called unexpectedly\n");
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
virtual transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||||
|
return relative_matrix(c2->master, c1->master);
|
||||||
|
}
|
||||||
|
virtual void draw() {
|
||||||
|
printf("undrawable\n");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hrmap_hyperbolic : hrmap {
|
// hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient
|
||||||
|
struct hrmap_standard : hrmap {
|
||||||
|
void draw() override;
|
||||||
|
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override;
|
||||||
|
heptagon *create_step(heptagon *h, int direction) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hrmap_hyperbolic : hrmap_standard {
|
||||||
heptagon *origin;
|
heptagon *origin;
|
||||||
eVariation mvar;
|
eVariation mvar;
|
||||||
hrmap_hyperbolic();
|
hrmap_hyperbolic();
|
||||||
heptagon *getOrigin() { return origin; }
|
hrmap_hyperbolic(heptagon *origin);
|
||||||
|
heptagon *getOrigin() override { return origin; }
|
||||||
~hrmap_hyperbolic() {
|
~hrmap_hyperbolic() {
|
||||||
DEBMEM ( verifycells(origin); )
|
DEBMEM ( verifycells(origin); )
|
||||||
// printf("Deleting hyperbolic map: %p\n", this);
|
// printf("Deleting hyperbolic map: %p\n", this);
|
||||||
dynamicval<eVariation> ph(variation, mvar);
|
dynamicval<eVariation> ph(variation, mvar);
|
||||||
clearfrom(origin);
|
clearfrom(origin);
|
||||||
}
|
}
|
||||||
void verify() { verifycells(origin); }
|
void verify() override { verifycells(origin); }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace irr {
|
namespace irr {
|
||||||
@ -3671,6 +3697,8 @@ namespace gp {
|
|||||||
int first_dir;
|
int first_dir;
|
||||||
int total_dir;
|
int total_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern local_info draw_li;
|
||||||
|
|
||||||
local_info get_local_info(cell *c);
|
local_info get_local_info(cell *c);
|
||||||
const char *disp(loc at);
|
const char *disp(loc at);
|
||||||
@ -4063,7 +4091,6 @@ void queuestr(const hyperpoint& h, int size, const string& chr, color_t col, int
|
|||||||
void queuechr(const transmatrix& V, double size, char chr, color_t col, int frame = 0);
|
void queuechr(const transmatrix& V, double size, char chr, color_t col, int frame = 0);
|
||||||
|
|
||||||
extern bool just_gmatrix;
|
extern bool just_gmatrix;
|
||||||
void drawStandard();
|
|
||||||
|
|
||||||
bool haveLeaderboard(int id);
|
bool haveLeaderboard(int id);
|
||||||
int get_currentscore(int id);
|
int get_currentscore(int id);
|
||||||
@ -4231,8 +4258,6 @@ extern void switchHardcore();
|
|||||||
|
|
||||||
extern bool shaderside_projection;
|
extern bool shaderside_projection;
|
||||||
|
|
||||||
void generateAlts(heptagon *h, int levs = IRREGULAR ? 1 : S3-3, bool link_cdata = true);
|
|
||||||
|
|
||||||
namespace ors {
|
namespace ors {
|
||||||
extern int mode;
|
extern int mode;
|
||||||
extern string choices[];
|
extern string choices[];
|
||||||
@ -4256,20 +4281,16 @@ hyperpoint get_horopoint(ld y, ld x);
|
|||||||
hyperpoint get_horopoint3(ld y, ld x, ld z);
|
hyperpoint get_horopoint3(ld y, ld x, ld z);
|
||||||
|
|
||||||
namespace binary {
|
namespace binary {
|
||||||
heptagon *createStep(heptagon *parent, int d);
|
|
||||||
#if MAXMDIM == 4
|
|
||||||
heptagon *createStep3(heptagon *parent, int d);
|
|
||||||
#endif
|
|
||||||
transmatrix parabolic(ld u);
|
transmatrix parabolic(ld u);
|
||||||
transmatrix parabolic3(ld u, ld v);
|
transmatrix parabolic3(ld u, ld v);
|
||||||
extern ld btrange, btrange_cosh;
|
extern ld btrange, btrange_cosh;
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1);
|
hrmap *new_map();
|
||||||
|
hrmap *new_alt_map(heptagon *o);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MAXMDIM == 4
|
#if MAXMDIM == 4
|
||||||
namespace euclid3 {
|
namespace euclid3 {
|
||||||
heptagon *createStep(heptagon *parent, int d);
|
|
||||||
hrmap* new_map();
|
hrmap* new_map();
|
||||||
void draw();
|
void draw();
|
||||||
}
|
}
|
||||||
@ -4277,11 +4298,7 @@ namespace euclid3 {
|
|||||||
namespace reg3 {
|
namespace reg3 {
|
||||||
void generate();
|
void generate();
|
||||||
hrmap* new_map();
|
hrmap* new_map();
|
||||||
heptagon *createStep(heptagon *parent, int d);
|
|
||||||
extern vector<hyperpoint> cellshape;
|
extern vector<hyperpoint> cellshape;
|
||||||
void draw();
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1);
|
|
||||||
int dist_alt(cell *c);
|
|
||||||
int celldistance(cell *c1, cell *c2);
|
int celldistance(cell *c1, cell *c2);
|
||||||
bool pseudohept(cell *c);
|
bool pseudohept(cell *c);
|
||||||
}
|
}
|
||||||
@ -4357,10 +4374,7 @@ namespace arcm {
|
|||||||
extern map<heptagon*, pair<heptagon*, transmatrix>> archimedean_gmatrix;
|
extern map<heptagon*, pair<heptagon*, transmatrix>> archimedean_gmatrix;
|
||||||
|
|
||||||
void initialize(heptagon *root);
|
void initialize(heptagon *root);
|
||||||
transmatrix relative_matrix(heptagon *h1, heptagon *h2);
|
|
||||||
short& id_of(heptagon *);
|
short& id_of(heptagon *);
|
||||||
void draw();
|
|
||||||
void create_adjacent(heptagon*, int);
|
|
||||||
int fix(heptagon *h, int spin);
|
int fix(heptagon *h, int spin);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -4385,7 +4399,6 @@ namespace crystal {
|
|||||||
int precise_distance(cell *c1, cell *c2);
|
int precise_distance(cell *c1, cell *c2);
|
||||||
ld space_distance(cell *c1, cell *c2);
|
ld space_distance(cell *c1, cell *c2);
|
||||||
hrmap *new_map();
|
hrmap *new_map();
|
||||||
void create_step(heptagon *h, int d);
|
|
||||||
void build_rugdata();
|
void build_rugdata();
|
||||||
void apply_rotation(const transmatrix t);
|
void apply_rotation(const transmatrix t);
|
||||||
void switch_z_coordinate();
|
void switch_z_coordinate();
|
||||||
|
62
hypgraph.cpp
62
hypgraph.cpp
@ -839,7 +839,7 @@ void drawrec(cell *c, const transmatrix& V) {
|
|||||||
|
|
||||||
vector<tuple<heptspin, hstate, transmatrix, ld> > drawn_cells;
|
vector<tuple<heptspin, hstate, transmatrix, ld> > drawn_cells;
|
||||||
|
|
||||||
void drawStandard() {
|
void hrmap_standard::draw() {
|
||||||
drawn_cells.clear();
|
drawn_cells.clear();
|
||||||
drawn_cells.emplace_back(viewctr, hsOrigin, cview(), band_shift);
|
drawn_cells.emplace_back(viewctr, hsOrigin, cview(), band_shift);
|
||||||
for(int i=0; i<isize(drawn_cells); i++) {
|
for(int i=0; i<isize(drawn_cells); i++) {
|
||||||
@ -969,54 +969,6 @@ transmatrix eumovedir(int d) {
|
|||||||
return eumove(0,0);
|
return eumove(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ld matrixnorm(const transmatrix& Mat) {
|
|
||||||
return Mat[0][2] * Mat[0][2] + Mat[1][2] * Mat[1][2];
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawEuclidean() {
|
|
||||||
DEBB(DF_GRAPH, (debugfile,"drawEuclidean\n"));
|
|
||||||
sphereflip = Id;
|
|
||||||
if(!centerover.at) centerover = cwt;
|
|
||||||
// printf("centerover = %p player = %p [%d,%d]-[%d,%d]\n", lcenterover, cwt.c,
|
|
||||||
// mindx, mindy, maxdx, maxdy);
|
|
||||||
int pvec = cellwalker_to_vec(centerover);
|
|
||||||
|
|
||||||
typedef pair<int, int> euspot;
|
|
||||||
|
|
||||||
const euspot zero = {0,0};
|
|
||||||
|
|
||||||
set<euspot> visited = {zero};
|
|
||||||
vector<euspot> dfs = {zero};
|
|
||||||
|
|
||||||
ld centerd = matrixnorm(View);
|
|
||||||
auto View0 = View;
|
|
||||||
|
|
||||||
for(int i=0; i<isize(dfs); i++) {
|
|
||||||
int dx, dy;
|
|
||||||
tie(dx, dy) = dfs[i];
|
|
||||||
|
|
||||||
cellwalker cw = vec_to_cellwalker(pvec + euclid_getvec(dx, dy));
|
|
||||||
if(!cw.at) continue;
|
|
||||||
transmatrix Mat = View0 * eumove(dx, dy);
|
|
||||||
torusconfig::torus_cx = dx;
|
|
||||||
torusconfig::torus_cy = dy;
|
|
||||||
|
|
||||||
if(true) {
|
|
||||||
ld locald = matrixnorm(Mat);
|
|
||||||
if(locald < centerd) centerd = locald, centerover = cw, View = Mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(do_draw(cw.at, Mat)) {
|
|
||||||
drawcell(cw.at, cw.mirrored ? Mat * spin(-2*M_PI*cw.spin / cw.at->type) * Mirror : Mat, cw.spin, cw.mirrored);
|
|
||||||
for(int x=-1; x<=+1; x++)
|
|
||||||
for(int y=-1; y<=+1; y++) {
|
|
||||||
euspot p(dx+x, dy+y);
|
|
||||||
if(!visited.count(p)) visited.insert(p), dfs.push_back(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void spinEdge(ld aspd) {
|
void spinEdge(ld aspd) {
|
||||||
|
|
||||||
if(playerfound && vid.fixed_facing) {
|
if(playerfound && vid.fixed_facing) {
|
||||||
@ -1127,17 +1079,7 @@ void optimizeview() {
|
|||||||
for(int i=0; i<viewctr.at->c7->type; i++) {
|
for(int i=0; i<viewctr.at->c7->type; i++) {
|
||||||
int i1 = i * DUALMUL;
|
int i1 = i * DUALMUL;
|
||||||
heptagon *h2 = createStep(viewctr.at, i1);
|
heptagon *h2 = createStep(viewctr.at, i1);
|
||||||
transmatrix T;
|
transmatrix T = currentmap->relative_matrix(h2, viewctr.at);
|
||||||
#if CAP_BT
|
|
||||||
if(binarytiling) T = binary::relative_matrix(h2, viewctr.at);
|
|
||||||
#endif
|
|
||||||
#if MAXMDIM == 4
|
|
||||||
else if(euclid && DIM == 3) T = euclid3::relative_matrix(h2, viewctr.at);
|
|
||||||
else if(DIM == 3) T = reg3::relative_matrix(h2, viewctr.at);
|
|
||||||
#endif
|
|
||||||
#if CAP_ARCM
|
|
||||||
if(archimedean) T = arcm::relative_matrix(h2, viewctr.at);
|
|
||||||
#endif
|
|
||||||
hyperpoint H = View * tC0(T);
|
hyperpoint H = View * tC0(T);
|
||||||
ld quality = hdist0(H);
|
ld quality = hdist0(H);
|
||||||
if(quality < best) best = quality, turn = i1, TB = T;
|
if(quality < best) best = quality, turn = i1, TB = T;
|
||||||
|
@ -718,7 +718,7 @@ void compute_horocycle(heptagon *alt) {
|
|||||||
set<heptagon*> region;
|
set<heptagon*> region;
|
||||||
for(int i=0; i<LOOKUP-1; i++) {
|
for(int i=0; i<LOOKUP-1; i++) {
|
||||||
for(auto h: hs[i]) {
|
for(auto h: hs[i]) {
|
||||||
generateAlts(h);
|
currentmap->generateAlts(h);
|
||||||
for(int j=0; j<S7; j++) {
|
for(int j=0; j<S7; j++) {
|
||||||
if(h->move(j)->alt->alt != master->alt->alt) continue;
|
if(h->move(j)->alt->alt != master->alt->alt) continue;
|
||||||
region.insert(h->move(j));
|
region.insert(h->move(j));
|
||||||
@ -789,7 +789,7 @@ int celldist(cell *c, bool alts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(doalts == 0) {
|
if(doalts == 0) {
|
||||||
generateAlts(master);
|
currentmap->generateAlts(master);
|
||||||
for(int i=0; i<S7; i++) if(master->move(i)->alt == master->alt->move[0] && periodmap[master->move(i)].celldists[true].empty())
|
for(int i=0; i<S7; i++) if(master->move(i)->alt == master->alt->move[0] && periodmap[master->move(i)].celldists[true].empty())
|
||||||
compute_horocycle(master);
|
compute_horocycle(master);
|
||||||
}
|
}
|
||||||
|
@ -1514,7 +1514,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
|||||||
if(fargen) {
|
if(fargen) {
|
||||||
if(!eubinary) {
|
if(!eubinary) {
|
||||||
if(c->master->alt && c->master->alt->distance <= 2) {
|
if(c->master->alt && c->master->alt->distance <= 2) {
|
||||||
if(!eubinary) generateAlts(c->master);
|
if(!eubinary) currentmap->generateAlts(c->master);
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
if(d <= 0)
|
if(d <= 0)
|
||||||
|
@ -38,7 +38,7 @@ namespace quotientspace {
|
|||||||
|
|
||||||
int rv(int x) { return (rvadd+x*rvdir) % S7; }
|
int rv(int x) { return (rvadd+x*rvdir) % S7; }
|
||||||
|
|
||||||
struct hrmap_quotient : hrmap {
|
struct hrmap_quotient : hrmap_standard {
|
||||||
|
|
||||||
hrmap_hyperbolic base;
|
hrmap_hyperbolic base;
|
||||||
|
|
||||||
@ -64,6 +64,8 @@ struct hrmap_quotient : hrmap {
|
|||||||
|
|
||||||
hrmap_quotient() {
|
hrmap_quotient() {
|
||||||
|
|
||||||
|
dynamicval<hrmap*> cmap(currentmap, this);
|
||||||
|
|
||||||
static int symmask = (1<<30);
|
static int symmask = (1<<30);
|
||||||
|
|
||||||
connections.clear();
|
connections.clear();
|
||||||
@ -350,7 +352,7 @@ struct hrmap_quotient : hrmap {
|
|||||||
for(int i=0; i<TOT; i++) {
|
for(int i=0; i<TOT; i++) {
|
||||||
if(i >= isize(by_dist)) { printf("too fast\n"); exit(1); }
|
if(i >= isize(by_dist)) { printf("too fast\n"); exit(1); }
|
||||||
for(int a=0; a<S7; a++) if(by_dist[i]->move(a)->alt == NULL) by_dist.push_back(by_dist[i]->move(a));
|
for(int a=0; a<S7; a++) if(by_dist[i]->move(a)->alt == NULL) by_dist.push_back(by_dist[i]->move(a));
|
||||||
generateAlts(by_dist[i], 0, false);
|
currentmap->generateAlts(by_dist[i], 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<TOT; i++) {
|
for(int i=0; i<TOT; i++) {
|
||||||
|
102
reg3.cpp
102
reg3.cpp
@ -196,9 +196,10 @@ namespace reg3 {
|
|||||||
alt->distance = 0;
|
alt->distance = 0;
|
||||||
alt->alt = alt;
|
alt->alt = alt;
|
||||||
alt->cdata = NULL;
|
alt->cdata = NULL;
|
||||||
binary_map = newAltMap(alt);
|
binary_map = binary::new_alt_map(alt);
|
||||||
T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * cspin(0, 2, 1.1249) * xpush(0.07) * Id;
|
T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * cspin(0, 2, 1.1249) * xpush(0.07) * Id;
|
||||||
}
|
}
|
||||||
|
else binary_map = NULL;
|
||||||
|
|
||||||
reg_gmatrix[origin] = make_pair(alt, T);
|
reg_gmatrix[origin] = make_pair(alt, T);
|
||||||
altmap[alt].emplace_back(origin, T);
|
altmap[alt].emplace_back(origin, T);
|
||||||
@ -218,7 +219,7 @@ namespace reg3 {
|
|||||||
|
|
||||||
#define DEB 0
|
#define DEB 0
|
||||||
|
|
||||||
heptagon *createStep(heptagon *parent, int d) {
|
heptagon *create_step(heptagon *parent, int d) {
|
||||||
auto& p1 = reg_gmatrix[parent];
|
auto& p1 = reg_gmatrix[parent];
|
||||||
if(DEB) println(hlog, "creating step ", parent, ":", d, ", at ", p1.first, tC0(p1.second));
|
if(DEB) println(hlog, "creating step ", parent, ":", d, ", at ", p1.first, tC0(p1.second));
|
||||||
heptagon *alt = p1.first;
|
heptagon *alt = p1.first;
|
||||||
@ -226,6 +227,7 @@ namespace reg3 {
|
|||||||
transmatrix T1 = T;
|
transmatrix T1 = T;
|
||||||
if(hyperbolic) {
|
if(hyperbolic) {
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
|
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||||
binary::virtualRebaseSimple(alt, T);
|
binary::virtualRebaseSimple(alt, T);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +279,53 @@ namespace reg3 {
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~hrmap_reg3() {
|
||||||
|
if(binary_map) delete binary_map;
|
||||||
|
clearfrom(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateAlts(heptagon* h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
sphereflip = Id;
|
||||||
|
|
||||||
|
// for(int i=0; i<S6; i++) queuepoly(ggmatrix(cwt.at), shWall3D[i], 0xFF0000FF);
|
||||||
|
|
||||||
|
dq::visited.clear();
|
||||||
|
dq::enqueue(viewctr.at, cview());
|
||||||
|
|
||||||
|
while(!dq::drawqueue.empty()) {
|
||||||
|
auto& p = dq::drawqueue.front();
|
||||||
|
heptagon *h = get<0>(p);
|
||||||
|
transmatrix V = get<1>(p);
|
||||||
|
dynamicval<ld> b(band_shift, get<2>(p));
|
||||||
|
bandfixer bf(V);
|
||||||
|
dq::drawqueue.pop();
|
||||||
|
|
||||||
|
|
||||||
|
cell *c = h->c7;
|
||||||
|
if(!do_draw(c, V)) continue;
|
||||||
|
drawcell(c, V, 0, false);
|
||||||
|
|
||||||
|
for(int i=0; i<S7; i++)
|
||||||
|
if(h->move(i))
|
||||||
|
dq::enqueue(h->move(i), V * relative_matrix(h->move(i), h));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
|
auto p1 = reg_gmatrix[h1];
|
||||||
|
auto p2 = reg_gmatrix[h2];
|
||||||
|
transmatrix T = Id;
|
||||||
|
if(hyperbolic) {
|
||||||
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
|
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||||
|
T = binary_map->relative_matrix(p2.first, p1.first);
|
||||||
|
}
|
||||||
|
return inverse(p1.second) * T * p2.second;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hrmap* new_map() {
|
hrmap* new_map() {
|
||||||
@ -287,54 +336,12 @@ hrmap_reg3* regmap() {
|
|||||||
return ((hrmap_reg3*) currentmap);
|
return ((hrmap_reg3*) currentmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *createStep(heptagon *parent, int d) {
|
|
||||||
return regmap()->createStep(parent, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
|
||||||
auto m = regmap();
|
|
||||||
auto p1 = m->reg_gmatrix[h1];
|
|
||||||
auto p2 = m->reg_gmatrix[h2];
|
|
||||||
transmatrix T = Id;
|
|
||||||
if(hyperbolic) {
|
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
|
||||||
T = binary::relative_matrix(p2.first, p1.first);
|
|
||||||
}
|
|
||||||
return inverse(p1.second) * T * p2.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
sphereflip = Id;
|
|
||||||
|
|
||||||
// for(int i=0; i<S6; i++) queuepoly(ggmatrix(cwt.at), shWall3D[i], 0xFF0000FF);
|
|
||||||
|
|
||||||
dq::visited.clear();
|
|
||||||
dq::enqueue(viewctr.at, cview());
|
|
||||||
|
|
||||||
while(!dq::drawqueue.empty()) {
|
|
||||||
auto& p = dq::drawqueue.front();
|
|
||||||
heptagon *h = get<0>(p);
|
|
||||||
transmatrix V = get<1>(p);
|
|
||||||
dynamicval<ld> b(band_shift, get<2>(p));
|
|
||||||
bandfixer bf(V);
|
|
||||||
dq::drawqueue.pop();
|
|
||||||
|
|
||||||
|
|
||||||
cell *c = h->c7;
|
|
||||||
if(!do_draw(c, V)) continue;
|
|
||||||
drawcell(c, V, 0, false);
|
|
||||||
|
|
||||||
for(int i=0; i<S7; i++)
|
|
||||||
dq::enqueue(h->move(i), V * relative_matrix(h->move(i), h));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int celldistance(cell *c1, cell *c2) {
|
int celldistance(cell *c1, cell *c2) {
|
||||||
if(c1 == c2) return 0;
|
if(c1 == c2) return 0;
|
||||||
|
|
||||||
auto r = regmap();
|
auto r = regmap();
|
||||||
|
|
||||||
hyperpoint h = tC0(relative_matrix(c1->master, c2->master));
|
hyperpoint h = tC0(r->relative_matrix(c1->master, c2->master));
|
||||||
int b = bucketer(h);
|
int b = bucketer(h);
|
||||||
if(close_distances.count(b)) return close_distances[b];
|
if(close_distances.count(b)) return close_distances[b];
|
||||||
|
|
||||||
@ -343,8 +350,9 @@ int celldistance(cell *c1, cell *c2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool pseudohept(cell *c) {
|
bool pseudohept(cell *c) {
|
||||||
|
auto m = regmap();
|
||||||
if(sphere) {
|
if(sphere) {
|
||||||
hyperpoint h = tC0(relative_matrix(c->master, regmap()->origin));
|
hyperpoint h = tC0(m->relative_matrix(c->master, regmap()->origin));
|
||||||
if(S7 == 12) {
|
if(S7 == 12) {
|
||||||
hyperpoint h1 = cspin(0, 1, atan2(16, 69) + M_PI/4) * h;
|
hyperpoint h1 = cspin(0, 1, atan2(16, 69) + M_PI/4) * h;
|
||||||
for(int i=0; i<4; i++) if(abs(abs(h1[i]) - .5) > .01) return false;
|
for(int i=0; i<4; i++) if(abs(abs(h1[i]) - .5) > .01) return false;
|
||||||
@ -353,7 +361,7 @@ bool pseudohept(cell *c) {
|
|||||||
if(S7 == 8)
|
if(S7 == 8)
|
||||||
return h[3] >= .99 || h[3] <= -.99 || abs(h[3]) < .01;
|
return h[3] >= .99 || h[3] <= -.99 || abs(h[3]) < .01;
|
||||||
if(loop == 3 && face == 3 && S7 == 4)
|
if(loop == 3 && face == 3 && S7 == 4)
|
||||||
return c == currentmap->gamestart();
|
return c == m->gamestart();
|
||||||
if(loop == 4 && face == 3)
|
if(loop == 4 && face == 3)
|
||||||
return abs(h[3]) > .9;
|
return abs(h[3]) > .9;
|
||||||
if(loop == 3 && face == 4)
|
if(loop == 3 && face == 4)
|
||||||
|
@ -60,8 +60,7 @@ void recursive_delete(heptagon *h, int i) {
|
|||||||
if(h2->alt && h2->alt->alt == h2->alt) {
|
if(h2->alt && h2->alt->alt == h2->alt) {
|
||||||
DEBSM(printf("destroying alternate map %p\n", h2->alt);)
|
DEBSM(printf("destroying alternate map %p\n", h2->alt);)
|
||||||
for(hrmap *& hm: allmaps) {
|
for(hrmap *& hm: allmaps) {
|
||||||
auto hm2 = dynamic_cast<hrmap_alternate*> (hm);
|
if(hm->getOrigin() == h2->alt) {
|
||||||
if(hm2 && hm2->origin == h2->alt) {
|
|
||||||
delete hm;
|
delete hm;
|
||||||
hm = allmaps.back();
|
hm = allmaps.back();
|
||||||
allmaps.pop_back();
|
allmaps.pop_back();
|
||||||
|
29
sphere.cpp
29
sphere.cpp
@ -17,7 +17,7 @@ int spherecells() {
|
|||||||
|
|
||||||
vector<int> siblings;
|
vector<int> siblings;
|
||||||
|
|
||||||
struct hrmap_spherical : hrmap {
|
struct hrmap_spherical : hrmap_standard {
|
||||||
heptagon *dodecahedron[12];
|
heptagon *dodecahedron[12];
|
||||||
eVariation mvar;
|
eVariation mvar;
|
||||||
|
|
||||||
@ -156,6 +156,33 @@ struct hrmap_spherical : hrmap {
|
|||||||
}
|
}
|
||||||
for(int i=0; i<spherecells(); i++) verifycells(dodecahedron[i]);
|
for(int i=0; i<spherecells(); i++) verifycells(dodecahedron[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||||
|
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
|
||||||
|
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
|
||||||
|
#if CAP_GP
|
||||||
|
auto bak = gp::draw_li;
|
||||||
|
#endif
|
||||||
|
swap(gmatrix, gmatrix0);
|
||||||
|
just_gmatrix = true;
|
||||||
|
draw();
|
||||||
|
just_gmatrix = false;
|
||||||
|
swap(gmatrix, gmatrix0);
|
||||||
|
#if CAP_GP
|
||||||
|
gp::draw_li = bak;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if(gmatrix0.count(c2) && gmatrix0.count(c1)) {
|
||||||
|
transmatrix T = inverse(gmatrix0[c1]) * gmatrix0[c2];
|
||||||
|
if(elliptic && T[2][2] < 0)
|
||||||
|
T = centralsym * T;
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("error: gmatrix0 not known\n");
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
heptagon *getDodecahedron(int i) {
|
heptagon *getDodecahedron(int i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user