binary-like tilings can now be embedded in Solv and variants

This commit is contained in:
Zeno Rogue 2022-12-15 11:43:26 +01:00
parent 7dac26a85a
commit 10e543a44e
5 changed files with 66 additions and 23 deletions

View File

@ -483,19 +483,19 @@ EX namespace bt {
transmatrix adj(heptagon *h, int dir) override {
if(geometry == gBinaryTiling) switch(dir) {
case bd_up: return xpush(-log(2));
case bd_up: return lxpush(-log(2));
case bd_left: return parabolic(-2);
case bd_right: return parabolic(+2);
case bd_down:
if(h->type == 6) return xpush(log(2));
if(h->type == 6) return lxpush(log(2));
/* case bd_down_left: */
return parabolic(-2) * xpush(log(2));
return parabolic(-2) * lxpush(log(2));
case bd_down_right:
return parabolic(+2) * xpush(log(2));
return parabolic(+2) * lxpush(log(2));
case bd_up_left:
return xpush(-log(2)) * parabolic(-2);
return lxpush(-log(2)) * parabolic(-2);
case bd_up_right:
return xpush(-log(2)) * parabolic(2);
return lxpush(-log(2)) * parabolic(2);
default:
throw hr_exception("unknown direction");
}
@ -634,9 +634,9 @@ EX namespace bt {
auto &x = h[0], &y = h[1], &z = h[2];
switch(geometry) {
case gBinaryTiling: case gBinary4:
return bt::parabolic(y) * xpush(x*z2*2);
return bt::parabolic(y) * lxpush(x*z2*2);
case gTernary:
return bt::parabolic(y) * xpush(x*z3*2);
return bt::parabolic(y) * lxpush(x*z3*2);
#if CAP_SOLV
case gSol:
return xpush(bwh*x) * ypush(bwh*y) * zpush(z2*z);
@ -700,16 +700,16 @@ EX namespace bt {
use_direct = (1 << (S7-1)) - 1;
if(geometry == gBinary4) {
use_direct = 3;
direct_tmatrix[0] = xpush(-log(2)) * parabolic(-1);
direct_tmatrix[1] = xpush(-log(2)) * parabolic(+1);
direct_tmatrix[0] = lxpush(-log(2)) * parabolic(-1);
direct_tmatrix[1] = lxpush(-log(2)) * parabolic(+1);
direct_tmatrix[2] = parabolic(2);
direct_tmatrix[4] = parabolic(-2);
use_direct = 1+2+4+16;
}
if(geometry == gTernary) {
direct_tmatrix[0] = xpush(-log(3)) * parabolic(-2);
direct_tmatrix[1] = xpush(-log(3));
direct_tmatrix[2] = xpush(-log(3)) * parabolic(+2);
direct_tmatrix[0] = lxpush(-log(3)) * parabolic(-2);
direct_tmatrix[1] = lxpush(-log(3));
direct_tmatrix[2] = lxpush(-log(3)) * parabolic(+2);
direct_tmatrix[3] = parabolic(2);
direct_tmatrix[5] = parabolic(-2);
use_direct = 1+2+4+8+32;
@ -1027,7 +1027,7 @@ EX int celldistance3(heptagon *c1, heptagon *c2) {
EX int celldistance3(cell *c1, cell *c2) { return celldistance3(c1->master, c2->master); }
EX hyperpoint get_horopoint(ld y, ld x) {
return bt::parabolic(x*2) * xpush(-y) * C0;
return bt::parabolic(x*2) * lxpush(-y) * C0;
}
EX hyperpoint get_horopoint(hyperpoint h) {

View File

@ -321,8 +321,9 @@ void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, ld
hyperpoint h0 = bt::get_corner_horo_coordinates(c, i) * size;
hyperpoint h1 = bt::get_corner_horo_coordinates(c, i+1) * size;
hyperpoint hd = (h1 - h0) / STEP;
transmatrix T = geom3::hyp_in_solnih() ? Id : iddspin_side(c, i);
for(int j=0; j<=STEP; j++)
hpcpush(iddspin_side(c, i) * bt::get_horopoint(h0 + hd * j));
hpcpush(T * bt::get_horopoint(h0 + hd * j));
chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
}

View File

@ -1128,6 +1128,10 @@ EX namespace geom3 {
return among(ggclass(), gcSol, gcNIH, gcSolN) && mgclass() == gcEuclid;
}
EX bool hyp_in_solnih() {
return among(ggclass(), gcSol, gcNIH, gcSolN) && mgclass() == gcHyperbolic;
}
EX bool euc_in_noniso() {
return among(ggclass(), gcNil, gcSol, gcNIH, gcSolN) && nonisotropic;
}
@ -1200,27 +1204,31 @@ EX namespace geom3 {
g.gameplay_dimension = 2;
}
if(spatial_embedding == seNil && euclid) {
bool ieuclid = g.kind == gcEuclid;
if(spatial_embedding == seNil && ieuclid) {
g = ginf[gNil].g;
g.gameplay_dimension = 2;
}
if(spatial_embedding == seSol && euclid) {
bool ieuc_or_binary = ieuclid || (gi.flags & qBINARY);
if(spatial_embedding == seSol && ieuc_or_binary) {
g = ginf[gSol].g;
g.gameplay_dimension = 2;
}
if(spatial_embedding == seNIH && euclid) {
if(spatial_embedding == seNIH && ieuc_or_binary) {
g = ginf[gNIH].g;
g.gameplay_dimension = 2;
}
if(spatial_embedding == seNIH_inv && euclid) {
if(spatial_embedding == seNIH_inv && ieuc_or_binary) {
g = ginf[gNIH].g;
g.gameplay_dimension = 2;
}
if(spatial_embedding == seSolN && euclid) {
if(spatial_embedding == seSolN && ieuc_or_binary) {
g = ginf[gSolN].g;
g.gameplay_dimension = 2;
}

View File

@ -346,12 +346,12 @@ void drawCurse(const shiftmatrix& V, eItem it) {
#define UNTRANS (GDIM == 3 ? 0x000000FF : 0)
EX transmatrix lpispin() {
if(geom3::euc_in_nil()) return spin180();
return pispin;
return spin180();
}
EX const transmatrix& lmirror() {
if(geom3::euc_in_nil()) return MirrorZ;
if(geom3::hyp_in_solnih()) return MirrorZ;
return Mirror;
}
@ -3749,7 +3749,7 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t
else if(sidepar == SIDE_BSHA) prio = PPR::BSHALLOW;
else prio = PPR::REDWALL-2+4*(sidepar-SIDE_SLEV);
if(geom3::euc_in_noniso()) {
if(geom3::euc_in_noniso() || geom3::hyp_in_solnih()) {
draw_shapevec(c, V, qfi.fshape->gpside[sidepar][i], col, prio);
return false;
}

View File

@ -561,6 +561,7 @@ EX hyperpoint normalize_flat(hyperpoint h) {
if(sl2) h = slr::translate(h) * zpush0(-atan2(h[2], h[3]));
if(geom3::euc_in_nil()) h[1] = 0;
if(geom3::euc_in_solnih()) h[2] = 0;
if(geom3::hyp_in_solnih()) h[0] = 0;
if(geom3::euc_in_hyp()) {
h = normalize(h);
auto h1 = deparabolic13(h);
@ -642,6 +643,7 @@ EX transmatrix cspin180(int a, int b) {
EX transmatrix spin(ld alpha) {
if(embedded_plane && geom3::euc_in_hyp() && !destandarize_eih) return cspin(1, 2, alpha);
if(embedded_plane && geom3::euc_in_nil()) return cspin(0, 2, alpha);
if(embedded_plane && geom3::hyp_in_solnih()) return cspin(1, 2, alpha);
return cspin(0, 1, alpha);
}
@ -649,6 +651,7 @@ EX transmatrix spin(ld alpha) {
EX transmatrix spin90() {
if(embedded_plane && geom3::euc_in_hyp() && !destandarize_eih) return cspin90(1, 2);
if(embedded_plane && geom3::euc_in_nil()) return cspin90(0, 2);
if(embedded_plane && geom3::hyp_in_solnih()) return cspin90(1, 2);
return cspin90(0, 1);
}
@ -656,6 +659,7 @@ EX transmatrix spin90() {
EX transmatrix spin180() {
if(embedded_plane && geom3::euc_in_hyp() && !destandarize_eih) return cspin180(1, 2);
if(embedded_plane && geom3::euc_in_nil()) return cspin180(0, 2);
if(embedded_plane && geom3::hyp_in_solnih()) return cspin180(1, 2);
return cspin180(0, 1);
}
@ -663,6 +667,7 @@ EX transmatrix spin180() {
EX transmatrix spin270() {
if(embedded_plane && geom3::euc_in_hyp() && !destandarize_eih) return cspin90(2, 1);
if(embedded_plane && geom3::euc_in_nil()) return cspin90(2, 0);
if(embedded_plane && geom3::hyp_in_solnih()) return cspin90(2, 1);
return cspin90(1, 0);
}
@ -750,6 +755,7 @@ EX transmatrix cpush(int cid, ld alpha) {
EX transmatrix lzpush(ld z) {
if(geom3::euc_in_hyp() && !destandarize_eih) return cpush(0, z);
if(geom3::hyp_in_solnih()) return cpush(0, z);
if(geom3::euc_in_nil()) return cpush(1, z);
return cpush(2, z);
}
@ -804,6 +810,9 @@ EX hyperpoint orthogonal_move(const hyperpoint& h, ld z) {
hf[3] = 1;
return hf;
}
if(geom3::hyp_in_solnih()) {
return nisot::translate(h) * cpush0(0, z);
}
if(geom3::sph_in_hyp()) {
ld z0 = acosh(h[3]);
ld f = sinh(z0 + z) / sinh(z0);
@ -860,6 +869,13 @@ EX void swapmatrix(transmatrix& T) {
for(int i=0; i<4; i++) U[i][3] = U[3][i] = i == 3;
T = parabolic13(mov[0], mov[1]) * U;
}
else if(geom3::hyp_in_solnih()) {
// rotations are illegal anyway...
hyperpoint h = get_column(T, 2);
swapmatrix(h);
T = rgpushxto0(h);
return;
}
else if(geom3::sph_in_euc() || geom3::sph_in_hyp()) {
if(!geom3::flipped) {
for(int i=0; i<4; i++) T[i][3] = T[3][i] = i == 3;
@ -901,6 +917,19 @@ EX void swapmatrix(hyperpoint& h) {
if(geom3::sph_in_hyp()) { h[0] *= sinh(1); h[1] *= sinh(1); h[2] *= sinh(1); h[3] = cosh(1); return; }
if(geom3::euc_in_nil()) { h[3] = 1; h[2] = h[1] * geom3::euclid_embed_scale; h[1] = 0; h[0] *= geom3::euclid_embed_scale; return; }
if(geom3::euc_in_solnih()) { h[3] = 1; h[1] = h[1] * geom3::euclid_embed_scale; h[2] = 0; h[0] *= geom3::euclid_embed_scale; return; }
if(geom3::hyp_in_solnih()) {
// copied from deparabolic13
h /= (1 + h[2]);
h[0] -= 1;
h /= sqhypot_d(2, h);
h[0] += .5;
ld hx = log(2) + log(-h[0]);
if(cgclass == gcNIH) hx /= log(3);
if(cgclass == gcSolN) hx /= log(3);
ld hy = h[1] * 2;
h = point31(0, hy, hx);
return;
}
swap(h[2], h[3]);
if(GDIM == 3) h[2] = 0;
if(geom3::euc_in_hyp()) h = parabolic13(h[0], h[1]) * C0;
@ -910,6 +939,9 @@ EX void swapmatrix(hyperpoint& h) {
EX transmatrix parabolic1(ld u) {
if(euclid)
return ypush(u);
else if(geom3::hyp_in_solnih()) {
return ypush(u);
}
else {
ld diag = u*u/2;
return matrix3(
@ -1026,6 +1058,7 @@ EX transmatrix rspintox(const hyperpoint& H) {
EX transmatrix lspintox(const hyperpoint& H) {
if(geom3::euc_in_nil()) return spintoc(H, 0, 2);
if(geom3::hyp_in_solnih()) return spintoc(H, 1, 2);
if(WDIM == 2 || gproduct) return spintoc(H, 0, 1);
transmatrix T1 = spintoc(H, 0, 1);
return spintoc(T1*H, 0, 2) * T1;
@ -1033,6 +1066,7 @@ EX transmatrix lspintox(const hyperpoint& H) {
EX transmatrix lrspintox(const hyperpoint& H) {
if(geom3::euc_in_nil()) return rspintoc(H, 0, 2);
if(geom3::hyp_in_solnih()) return rspintoc(H, 1, 2);
if(WDIM == 2 || gproduct) return rspintoc(H, 0, 1);
transmatrix T1 = spintoc(H, 0, 1);
return rspintoc(H, 0, 1) * rspintoc(T1*H, 0, 2);