slr:: works with bitruncated tilings (Archimedean not tested)

This commit is contained in:
Zeno Rogue 2019-08-26 15:09:08 +02:00
parent 86ca34669a
commit a0140254c8
7 changed files with 101 additions and 93 deletions

View File

@ -431,10 +431,18 @@ void ge_select_tiling(const vector<eGeometry>& lst) {
pushScreen(arcm::show);
#endif
else dialog::do_if_confirmed([targetgeometry] () {
if(targetgeometry == gProduct && (WDIM == 3 || euclid)) {
bool th = among(targetgeometry, gProduct, gSL2);
if(th && (WDIM == 3 || euclid)) {
addMessage(XLAT("Only works with 2D non-Euclidean geometries"));
return;
}
if(targetgeometry == gSL2) {
bool ok = true;
if(archimedean) ok = PURE;
else if(binarytiling || penrose) ok = false;
else ok = PURE || BITRUNCATED;
if(!ok) addMessage(XLAT("Only works with (semi-)regular tilings"));
}
set_geometry(targetgeometry);
start_game();
if(euwrap) {

View File

@ -578,8 +578,8 @@ void geometry_information::prepare_basics() {
if(sl2) {
single_step = S3 * S7 - 2 * S7 - 2 * S3;
steps = 2 * S7;
println(hlog, "steps = ", steps, " / ", single_step);
if(BITRUNCATED) steps *= S3;
DEBB(DF_GEOM | DF_POLY, ("steps = ", steps, " / ", single_step));
plevel = M_PI * single_step / steps;
}

View File

@ -4564,6 +4564,7 @@ void radar_grid(cell *c, const transmatrix& V) {
int wall_offset(cell *c) {
if(prod) return product::cwall_offset;
if(sl2) return hybrid::wall_offset(c);
if(penrose && kite::getshape(c->master) == kite::pKite) return 10;
return 0;
}

View File

@ -1384,9 +1384,18 @@ EX void optimizeview() {
cell *cbest = NULL;
ld best = hdist0(tC0(gmatrix[c]));
if(isnan(best)) return;
forCellEx(c2, c) {
ld quality = hdist0(tC0(gmatrix[c2]));
if(quality < best) best = quality, cbest = c2;
forCellIdEx(c2, i2, c) {
if(!gmatrix.count(c2)) return;
if(PURE || i2 >= c->type-2) {
ld quality = hdist0(tC0(gmatrix[c2]));
if(quality < best) best = quality, cbest = c2;
}
else forCellIdEx(c3, i3, c2) if(i3%2 == 0 && i3 < c2->type-2 && gmatrix.count(c3)) {
// cell *w = hybrid::get_where(c3).first;
// assert (w->master->c7 != w)
ld quality = hdist0(tC0(gmatrix[c3]));
if(quality < best) best = quality, cbest = c3;
}
}
if(cbest) {
View = View * currentmap->relative_matrix(cbest, c, C0);

View File

@ -569,7 +569,6 @@ EX namespace hybrid {
EX geometry_information *underlying_cgip;
EX void configure(eGeometry g) {
if(g == gSL2) variation = eVariation::pure;
if(vid.always3) { vid.always3 = false; geom3::apply_always3(); }
check_cgi();
cgi.prepare_basics();
@ -677,6 +676,81 @@ EX namespace hybrid {
#define PIU(x) hr::hybrid::in_underlying_geometry([&] { return (x); })
#endif
EX hyperpoint get_corner(cell *c, int i, int next, ld z) {
ld lev = cgi.plevel * z / 2;
if(prod) {
dynamicval<eGeometry> g(geometry, hybrid::underlying);
dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip);
return mscale(get_corner_position(c, i+next), exp(lev));
}
else {
ld tf, he;
transmatrix Spin;
in_underlying_map([&] {
hyperpoint h1 = get_corner_position(c, i);
hyperpoint h2 = get_corner_position(c, i+1);
hyperpoint hm = mid(h1, h2);
tf = hdist0(hm)/2;
he = hdist(hm, h2)/2;
Spin = spintox(hm); /* inverse! */
});
return Spin * xpush(tf) * ypush(next?he:-he) * zpush0(lev);
}
}
EX int wall_offset(cell *c) {
int id = hybrid::underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, -1);
int &wo = cgi.walloffsets[id];
if(wo == -1) {
cell *c1 = hybrid::get_where(c).first;
wo = isize(cgi.shWall3D);
int won = wo + c->type;
cgi.reserve_wall3d(won);
if(prod) for(int i=0; i<c1->type; i++) {
hyperpoint w;
hybrid::in_underlying_geometry([&] {
/* mirror image of C0 in the axis h1-h2 */
hyperpoint h1 = get_corner_position(c1, i);
hyperpoint h2 = get_corner_position(c1, i+1);
transmatrix T = gpushxto0(h1);
T = spintox(T * h2) * T;
w = T * C0;
w[1] = -w[1];
w = inverse(T) * w;
});
cgi.walltester[wo + i] = w;
}
for(int i=0; i<c1->type; i++)
cgi.make_wall(wo + i, {hybrid::get_corner(c1, i, 0, -1), hybrid::get_corner(c1, i, 0, +1), hybrid::get_corner(c1, i, 1, +1), hybrid::get_corner(c1, i, 1, -1)});
for(int a: {0,1}) {
vector<hyperpoint> l;
int z = a ? 1 : -1;
hyperpoint ctr = zpush0(z * cgi.plevel/2);
for(int i=0; i<c1->type; i++)
if(prod)
l.push_back(hybrid::get_corner(c1, i, 0, z));
else {
l.push_back(ctr);
l.push_back(hybrid::get_corner(c1, i, 0, z));
l.push_back(hybrid::get_corner(c1, i+1, 1, z));
l.push_back(ctr);
l.push_back(hybrid::get_corner(c1, i, 1, z));
l.push_back(hybrid::get_corner(c1, i, 0, z));
}
cgi.make_wall(won-2+a, l);
}
cgi.compute_cornerbonus();
cgi.extra_vertices();
}
return wo;
}
EX }
EX namespace product {
@ -699,7 +773,7 @@ EX namespace product {
bool s = sphere;
hybrid::in_actual([&] {
cell *c0 = hybrid::get_at(c, hybrid::current_view_level);
cwall_offset = wall_offset(c0);
cwall_offset = hybrid::wall_offset(c0);
if(s) cwall_mask = (1<<c->type) - 1;
else {
cwall_mask = 0;
@ -722,54 +796,6 @@ EX namespace product {
});
}
EX hyperpoint get_corner(cell *c, int i, ld z) {
ld lev = cgi.plevel * z / 2;
dynamicval<eGeometry> g(geometry, hybrid::underlying);
dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip);
return mscale(get_corner_position(c, i), exp(lev));
}
EX int wall_offset(cell *c) {
int id = hybrid::underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, -1);
int &wo = cgi.walloffsets[id];
if(wo == -1) {
cell *c1 = hybrid::get_where(c).first;
wo = isize(cgi.shWall3D);
int won = wo + c->type;
cgi.reserve_wall3d(won);
for(int i=0; i<c1->type; i++) {
hyperpoint w;
hybrid::in_underlying_geometry([&] {
/* mirror image of C0 in the axis h1-h2 */
hyperpoint h1 = get_corner_position(c1, i);
hyperpoint h2 = get_corner_position(c1, i+1);
transmatrix T = gpushxto0(h1);
T = spintox(T * h2) * T;
w = T * C0;
w[1] = -w[1];
w = inverse(T) * w;
});
cgi.walltester[wo + i] = w;
}
for(int i=0; i<c1->type; i++)
cgi.make_wall(wo + i, {product::get_corner(c1, i, -1), product::get_corner(c1, i, +1), product::get_corner(c1, i+1, +1), product::get_corner(c1, i+1, -1)});
for(int a: {0,1}) {
vector<hyperpoint> l;
int z = a ? 1 : -1;
for(int i=0; i<c1->type; i++)
l.push_back(product::get_corner(c1, i, z));
cgi.make_wall(won-2+a, l);
}
cgi.compute_cornerbonus();
cgi.extra_vertices();
}
return wo;
}
EX bool product_sphere() { return ginf[hybrid::underlying].cclass == gcSphere; }
EX hyperpoint inverse_exp(hyperpoint h) {

View File

@ -803,7 +803,7 @@ void geometry_information::reserve_wall3d(int i) {
void geometry_information::create_wall3d() {
if(WDIM == 2) return;
reserve_wall3d(penrose ? 22 : prod ? 0 : sl2 ? S7+2 : S7);
reserve_wall3d(penrose ? 22 : prod ? 0 : sl2 ? 0 : S7);
if(GDIM == 3 && binarytiling && geometry == gBinary3) {
hyperpoint h00 = point3(-1,-1,-1);
hyperpoint h01 = point3(-1,0,-1);
@ -969,42 +969,6 @@ void geometry_information::create_wall3d() {
}
}
if(geometry == gSL2) {
ld zs = cgi.plevel;
ld a = 2 * M_PI/ S7;
ld tf = cgi.tessf / 2;
ld he = cgi.hexhexdist / 2;
ld A = master_to_c7_angle();
hyperpoint right_u = spin(A) * xpush(tf) * ypush(-he) * zpush0(zs/2);
hyperpoint right_d = spin(A) * xpush(tf) * ypush(-he) * zpush0(-zs/2);
hyperpoint left_u = spin(A) * 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_d = zpush0(-zs/2);
for(int i=0; i<S7; i++) {
auto s =spin(a * i);
make_wall(i, {s * right_u, s * right_d, s * left_d, s * left_u});
}
vector<hyperpoint> top, bot;
for(int i=0; i<S7; i++) {
bot.push_back(center_d);
bot.push_back(spin(a*i) * left_d);
bot.push_back(spin(a*i) * right_d);
bot.push_back(center_d);
bot.push_back(spin(a*i) * right_d);
bot.push_back(spin(a*(i+1)) * left_d);
top.push_back(center_u);
top.push_back(spin(a*i) * left_u);
top.push_back(spin(a*i) * right_u);
top.push_back(center_u);
top.push_back(spin(a*i) * right_u);
top.push_back(spin(a*(i+1)) * left_u);
}
make_wall(S7, bot);
make_wall(S7+1, top);
}
if(geometry == gSol) {
ld zstep = -log(2) / 2;
ld bwh = vid.binary_width * zstep;

View File

@ -1182,7 +1182,7 @@ EX void set_geometry(eGeometry target) {
if(DUAL && geometry != gArchimedean)
variation = ginf[geometry].default_variation;
#if CAP_BT
if(binarytiling || WDIM == 3 || penrose) if(!prod) variation = eVariation::pure;
if(binarytiling || WDIM == 3 || penrose) if(!hybri) variation = eVariation::pure;
#endif
if(GDIM == 3 && old_DIM == 2 && pmodel == mdDisk) pmodel = mdPerspective;
if(nonisotropic && old_DIM == 2) pmodel = mdGeodesic;