1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 01:20:37 +00:00

slr:: generalized to other regular

This commit is contained in:
Zeno Rogue 2019-08-26 14:16:55 +02:00
parent a546b3a62e
commit 86ca34669a
4 changed files with 72 additions and 35 deletions

View File

@ -128,6 +128,10 @@ struct geometry_information {
ld tentacle_length; ld tentacle_length;
/** level in product geometries */ /** level in product geometries */
ld plevel; ld plevel;
/** level for a z-step */
int single_step;
/** the number of levels in SL2 */
int steps;
/** various parameters related to the 3D view */ /** various parameters related to the 3D view */
ld INFDEEP, BOTTOM, HELLSPIKE, LAKE, WALL, FLOOR, STUFF, ld INFDEEP, BOTTOM, HELLSPIKE, LAKE, WALL, FLOOR, STUFF,
@ -465,7 +469,7 @@ void geometry_information::prepare_basics() {
t->hcrossf = cgi.crossf / d; t->hcrossf = cgi.crossf / d;
t->tessf = cgi.tessf / d; t->tessf = cgi.tessf / d;
t->hexvdist = cgi.hexvdist / d; t->hexvdist = cgi.hexvdist / d;
t->hexhexdist = cgi.hexhexdist / d; t->hexhexdist = hdist(xpush0(cgi.hcrossf), xspinpush0(M_PI*2/S7, cgi.hcrossf)) / d;
t->base_distlimit = cgi.base_distlimit-1; t->base_distlimit = cgi.base_distlimit-1;
}); });
goto hybrid_finish; goto hybrid_finish;
@ -569,7 +573,15 @@ void geometry_information::prepare_basics() {
} }
plevel = vid.plevel_factor * scalefactor; plevel = vid.plevel_factor * scalefactor;
if(sl2) plevel = M_PI / 14; steps = 0;
single_step = 1;
if(sl2) {
single_step = S3 * S7 - 2 * S7 - 2 * S3;
steps = 2 * S7;
println(hlog, "steps = ", steps, " / ", single_step);
if(BITRUNCATED) steps *= S3;
plevel = M_PI * single_step / steps;
}
set_sibling_limit(); set_sibling_limit();

View File

@ -909,7 +909,7 @@ EX bool confusingGeometry() {
} }
EX ld master_to_c7_angle() { EX ld master_to_c7_angle() {
if(prod) return hybrid::in_underlying_geometry(master_to_c7_angle); if(hybri) return hybrid::in_underlying_geometry(master_to_c7_angle);
ld alpha = 0; ld alpha = 0;
#if CAP_GP #if CAP_GP
if(cgi.gpdata) alpha = cgi.gpdata->alpha; if(cgi.gpdata) alpha = cgi.gpdata->alpha;

View File

@ -569,17 +569,20 @@ EX namespace hybrid {
EX geometry_information *underlying_cgip; EX geometry_information *underlying_cgip;
EX void configure(eGeometry g) { EX void configure(eGeometry g) {
if(g == gSL2) variation = eVariation::pure, geometry = gNormal; if(g == gSL2) variation = eVariation::pure;
if(vid.always3) { vid.always3 = false; geom3::apply_always3(); } if(vid.always3) { vid.always3 = false; geom3::apply_always3(); }
check_cgi(); check_cgi();
cgi.prepare_basics(); cgi.prepare_basics();
underlying = geometry; underlying = geometry;
underlying_cgip = cgip; underlying_cgip = cgip;
geometry = g; geometry = g;
ginf[gProduct] = ginf[underlying]; ginf[g] = ginf[underlying];
ginf[gProduct].cclass = gcProduct; if(g == gSL2) ginf[g].g = giSL2;
ginf[gProduct].g.gameplay_dimension++; else {
ginf[gProduct].g.graphical_dimension++; ginf[g].cclass = g == gSL2 ? gcSL2 : gcProduct;
ginf[g].g.gameplay_dimension++;
ginf[g].g.graphical_dimension++;
}
} }
hrmap *pmap; hrmap *pmap;
@ -614,7 +617,7 @@ EX namespace hybrid {
} }
cell *getCell(cell *u, int h) { cell *getCell(cell *u, int h) {
if(sl2) h = gmod(h, 14); if(sl2) h = gmod(h, cgi.steps);
cell*& c = at[make_pair(u, h)]; cell*& c = at[make_pair(u, h)];
if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; } if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; }
return c; return c;
@ -645,14 +648,15 @@ EX namespace hybrid {
void find_cell_connection(cell *c, int d) { void find_cell_connection(cell *c, int d) {
auto m = hmap(); auto m = hmap();
if(d >= c->type - 2) { if(d >= c->type - 2) {
cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1)); int s = cgi.single_step;
cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? s : -s));
c->c.connect(d, c1, c1->type - 3 + c->type - d, false); c->c.connect(d, c1, c1->type - 3 + c->type - d, false);
} }
else { else {
auto cu = m->where[c].first; auto cu = m->where[c].first;
auto cu1 = m->in_underlying([&] { return cu->cmove(d); }); auto cu1 = m->in_underlying([&] { return cu->cmove(d); });
int d1 = cu->c.spin(d); int d1 = cu->c.spin(d);
int s = sl2 ? - d1*2 + d*2 + 7 : 0; int s = sl2 ? d*cgi.steps / cu->type - d1*cgi.steps / cu1->type + cgi.steps/2 : 0;
cell *c1 = get_at(cu1, m->where[c].second + s); cell *c1 = get_at(cu1, m->where[c].second + s);
c->c.connect(d, c1, d1, cu->c.mirror(d)); c->c.connect(d, c1, d1, cu->c.mirror(d));
} }
@ -1068,20 +1072,41 @@ EX namespace slr {
"return vec4(s * cos(beta) * cos(alpha), s * sin(beta) * cos(alpha), s * sin(alpha), 1.);" "return vec4(s * cos(beta) * cos(alpha), s * sin(beta) * cos(alpha), s * sin(alpha), 1.);"
"}"; "}";
EX transmatrix adjmatrix(int i, int j) {
ld zs = 2 * M_PI / 28;
if(i == 7) return zpush(-zs) * spin(-2*zs);
if(i == 8) return zpush(+zs) * spin(+2*zs);
return spin(2 * M_PI * i / 7) * xpush(tessf7/2) * spin(M_PI - 2 * M_PI * j / 7);
}
struct hrmap_psl2 : hybrid::hrmap_hybrid { struct hrmap_psl2 : hybrid::hrmap_hybrid {
transmatrix relative_matrix(cell *c1, int i) {
if(i == c1->type-2) return zpush(-cgi.plevel) * spin(-2*cgi.plevel);
if(i == c1->type-1) return zpush(+cgi.plevel) * spin(+2*cgi.plevel);
if(PURE && !archimedean) {
int j = c1->c.spin(i);
ld A = master_to_c7_angle();
transmatrix Q = spin(-A + 2 * M_PI * i / S7) * xpush(cgi.tessf) * spin(M_PI - 2 * M_PI * j / S7 + A);
return Q;
/* if(!eqmatrix(Q, R)) {
println(hlog, "matrix discrepancy");
println(hlog, Q);
println(hlog, R);
} */
}
transmatrix Spin;
hyperpoint d;
cell *c2 = where[c1].first;
in_underlying([&] {
transmatrix T = cellrelmatrix(c2, i);
hyperpoint h = tC0(T);
Spin = inverse(gpushxto0(h) * T);
d = hr::inverse_exp(h, iTable);
});
for(int k=0; k<3; k++) Spin[3][k] = Spin[k][3] = 0; Spin[3][3] = 1;
transmatrix R = eupush3(d[0]/2, -d[1]/2, 0) * Spin;
return R;
}
virtual transmatrix relative_matrix(cell *c2, cell *c1, const struct hyperpoint& point_hint) override { virtual transmatrix relative_matrix(cell *c2, cell *c1, const struct hyperpoint& point_hint) override {
if(c1 == c2) return Id; if(c1 == c2) return Id;
for(int i=0; i<c1->type; i++) if(c1->move(i) == c2) return adjmatrix(i, c1->c.spin(i));
if(gmatrix0.count(c2) && gmatrix0.count(c1)) if(gmatrix0.count(c2) && gmatrix0.count(c1))
return inverse(gmatrix0[c1]) * gmatrix0[c2]; return inverse(gmatrix0[c1]) * gmatrix0[c2];
for(int i=0; i<c1->type; i++) if(c1->move(i) == c2) return relative_matrix(c1, i);
return Id; // not implemented yet return Id; // not implemented yet
} }
@ -1102,12 +1127,12 @@ EX namespace slr {
if(!do_draw(c, V)) continue; if(!do_draw(c, V)) continue;
drawcell(c, V, 0, false); drawcell(c, V, 0, false);
for(int i=0; i<9; i++) { for(int i=0; i<c->type; i++) {
// note: need do cmove before c.spin // note: need do cmove before c.spin
cell *c1 = c->cmove(i); cell *c1 = c->cmove(i);
if(visited.count(c1)) continue; if(visited.count(c1)) continue;
visited.insert(c1); visited.insert(c1);
dq.emplace_back(c1, V * adjmatrix(i, c->c.spin(i))); dq.emplace_back(c1, V * relative_matrix(c, i));
} }
} }
} }

View File

@ -803,7 +803,7 @@ void geometry_information::reserve_wall3d(int i) {
void geometry_information::create_wall3d() { void geometry_information::create_wall3d() {
if(WDIM == 2) return; if(WDIM == 2) return;
reserve_wall3d(penrose ? 22 : prod ? 0 : sl2 ? 9 : S7); reserve_wall3d(penrose ? 22 : prod ? 0 : sl2 ? S7+2 : S7);
if(GDIM == 3 && binarytiling && geometry == gBinary3) { if(GDIM == 3 && binarytiling && geometry == gBinary3) {
hyperpoint h00 = point3(-1,-1,-1); hyperpoint h00 = point3(-1,-1,-1);
hyperpoint h01 = point3(-1,0,-1); hyperpoint h01 = point3(-1,0,-1);
@ -970,23 +970,23 @@ void geometry_information::create_wall3d() {
} }
if(geometry == gSL2) { if(geometry == gSL2) {
ld zs = 2 * M_PI / 28; ld zs = cgi.plevel;
ld a = 2 * M_PI/7; ld a = 2 * M_PI/ S7;
ld tf = tessf7 / 4; ld tf = cgi.tessf / 2;
ld halfedge = 0.283128; ld he = cgi.hexhexdist / 2;
ld he = halfedge / 2; ld A = master_to_c7_angle();
hyperpoint right_u = xpush(tf) * ypush(-he) * zpush0(zs/2); hyperpoint right_u = spin(A) * xpush(tf) * ypush(-he) * zpush0(zs/2);
hyperpoint right_d = xpush(tf) * ypush(-he) * zpush0(-zs/2); hyperpoint right_d = spin(A) * xpush(tf) * ypush(-he) * zpush0(-zs/2);
hyperpoint left_u = xpush(tf) * ypush(+he) * zpush0(zs/2); hyperpoint left_u = spin(A) * xpush(tf) * ypush(+he) * zpush0(zs/2);
hyperpoint left_d = xpush(tf) * ypush(+he) * zpush0(-zs/2); hyperpoint left_d = spin(A) * xpush(tf) * ypush(+he) * zpush0(-zs/2);
hyperpoint center_u = zpush0(zs/2); hyperpoint center_u = zpush0(zs/2);
hyperpoint center_d = zpush0(-zs/2); hyperpoint center_d = zpush0(-zs/2);
for(int i=0; i<7; i++) { for(int i=0; i<S7; i++) {
auto s =spin(a * i); auto s =spin(a * i);
make_wall(i, {s * right_u, s * right_d, s * left_d, s * left_u}); make_wall(i, {s * right_u, s * right_d, s * left_d, s * left_u});
} }
vector<hyperpoint> top, bot; vector<hyperpoint> top, bot;
for(int i=0; i<7; i++) { for(int i=0; i<S7; i++) {
bot.push_back(center_d); bot.push_back(center_d);
bot.push_back(spin(a*i) * left_d); bot.push_back(spin(a*i) * left_d);
bot.push_back(spin(a*i) * right_d); bot.push_back(spin(a*i) * right_d);
@ -1001,8 +1001,8 @@ void geometry_information::create_wall3d() {
top.push_back(spin(a*i) * right_u); top.push_back(spin(a*i) * right_u);
top.push_back(spin(a*(i+1)) * left_u); top.push_back(spin(a*(i+1)) * left_u);
} }
make_wall(7, bot); make_wall(S7, bot);
make_wall(8, top); make_wall(S7+1, top);
} }
if(geometry == gSol) { if(geometry == gSol) {