mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-20 15:40:26 +00:00
slr:: fixes in ~SL quotients: auto disc_quotient, underlying spaces drawn correctly, comment in period selector
This commit is contained in:
parent
8e041e7b2c
commit
7d7fe85199
@ -844,7 +844,8 @@ EX void showEuclideanMenu() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if(hybri) {
|
else if(hybri) {
|
||||||
dialog::addSelItem(XLAT("number of levels"), its(hybrid::csteps / cgi.single_step), 0);
|
dialog::addSelItem(XLAT("number of levels"), its(hybrid::csteps / cgi.single_step), 'L');
|
||||||
|
dialog::add_action(hybrid::configure_period);
|
||||||
}
|
}
|
||||||
else if(bt::in()) {
|
else if(bt::in()) {
|
||||||
dialog::addSelItem(XLAT("width"), fts(vid.binary_width), 'v');
|
dialog::addSelItem(XLAT("width"), fts(vid.binary_width), 'v');
|
||||||
|
103
nonisotropic.cpp
103
nonisotropic.cpp
@ -1067,6 +1067,8 @@ EX namespace hybrid {
|
|||||||
|
|
||||||
EX int csteps;
|
EX int csteps;
|
||||||
|
|
||||||
|
EX int disc_quotient = 0;
|
||||||
|
|
||||||
EX transmatrix ray_iadj(cell *c, int i) {
|
EX transmatrix ray_iadj(cell *c, int i) {
|
||||||
if(prod && i == c->type-2) return (mscale(Id, +cgi.plevel));
|
if(prod && i == c->type-2) return (mscale(Id, +cgi.plevel));
|
||||||
if(prod && i == c->type-1) return (mscale(Id, -cgi.plevel));
|
if(prod && i == c->type-1) return (mscale(Id, -cgi.plevel));
|
||||||
@ -1101,10 +1103,20 @@ EX namespace hybrid {
|
|||||||
ginf[g].g = sph ? giSphere3 : 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;
|
||||||
string qplus = sph ? "elliptic" : qn;
|
if(csteps && csteps != (sph ? cgi.psl_steps*2 : 0)) {
|
||||||
if(qn == "none" || qn == "elliptic") qn = qplus;
|
string qplus;
|
||||||
else qn = qn + "/" + qplus;
|
if(csteps == cgi.psl_steps)
|
||||||
if(sph) ginf[g].flags |= qELLIPTIC;
|
qplus = sph ? "elliptic" : "PSL";
|
||||||
|
else if(csteps == 2 * cgi.psl_steps && !sph)
|
||||||
|
qplus = "SL";
|
||||||
|
else qplus = its(csteps);
|
||||||
|
if(qn == "none") qn = qplus;
|
||||||
|
else qn = qn + "/" + qplus;
|
||||||
|
}
|
||||||
|
if(elliptic) ginf[g].flags |= qELLIPTIC;
|
||||||
|
println(hlog, "set elliptic if: 0=", csteps % cgi.psl_steps);
|
||||||
|
if(csteps && csteps != cgi.psl_steps && csteps != 2*cgi.psl_steps)
|
||||||
|
ginf[g].flags |= qANYQ;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ginf[g].cclass = g == gRotSpace ? gcSL2 : gcProduct;
|
ginf[g].cclass = g == gRotSpace ? gcSL2 : gcProduct;
|
||||||
@ -1154,7 +1166,7 @@ EX namespace hybrid {
|
|||||||
|
|
||||||
EX vector<int>& make_shift(cell *c) {
|
EX vector<int>& make_shift(cell *c) {
|
||||||
auto& res = shifts[c];
|
auto& res = shifts[c];
|
||||||
if(res.empty()) res = vector<int> (c->type, SHIFT_UNKNOWN);
|
if(res.empty()) res = vector<int> (c->type+1, SHIFT_UNKNOWN);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,6 +1179,7 @@ EX namespace hybrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX int get_shift(cell *c, int i) {
|
EX int get_shift(cell *c, int i) {
|
||||||
|
if(S3 >= OINF) return 0;
|
||||||
auto& v = get_shift_current(c, i);
|
auto& v = get_shift_current(c, i);
|
||||||
if(v != SHIFT_UNKNOWN) return v;
|
if(v != SHIFT_UNKNOWN) return v;
|
||||||
|
|
||||||
@ -1183,39 +1196,48 @@ EX namespace hybrid {
|
|||||||
cw += wstep;
|
cw += wstep;
|
||||||
cw += a;
|
cw += a;
|
||||||
}
|
}
|
||||||
candidates.push_back(-a * cgi.single_step - s);
|
candidates.push_back(-a * cgi.single_step * (sphere ? -1 : 1) - s);
|
||||||
next: ;
|
next: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(candidates.size() == 2 && candidates[0] != candidates[1]) {
|
if(candidates.size() == 2 && candidates[0] != candidates[1]) {
|
||||||
println(hlog, "discrepancy found ", candidates);
|
int val = candidates[0] - candidates[1];
|
||||||
|
if(disc_quotient == 0) disc_quotient = val;
|
||||||
|
disc_quotient = gcd(val, disc_quotient);
|
||||||
|
if(disc_quotient < 0) disc_quotient = -disc_quotient;
|
||||||
}
|
}
|
||||||
|
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
|
||||||
|
if(1) {
|
||||||
|
/* the value from PSL, helps to draw the underlying space correctly */
|
||||||
|
auto ps = cgi.psl_steps;
|
||||||
|
val = i*ps / c->type - c->c.spin(i)*ps / c->move(i)->type + ps/2;
|
||||||
|
}
|
||||||
if(!candidates.empty()) val = candidates[0];
|
if(!candidates.empty()) val = candidates[0];
|
||||||
|
|
||||||
v = val;
|
v = val;
|
||||||
get_shift_current(c->move(i), c->c.spin(i)) = -val;
|
get_shift_current(c->move(i), c->c.spin(i)) = -val;
|
||||||
|
|
||||||
for(int a: {1, -1}) {
|
|
||||||
cellwalker cw0(c, i);
|
|
||||||
cellwalker cw = cw0;
|
|
||||||
cw += wstep; cw += a;
|
|
||||||
int s = 0;
|
|
||||||
while(cw != cw0) {
|
|
||||||
if(!have_shift(cw.at, cw.spin)) goto next1;
|
|
||||||
s += shifts[cw.at][cw.spin];
|
|
||||||
cw += wstep;
|
|
||||||
cw += a;
|
|
||||||
}
|
|
||||||
if(val != -a * cgi.single_step - s)
|
|
||||||
println(hlog, "incorrect val after setting");
|
|
||||||
next1: ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX void ensure_shifts(cell *c) {
|
||||||
|
if(S3 >= OINF) return;
|
||||||
|
if(have_shift(c, c->type)) return;
|
||||||
|
forCellEx(c1, c)
|
||||||
|
for(int a=0; a<c->type; a++) {
|
||||||
|
cellwalker cw0(c, a);
|
||||||
|
cellwalker cw = cw0;
|
||||||
|
while(cw != cw0) {
|
||||||
|
get_shift(cw.at, cw.spin);
|
||||||
|
cw += wstep;
|
||||||
|
cw += a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get_shift_current(c, c->type) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T> auto in_underlying(const T& t) -> decltype(t()) {
|
template<class T> auto in_underlying(const T& t) -> decltype(t()) {
|
||||||
pcgip = cgip;
|
pcgip = cgip;
|
||||||
dynamicval<hrmap*> gpm(pmap, this);
|
dynamicval<hrmap*> gpm(pmap, this);
|
||||||
@ -1245,6 +1267,7 @@ EX namespace hybrid {
|
|||||||
|
|
||||||
hrmap_hybrid() {
|
hrmap_hybrid() {
|
||||||
twisted = false;
|
twisted = false;
|
||||||
|
disc_quotient = 0;
|
||||||
in_underlying([this] { initcells(); underlying_map = currentmap; });
|
in_underlying([this] { initcells(); underlying_map = currentmap; });
|
||||||
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
|
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
|
||||||
}
|
}
|
||||||
@ -1324,12 +1347,9 @@ EX namespace hybrid {
|
|||||||
int d1 = cu->c.spin(d);
|
int d1 = cu->c.spin(d);
|
||||||
int s = 0;
|
int s = 0;
|
||||||
if(geometry == gRotSpace) {
|
if(geometry == gRotSpace) {
|
||||||
if(csteps && cgi.psl_steps % csteps == 0) {
|
auto cm = (hrmap_hybrid*)currentmap;
|
||||||
auto ps = cgi.psl_steps;
|
m->in_underlying([&] { cm->ensure_shifts(cu); });
|
||||||
s = d*ps / cu->type - d1*ps / cu1->type + ps/2;
|
s = ((hrmap_hybrid*)currentmap)->get_shift(cu, d);
|
||||||
}
|
|
||||||
else
|
|
||||||
s = ((hrmap_hybrid*)currentmap)->get_shift(cu, d);
|
|
||||||
}
|
}
|
||||||
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));
|
||||||
@ -1520,9 +1540,17 @@ EX namespace hybrid {
|
|||||||
EX void configure_period() {
|
EX void configure_period() {
|
||||||
static int s;
|
static int s;
|
||||||
s = csteps / cgi.single_step;
|
s = csteps / cgi.single_step;
|
||||||
dialog::editNumber(s, 0, 16, 1, 0, XLAT("%1 period", "Z"), "");
|
string str = "";
|
||||||
|
if(rotspace)
|
||||||
|
str = XLAT(
|
||||||
|
"Theoretically, the double period ('sphere') works in underlying spherical geometry, "
|
||||||
|
"any value works in (full) hyperbolic geometry, and single period ('PSL(2,R)') "
|
||||||
|
"works in hyperbolic quotient spaces; quotients of these numbers work too. "
|
||||||
|
"(The current implementation in HyperRogue is not perfect, though, so only single is guaranteed to work.) "
|
||||||
|
"We won't stop you from trying illegal numbers, but they won't work correctly.");
|
||||||
|
dialog::editNumber(s, 0, 16, 1, 0, XLAT("%1 period", "Z"), str);
|
||||||
dialog::bound_low(0);
|
dialog::bound_low(0);
|
||||||
auto set_s = [] (int s1) {
|
auto set_s = [] (int s1, bool ret) {
|
||||||
return [s1] {
|
return [s1] {
|
||||||
if(csteps == s1) return;
|
if(csteps == s1) return;
|
||||||
stop_game();
|
stop_game();
|
||||||
@ -1530,24 +1558,27 @@ EX namespace hybrid {
|
|||||||
hybrid::reconfigure();
|
hybrid::reconfigure();
|
||||||
start_game();
|
start_game();
|
||||||
};
|
};
|
||||||
|
if(ret) popScreen();
|
||||||
};
|
};
|
||||||
dialog::extra_options = [=] () {
|
dialog::extra_options = [=] () {
|
||||||
if(rotspace) {
|
if(rotspace) {
|
||||||
int e_steps = cgi.psl_steps / gcd(cgi.single_step, cgi.psl_steps);
|
int e_steps = cgi.psl_steps / gcd(cgi.single_step, cgi.psl_steps);
|
||||||
dialog::addSelItem( XLAT(sphere ? "elliptic" : "PSL(2,R)"), its(e_steps), 'P');
|
dialog::addSelItem( XLAT(sphere ? "elliptic" : "PSL(2,R)"), its(e_steps), 'P');
|
||||||
dialog::add_action(set_s(e_steps));
|
dialog::add_action(set_s(e_steps, true));
|
||||||
dialog::addSelItem( XLAT(sphere ? "sphere" : "SL(2,R)"), its(2*e_steps), 'P');
|
dialog::addSelItem( XLAT(sphere ? "sphere" : "SL(2,R)"), its(2*e_steps), 'P');
|
||||||
dialog::add_action(set_s(2*e_steps));
|
dialog::add_action(set_s(2*e_steps, true));
|
||||||
if(sl2) {
|
if(sl2) {
|
||||||
dialog::addSelItem( XLAT("universal cover"), its(0), 'P');
|
dialog::addSelItem( XLAT("universal cover"), its(0), 'P');
|
||||||
dialog::add_action(set_s(0));
|
dialog::add_action(set_s(0, true));
|
||||||
}
|
}
|
||||||
|
dialog::addSelItem( XLAT("works correctly so far"), its(disc_quotient), 'Q');
|
||||||
|
dialog::add_action(set_s(disc_quotient, true));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dialog::addSelItem( XLAT("non-periodic"), its(0), 'N');
|
dialog::addSelItem( XLAT("non-periodic"), its(0), 'N');
|
||||||
dialog::add_action(set_s(0));
|
dialog::add_action(set_s(0, true));
|
||||||
}
|
}
|
||||||
dialog::reaction_final = set_s(s);
|
dialog::reaction_final = set_s(s, false);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user