1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-23 21:07:17 +00:00

arcm:: digons

This commit is contained in:
Zeno Rogue 2018-08-21 04:24:14 +02:00
parent 598cbc5f2f
commit 903fd179d9
2 changed files with 80 additions and 27 deletions

View File

@ -49,7 +49,9 @@ struct archimedean_tiling {
string errormsg;
pair<int, int>& get_adj(heptagon *h, int cid);
pair<int, int>& get_adj(heptspin hs) { return get_adj(hs.at, hs.spin); }
pair<ld, ld>& get_triangle(heptagon *h, int cid);
pair<ld, ld>& get_triangle(heptspin hs) { return get_triangle(hs.at, hs.spin); }
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0);
pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0);
@ -112,7 +114,7 @@ void archimedean_tiling::prepare() {
errors++;
return;
}
for(int i: faces) if(i < 3) {
for(int i: faces) if(i < 2) {
errormsg = XLAT("not enough edges");
errors++;
return;
@ -260,12 +262,21 @@ void archimedean_tiling::compute_geometry() {
alphas.resize(N);
ld elmin = 0, elmax = hyperbolic ? 10 : sphere ? M_PI : 1;
if(N == 2) {
int real_faces = 0;
int rf = 0;
for(int i=0; i<N; i++) if(faces[i] > 2) real_faces++, rf += faces[i];
if(real_faces == 2) {
/* standard methods fail, but the answer is easy */
edgelength = 2 * M_PI / faces[0];
for(int i=0; i<2; i++)
alphas[i] = M_PI/2,
circumradius[i] = inradius[i] = M_PI/2;
for(int i=0; i<N; i++)
if(faces[i] == 2)
alphas[i] = 0,
circumradius[i] = 2 * M_PI / rf,
inradius[i] = 0;
else
alphas[i] = M_PI/2,
circumradius[i] = inradius[i] = M_PI/2;
}
else for(int p=0; p<100; p++) {
edgelength = (elmin + elmax) / 2;
@ -370,6 +381,13 @@ struct hrmap_archimedean : hrmap {
archimedean_gmatrix[origin] = make_pair(alt, T);
altmap[alt].emplace_back(origin, T);
if(origin->c7->type == 2) {
create_adjacent(origin, 0);
create_adjacent(origin, 1);
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);
}
base_distlimit = 0;
celllister cl(origin->c7, 1000, 200, NULL);
base_distlimit = cl.dists.back();
@ -393,28 +411,47 @@ hrmap *new_map() { return new hrmap_archimedean; }
transmatrix adjcell_matrix(heptagon *h, int d);
heptagon *build_child(heptagon *parent, int d, int id, int pindex) {
heptagon *build_child(heptspin p, pair<int, int> adj) {
indenter ind;
auto h = buildHeptagon1(new heptagon, parent, d, hstate(1), 0);
SDEBUG( printf("NEW %p.%d ~ %p.0\n", parent, d, h); )
id_of(h) = id;
parent_index_of(h) = pindex;
auto h = buildHeptagon1(new heptagon, p.at, p.spin, hstate(1), 0);
SDEBUG( printf("NEW %p.%d ~ %p.0\n", p.at, p.spin, h); )
id_of(h) = adj.first;
parent_index_of(h) = adj.second;
int nei = neighbors_of(h);
h->c7 = newCell(nei, h);
h->distance = parent->distance + 1;
if(id < 2*current.N)
h->fieldval = parent->move(0)->fieldval + (d/2);
h->distance = p.at->distance + 1;
if(adj.first < 2*current.N)
h->fieldval = p.at->move(0)->fieldval + (adj.second/2);
h->fiftyval = isize(archimedean_gmatrix);
heptspin hs(h, 0);
return h;
}
void connectHeptagons(heptagon *h, int i, heptspin hs) {
SDEBUG( printf("OLD %p.%d ~ %p.%d\n", h, i, hs.at, hs.spin); )
if(h->move(i) == hs.at && h->c.spin(i) == hs.spin) {
bool skip_digons(heptspin hs, int step) {
return
isize(current.adjacent[current.get_adj(hs).first]) == 2 ||
isize(current.adjacent[current.get_adj(hs+step).first]) == 2;
}
void connect_digons_too(heptspin h1, heptspin h2) {
if(skip_digons(h1, -1)) {
h1--, h2++;
heptagon *hnew = build_child(h1, current.get_adj(h1));
// no need to specify archimedean_gmatrix and altmap
hnew->c.connect(1, h2);
h1--, h2++;
SDEBUG( printf("OL2 %p.%d ~ %p.%d\n", h1.at, h1.spin, h2.at, h2.spin); )
h1.at->c.connect(h1.spin, h2);
}
}
void connectHeptagons(heptspin hi, heptspin hs) {
SDEBUG( printf("OLD %p.%d ~ %p.%d\n", hi.at, hi.spin, hs.at, hs.spin); )
if(hi.at->move(hi.spin) == hs.at && hi.at->c.spin(hi.spin) == hs.spin) {
SDEBUG( printf("WARNING: already connected\n"); )
return;
}
if(h->move(i)) {
if(hi.peek()) {
SDEBUG( printf("ERROR: already connected left\n"); )
exit(1);
}
@ -422,9 +459,9 @@ void connectHeptagons(heptagon *h, int i, heptspin hs) {
SDEBUG( printf("ERROR: already connected right\n"); )
exit(1);
}
h->c.connect(i, hs);
hi.at->c.connect(hi.spin, hs);
auto p = current.get_adj(h, i);
auto p = current.get_adj(hi);
if(current.tilegroup[p.first] != current.tilegroup[id_of(hs.at)])
printf("should merge %d %d\n", p.first, id_of(hs.at));
// heptagon *hnew = build_child(h, d, get_adj(h, d).first, get_adj(h, d).second);
@ -434,7 +471,11 @@ void create_adjacent(heptagon *h, int d) {
SDEBUG( printf("%p.%d ~ ?\n", h, d); )
auto& t1 = current.get_triangle(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)
@ -454,28 +495,32 @@ void create_adjacent(heptagon *h, int d) {
SDEBUG( printf("look for: %p / %s\n", alt, display(T * C0)); )
for(auto& p: altmap[alt]) if(intval(p.second * C0, T * C0) < 1e-6) {
for(auto& p: altmap[alt]) if(intval(p.second * C0, T * C0) < 1e-4) {
SDEBUG( printf("cell found: %p\n", p.first); )
for(int d2=0; d2<p.first->c7->type; d2++) {
heptspin hs(p.first, d2);
auto& t2 = current.get_triangle(p.first, d2);
transmatrix T1 = T * spin(M_PI + t2.first);
SDEBUG( printf("compare: %s", display(T1 * xpush0(1))); )
SDEBUG( printf(":: %s\n", display(p.second * xpush0(1))); )
if(intval(T1 * xpush0(1), p.second * xpush0(1)) < 1e-6) {
connectHeptagons(h, d, heptspin(p.first, d2));
if(intval(T1 * xpush0(1), p.second * xpush0(1)) < 1e-4) {
while(skip_digons(hs, -1)) hs--;
connectHeptagons(hi, hs);
connect_digons_too(hi, hs);
return;
}
}
SDEBUG( printf("but rotation not found\n"));
}
auto& t2 = current.get_triangle(current.get_adj(h, d));
auto& t2 = current.get_triangle(current.get_adj(hi));
transmatrix T1 = T * spin(M_PI + t2.first);
fixmatrix(T1);
heptagon *hnew = build_child(h, d, current.get_adj(h, d).first, current.get_adj(h, d).second);
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));
}
set<heptagon*> visited;
@ -744,6 +789,9 @@ vector<string> samples = {
"(3,5,5,5,5,5) (0 1)(2 4)[3 5]",
"(3,5,5,5,5,5) (0 1)[2 4](3)(5)",
"(3,5,5,5,5,5) (0 1)(2)(3)(4)(5)",
/* with digons */
"2,3,3,3,3,3 (2,3) (4,5)"
};
int lastsample = 0;

View File

@ -373,8 +373,13 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
sizeto(fsh.b, id);
bshape(fsh.b[id], fsh.prio);
if(&fsh == &shTriheptaFloor && cor == 4 && siid)
/* draw digons specially */
if(cor == 2) {
/* give digons some width */
for(int i=0; i<cor; i++) hpcpush(spin(-.1) * cornerlist[i]), hpcpush(spin(+.1) * cornerlist[i]);
hpcpush(spin(-.1) * cornerlist[0]);
}
else if(&fsh == &shTriheptaFloor && cor == 4 && siid)
/* trihepta floors generate digons too */
for(int i=0; i<=cor; i++) hpcpush(spin((i&1) ? .1 : -.1) * cornerlist[i%cor]);
else
for(int i=0; i<=cor; i++) hpcpush(cornerlist[i%cor]);