1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-10-14 05:57:37 +00:00

New file geometry2.cpp, with moved ggmatrix, relative_matrix, virtualRebase, and new get_corner_position family. Refactored in floorpatterns, textures, and grid to use get_corner_position family.

This commit is contained in:
Zeno Rogue
2018-08-17 16:47:06 +02:00
parent 749ad03138
commit 9faa285814
18 changed files with 753 additions and 887 deletions

275
shmup.cpp
View File

@@ -923,8 +923,6 @@ void profile(const char *buf) {
namespace shmup {
transmatrix &ggmatrix(cell *c);
using namespace multi;
eItem targetRangedOrbKey(orbAction a);
@@ -978,18 +976,6 @@ cell *findbaseAroundRepeat(const transmatrix& H, cell *around) {
return asinh(h[2]);
} */
void fixelliptic(transmatrix& at) {
if(elliptic && at[2][2] < 0) {
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
at[i][j] = -at[i][j];
}
}
void fixelliptic(hyperpoint& h) {
if(elliptic && h[2] < 0)
for(int i=0; i<3; i++) h[i] = -h[i];
}
void monster::store() {
monstersAt.insert(make_pair(base, this));
}
@@ -3344,267 +3330,6 @@ transmatrix master_relative(cell *c, bool get_inverse) {
return pispin * Id;
}
transmatrix calc_relative_matrix(cell *c2, cell *c1, int direction_hint) {
return calc_relative_matrix(c2, c1, ddspin(c1, direction_hint) * xpush(1e-2) * C0);
}
// target, source, direction from source to target
transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
if(sphere) {
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
auto bak = gp::draw_li;
swap(gmatrix, gmatrix0);
just_gmatrix = true;
drawrec(viewctr, hsOrigin, Id);
just_gmatrix = false;
swap(gmatrix, gmatrix0);
gp::draw_li = bak;
}
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(binarytiling) return binary::relative_matrix(c2->master, c1->master);
if(syntetic) return synt::relative_matrix(c2->master, c1->master);
if(torus) {
transmatrix t = Id;
if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));
int mirrors = 0;
approach:
int d = celldistance(c2, c1);
forCellIdEx(c3, i, c2) {
if(celldistance(c3, c1) < d) {
if(whateveri) printf(" %d [%p,%d]", i, c3, celldistance(c3, c1));
if(c2->type < 8)
t = eumovedir(i+(euclid6?3:2)) * t;
else if(i&1)
t = eumovedir(2+i/2) * eumovedir(2+(i+1)/2) * t;
else
t = eumovedir(2+i/2) * t;
if(c2->mirror(i)) mirrors++;
c2 = c3;
goto approach;
}
}
if(d != 0) printf("ERROR not reached\n");
if(mirrors&1) t = Mirror * t * Mirror;
if(whateveri) printf(" => %p\n", c1);
return t;
}
if(euclid) return inverse(gmatrix0[c1]) * gmatrix0[c2];
heptagon *h1 = c1->master;
transmatrix gm = master_relative(c1, true);
heptagon *h2 = c2->master;
transmatrix where = master_relative(c2);
// always add to last!
//bool hsol = false;
//transmatrix sol;
while(h1 != h2) {
if(quotient & qSMALL) {
transmatrix T;
ld bestdist = 1e9;
for(int d=0; d<S7; d++) if(h2->move[d]) {
int sp = h2->spin(d);
transmatrix S = heptmove[sp] * spin(2*M_PI*d/S7);
if(h2->move[d] == h1) {
transmatrix T1 = gm * S * where;
auto curdist = hdist(tC0(T1), point_hint);
if(curdist < bestdist) T = T1, bestdist = curdist;
}
for(int e=0; e<S7; e++) if(h2->move[d]->move[e] == h1) {
int sp2 = h2->move[d]->spin(e);
transmatrix T1 = gm * heptmove[sp2] * spin(2*M_PI*e/S7) * S * where;
auto curdist = hdist(tC0(T1), point_hint);
if(curdist < bestdist) T = T1, bestdist = curdist;
}
}
if(bestdist < 1e8) return T;
}
for(int d=0; d<S7; d++) if(h2->move[d] == h1) {
int sp = h2->spin(d);
return gm * heptmove[sp] * spin(2*M_PI*d/S7) * where;
}
if(geometry == gFieldQuotient) {
int bestdist = 1000, bestd = 0;
for(int d=0; d<S7; d++) {
int dist = celldistance(h2->move[d]->c7, c1);
if(dist < bestdist) bestdist = dist, bestd = d;
}
int sp = h2->spin(bestd);
where = heptmove[sp] * spin(2*M_PI*bestd/S7) * where;
h2 = h2->move[bestd];
}
else if(h1->distance < h2->distance) {
int sp = h2->spin(0);
h2 = h2->move[0];
where = heptmove[sp] * where;
}
else {
int sp = h1->spin(0);
h1 = h1->move[0];
gm = gm * invheptmove[sp];
}
}
/*if(hsol) {
transmatrix sol2 = gm * where;
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
if(fabs(sol2[i][j]-sol[i][j] > 1e-3)) {
printf("ERROR\n");
display(sol);
display(sol2);
exit(1);
}
} */
return gm * where;
}
transmatrix &ggmatrix(cell *c) {
transmatrix& t = gmatrix[c];
if(t[2][2] == 0) {
if(torus && centerover.c)
t = calc_relative_matrix(c, centerover.c, C0);
else if(euclid) {
if(!centerover.c) centerover = cwt;
t = View * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
}
else
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h->c7, C0);
}
return t;
}
transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) {
transmatrix gm = Id;
heptagon *h2 = c->master;
transmatrix where = Id;
if(gp::on && c != c->master->c7) {
auto li = gp::get_local_info(c);
where = gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)];
}
else if(!nonbitrunc) for(int d=0; d<S7; d++) if(h2->c7->mov[d] == c)
where = hexmove[d];
// always add to last!
while(h1 != h2) {
for(int d=0; d<S7; d++) if(h1->move[d] == h2) printf("(adj) ");
if(h1->distance < h2->distance) {
int sp = h2->spin(0);
printf("A%d ", sp);
h2 = h2->move[0];
where = heptmove[sp] * where;
}
else {
int sp = h1->spin(0);
printf("B%d ", sp);
h1 = h1->move[0];
gm = gm * invheptmove[sp];
}
}
printf("OK\n");
display(gm * where);
return gm * where;
}
template<class T, class U>
void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
if(euclid || sphere) {
again:
if(torus) for(int i=0; i<6; i++) {
auto newat = eumovedir(3+i) * at;
if(hdist0(check(newat)) < hdist0(check(at))) {
at = newat;
base = createMov(base, i);
goto again;
}
}
else forCellCM(c2, base) {
auto newat = inverse(ggmatrix(c2)) * ggmatrix(base) * at;
if(hypot(check(newat)[0], check(newat)[1])
< hypot(check(at)[0], check(at)[1])) {
at = newat;
base = c2;
goto again;
}
}
fixelliptic(at);
return;
}
at = master_relative(base) * at;
base = base->master->c7;
while(true) {
double currz = check(at)[2];
heptagon *h = base->master;
cell *newbase = NULL;
transmatrix bestV;
for(int d=0; d<S7; d++) {
heptspin hs;
hs.h = h;
hs.spin = d;
heptspin hs2 = hs + wstep;
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * invheptmove[d];
double newz = check(V2 * at) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
newbase = hs2.h->c7;
}
}
if(newbase) {
base = newbase;
at = bestV * at;
}
else {
if(tohex && !nonbitrunc) for(int d=0; d<S7; d++) {
cell *c = createMov(base, d);
transmatrix V2 = spin(-base->spn(d)*2*M_PI/S6) * invhexmove[d];
double newz = check(V2 *at) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
newbase = c;
}
}
if(newbase) {
base = newbase;
at = bestV * at;
}
else at = master_relative(base, true) * at;
break;
}
}
}
void virtualRebase(cell*& base, transmatrix& at, bool tohex) {
virtualRebase(base, at, tohex, tC0);
}
void virtualRebase(cell*& base, hyperpoint& h, bool tohex) {
virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return h; });
}
void virtualRebase(shmup::monster *m, bool tohex) {
virtualRebase(m->base, m->at, tohex);
}