mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-22 22:10:20 +00:00
generalized PSL2 to spherical rotation spaces too
This commit is contained in:
parent
2bedd5f2ce
commit
c33c79a902
2
cell.cpp
2
cell.cpp
@ -263,7 +263,7 @@ EX void initcells() {
|
|||||||
|
|
||||||
hrmap* res = callhandlers((hrmap*)nullptr, hooks_newmap);
|
hrmap* res = callhandlers((hrmap*)nullptr, hooks_newmap);
|
||||||
if(res) currentmap = res;
|
if(res) currentmap = res;
|
||||||
else if(nonisotropic || prod) currentmap = nisot::new_map();
|
else if(nonisotropic || hybri) currentmap = nisot::new_map();
|
||||||
#if CAP_CRYSTAL
|
#if CAP_CRYSTAL
|
||||||
else if(cryst) currentmap = crystal::new_map();
|
else if(cryst) currentmap = crystal::new_map();
|
||||||
#endif
|
#endif
|
||||||
|
@ -461,7 +461,7 @@ void geometry_information::prepare_basics() {
|
|||||||
|
|
||||||
if(hybri) {
|
if(hybri) {
|
||||||
auto t = this;
|
auto t = this;
|
||||||
ld d = sl2 ? 2 : 1;
|
ld d = prod ? 1 : 2;
|
||||||
hybrid::in_underlying_geometry([&] {
|
hybrid::in_underlying_geometry([&] {
|
||||||
t->rhexf = cgi.rhexf / d;
|
t->rhexf = cgi.rhexf / d;
|
||||||
t->hexf = cgi.hexf / d;
|
t->hexf = cgi.hexf / d;
|
||||||
@ -575,17 +575,18 @@ void geometry_information::prepare_basics() {
|
|||||||
plevel = vid.plevel_factor * scalefactor;
|
plevel = vid.plevel_factor * scalefactor;
|
||||||
steps = 0;
|
steps = 0;
|
||||||
single_step = 1;
|
single_step = 1;
|
||||||
if(sl2) {
|
if(hybri && !prod) {
|
||||||
if(hybrid::underlying == gArchimedean) {
|
if(hybrid::underlying == gArchimedean) {
|
||||||
ld s = arcm::current.euclidean_angle_sum - 2;
|
ld s = arcm::current.euclidean_angle_sum - 2;
|
||||||
single_step = 2;
|
single_step = 2;
|
||||||
DEBB(DF_GEOM | DF_POLY, ("1/s = ", 1/s));
|
DEBB(DF_GEOM | DF_POLY, ("1/s = ", 1/s));
|
||||||
steps = 4/s + .5;
|
steps = 4/abs(s) + .5;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
single_step = S3 * S7 - 2 * S7 - 2 * S3;
|
single_step = S3 * S7 - 2 * S7 - 2 * S3;
|
||||||
steps = 2 * S7;
|
steps = 2 * S7;
|
||||||
if(BITRUNCATED) steps *= S3;
|
if(BITRUNCATED) steps *= S3;
|
||||||
|
if(single_step < 0) single_step = -single_step;
|
||||||
}
|
}
|
||||||
DEBB(DF_GEOM | DF_POLY, ("steps = ", steps, " / ", single_step));
|
DEBB(DF_GEOM | DF_POLY, ("steps = ", steps, " / ", single_step));
|
||||||
plevel = M_PI * single_step / steps;
|
plevel = M_PI * single_step / steps;
|
||||||
|
@ -574,14 +574,19 @@ EX namespace hybrid {
|
|||||||
cgi.prepare_basics();
|
cgi.prepare_basics();
|
||||||
underlying = geometry;
|
underlying = geometry;
|
||||||
underlying_cgip = cgip;
|
underlying_cgip = cgip;
|
||||||
|
bool sph = sphere;
|
||||||
geometry = g;
|
geometry = g;
|
||||||
|
auto keep = ginf[g].menu_displayed_name;
|
||||||
ginf[g] = ginf[underlying];
|
ginf[g] = ginf[underlying];
|
||||||
|
ginf[g].menu_displayed_name = keep;
|
||||||
if(g == gSL2) {
|
if(g == gSL2) {
|
||||||
ginf[g].g = giSL2;
|
ginf[g].g = sph ? giSphere3 : giSL2;
|
||||||
ginf[g].tiling_name = "Iso(" + ginf[g].tiling_name + ")";
|
ginf[g].tiling_name = "Iso(" + ginf[g].tiling_name + ")";
|
||||||
string& qn = ginf[g].quotient_name;
|
string& qn = ginf[g].quotient_name;
|
||||||
if(qn == "none") qn = "PSL(2,R)";
|
string qplus = sph ? "elliptic" : qn;
|
||||||
else qn = qn + "/PSL(2,R)";
|
if(qn == "none" || qn == "elliptic") qn = qplus;
|
||||||
|
else qn = qn + "/" + qplus;
|
||||||
|
if(sph) ginf[g].flags |= qELLIPTIC;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ginf[g].cclass = g == gSL2 ? gcSL2 : gcProduct;
|
ginf[g].cclass = g == gSL2 ? gcSL2 : gcProduct;
|
||||||
@ -693,17 +698,16 @@ EX namespace hybrid {
|
|||||||
return mscale(get_corner_position(c, i+next), exp(lev));
|
return mscale(get_corner_position(c, i+next), exp(lev));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ld tf, he;
|
ld tf, he, alpha;
|
||||||
transmatrix Spin;
|
|
||||||
in_underlying_map([&] {
|
in_underlying_map([&] {
|
||||||
hyperpoint h1 = get_corner_position(c, i);
|
hyperpoint h1 = get_corner_position(c, i);
|
||||||
hyperpoint h2 = get_corner_position(c, i+1);
|
hyperpoint h2 = get_corner_position(c, i+1);
|
||||||
hyperpoint hm = mid(h1, h2);
|
hyperpoint hm = mid(h1, h2);
|
||||||
tf = hdist0(hm)/2;
|
tf = hdist0(hm)/2;
|
||||||
he = hdist(hm, h2)/2;
|
he = hdist(hm, h2)/2;
|
||||||
Spin = spintox(hm); /* inverse! */
|
alpha = atan2(hm[1], hm[0]);
|
||||||
});
|
});
|
||||||
return Spin * xpush(tf) * ypush(next?he:-he) * zpush0(lev);
|
return spin(alpha) * rots::uxpush(tf) * rots::uypush(next?he:-he) * rots::uzpush(lev) * C0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,16 +1110,35 @@ 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.);"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
struct hrmap_psl2 : hybrid::hrmap_hybrid {
|
EX }
|
||||||
|
|
||||||
|
EX namespace rots {
|
||||||
|
|
||||||
|
EX transmatrix uxpush(ld x) {
|
||||||
|
if(sl2) return xpush(x);
|
||||||
|
return cspin(1, 3, x) * cspin(0, 2, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
EX transmatrix uypush(ld y) {
|
||||||
|
if(sl2) return ypush(y);
|
||||||
|
return cspin(0, 3, -y) * cspin(1, 2, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
EX transmatrix uzpush(ld z) {
|
||||||
|
if(sl2) return zpush(z);
|
||||||
|
return cspin(3, 2, -z) * cspin(0, 1, -z);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hrmap_rotation_space : hybrid::hrmap_hybrid {
|
||||||
|
|
||||||
transmatrix relative_matrix(cell *c1, int i) {
|
transmatrix relative_matrix(cell *c1, int i) {
|
||||||
if(i == c1->type-2) return zpush(-cgi.plevel) * spin(-2*cgi.plevel);
|
if(i == c1->type-2) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
|
||||||
if(i == c1->type-1) return zpush(+cgi.plevel) * spin(+2*cgi.plevel);
|
if(i == c1->type-1) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
|
||||||
if(PURE && hybrid::underlying != gArchimedean) {
|
if(PURE && hybrid::underlying != gArchimedean) {
|
||||||
/* todo: always do something like this! */
|
/* todo: always do something like this! */
|
||||||
int j = c1->c.spin(i);
|
int j = c1->c.spin(i);
|
||||||
ld A = master_to_c7_angle();
|
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);
|
transmatrix Q = spin(-A + 2 * M_PI * i / S7) * uxpush(cgi.tessf) * spin(M_PI - 2 * M_PI * j / S7 + A);
|
||||||
return Q;
|
return Q;
|
||||||
/* if(!eqmatrix(Q, R)) {
|
/* if(!eqmatrix(Q, R)) {
|
||||||
println(hlog, "matrix discrepancy");
|
println(hlog, "matrix discrepancy");
|
||||||
@ -1123,17 +1146,21 @@ EX namespace slr {
|
|||||||
println(hlog, R);
|
println(hlog, R);
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
transmatrix Spin;
|
|
||||||
hyperpoint d;
|
hyperpoint d;
|
||||||
|
ld alpha, beta, distance;
|
||||||
|
transmatrix Spin;
|
||||||
cell *c2 = where[c1].first;
|
cell *c2 = where[c1].first;
|
||||||
in_underlying([&] {
|
in_underlying([&] {
|
||||||
transmatrix T = cellrelmatrix(c2, i);
|
transmatrix T = cellrelmatrix(c2, i);
|
||||||
hyperpoint h = tC0(T);
|
hyperpoint h = tC0(T);
|
||||||
Spin = inverse(gpushxto0(h) * T);
|
Spin = inverse(gpushxto0(h) * T);
|
||||||
d = hr::inverse_exp(h, iTable);
|
d = hr::inverse_exp(h, iTable);
|
||||||
|
alpha = atan2(Spin[0][1], Spin[0][0]);
|
||||||
|
distance = hdist0(h);
|
||||||
|
beta = atan2(h[1], h[0]);
|
||||||
});
|
});
|
||||||
for(int k=0; k<3; k++) Spin[3][k] = Spin[k][3] = 0; Spin[3][3] = 1;
|
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;
|
transmatrix R = spin(beta) * uxpush(distance/2) * spin(-beta+alpha);
|
||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,12 +1185,16 @@ EX namespace slr {
|
|||||||
cell *c = dq[i].first;
|
cell *c = dq[i].first;
|
||||||
transmatrix V = dq[i].second;
|
transmatrix V = dq[i].second;
|
||||||
|
|
||||||
if(V[3][3] < 0) V = centralsym * V;
|
if(sl2) {
|
||||||
if(!do_draw(c, V)) continue;
|
if(V[3][3] < 0) V = centralsym * V;
|
||||||
drawcell(c, V, 0, false);
|
if(!do_draw(c, V)) continue;
|
||||||
|
drawcell(c, V, 0, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
drawcell(c, V, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
for(int i=0; i<c->type; i++) {
|
for(int i=0; i<c->type; i++) {
|
||||||
// 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);
|
||||||
@ -1276,8 +1307,8 @@ EX namespace nisot {
|
|||||||
EX hrmap *new_map() {
|
EX hrmap *new_map() {
|
||||||
if(sol) return new solv::hrmap_sol;
|
if(sol) return new solv::hrmap_sol;
|
||||||
if(nil) return new nilv::hrmap_nil;
|
if(nil) return new nilv::hrmap_nil;
|
||||||
if(geometry == gProduct) return new product::hrmap_product;
|
if(prod) return new product::hrmap_product;
|
||||||
if(hybri) return new slr::hrmap_psl2;
|
if(hybri) return new rots::hrmap_rotation_space;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1316,6 +1347,11 @@ EX namespace nisot {
|
|||||||
set_geometry(gProduct);
|
set_geometry(gProduct);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if(argis("-rotspace")) {
|
||||||
|
PHASEFROM(2);
|
||||||
|
set_geometry(gSL2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user