Clifford torus embedding (needs to be configured manually and on a straight square for now)
This commit is contained in:
parent
bc96b7fba9
commit
32546cee4a
14
geometry.cpp
14
geometry.cpp
|
@ -1080,7 +1080,7 @@ EX namespace geom3 {
|
||||||
seProduct,
|
seProduct,
|
||||||
seNil,
|
seNil,
|
||||||
seSol, seNIH, seSolN,
|
seSol, seNIH, seSolN,
|
||||||
seNIH_inv
|
seCliffordTorus
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1094,6 +1094,7 @@ EX namespace geom3 {
|
||||||
{"Sol", "Embed into Sol. Works only with Euclidean. You need to set the variation to Pure."},
|
{"Sol", "Embed into Sol. Works only with Euclidean. You need to set the variation to Pure."},
|
||||||
{"stretched hyperbolic", "Embed into stretched hyperbolic geometry. Works only with Euclidean. You need to set the variation to Pure."},
|
{"stretched hyperbolic", "Embed into stretched hyperbolic geometry. Works only with Euclidean. You need to set the variation to Pure."},
|
||||||
{"stretched Sol", "Embed into stretched Sol geometry. Works only with Euclidean. You need to set the variation to Pure."},
|
{"stretched Sol", "Embed into stretched Sol geometry. Works only with Euclidean. You need to set the variation to Pure."},
|
||||||
|
{"Clifford Torus", "Embed Euclidean torus into S3. You need to set the variation to Pure."},
|
||||||
};
|
};
|
||||||
|
|
||||||
EX eSpatialEmbedding spatial_embedding = seDefault;
|
EX eSpatialEmbedding spatial_embedding = seDefault;
|
||||||
|
@ -1132,13 +1133,17 @@ EX namespace geom3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool euc_in_noniso() {
|
EX bool euc_in_noniso() {
|
||||||
return among(ggclass(), gcNil, gcSol, gcNIH, gcSolN) && mgclass() == gcEuclid;
|
return among(ggclass(), gcNil, gcSol, gcNIH, gcSolN, gcSphere) && mgclass() == gcEuclid;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool sph_in_euc() {
|
EX bool sph_in_euc() {
|
||||||
return ggclass() == gcEuclid && mgclass() == gcSphere;
|
return ggclass() == gcEuclid && mgclass() == gcSphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX bool euc_in_sph() {
|
||||||
|
return ggclass() == gcSphere && mgclass() == gcEuclid;
|
||||||
|
}
|
||||||
|
|
||||||
EX bool sph_in_hyp() {
|
EX bool sph_in_hyp() {
|
||||||
return ggclass() == gcHyperbolic && mgclass() == gcSphere;
|
return ggclass() == gcHyperbolic && mgclass() == gcSphere;
|
||||||
}
|
}
|
||||||
|
@ -1220,6 +1225,11 @@ EX namespace geom3 {
|
||||||
g.gameplay_dimension = 2;
|
g.gameplay_dimension = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(spatial_embedding == seCliffordTorus && ieuclid) {
|
||||||
|
g = ginf[gCell120].g;
|
||||||
|
g.gameplay_dimension = 2;
|
||||||
|
}
|
||||||
|
|
||||||
bool ieuc_or_binary = ieuclid || (gi.flags & qBINARY);
|
bool ieuc_or_binary = ieuclid || (gi.flags & qBINARY);
|
||||||
|
|
||||||
if(spatial_embedding == seSol && ieuc_or_binary) {
|
if(spatial_embedding == seSol && ieuc_or_binary) {
|
||||||
|
|
|
@ -442,7 +442,7 @@ EX bool no_easy_spin() {
|
||||||
return NONSTDVAR || arcm::in() || WDIM == 3 || bt::in() || kite::in();
|
return NONSTDVAR || arcm::in() || WDIM == 3 || bt::in() || kite::in();
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool dont_inverse() { return geometry == 1 && PURE && geom3::euc_in_noniso(); }
|
EX bool dont_inverse() { return meuclid && PURE && geom3::euc_in_noniso(); }
|
||||||
|
|
||||||
ld hrmap_standard::spin_angle(cell *c, int d) {
|
ld hrmap_standard::spin_angle(cell *c, int d) {
|
||||||
if(WDIM == 3) return SPIN_NOT_AVAILABLE;
|
if(WDIM == 3) return SPIN_NOT_AVAILABLE;
|
||||||
|
|
|
@ -572,6 +572,15 @@ EX hyperpoint normalize_flat(hyperpoint h) {
|
||||||
if(geom3::euc_in_nil()) h[1] = 0;
|
if(geom3::euc_in_nil()) h[1] = 0;
|
||||||
if(geom3::euc_in_solnih()) h[2] = 0;
|
if(geom3::euc_in_solnih()) h[2] = 0;
|
||||||
if(geom3::hyp_in_solnih()) h[0] = 0;
|
if(geom3::hyp_in_solnih()) h[0] = 0;
|
||||||
|
if(geom3::euc_in_sph()) {
|
||||||
|
ld tx = hypot(h[0], h[2]);
|
||||||
|
ld ty = hypot(h[1], h[3]);
|
||||||
|
h[0] = h[0] / tx * sin(1);
|
||||||
|
h[1] = h[1] / ty * cos(1);
|
||||||
|
h[2] = h[2] / tx * sin(1);
|
||||||
|
h[3] = h[3] / ty * cos(1);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
if(geom3::euc_in_hyp()) {
|
if(geom3::euc_in_hyp()) {
|
||||||
h = normalize(h);
|
h = normalize(h);
|
||||||
auto h1 = deparabolic13(h);
|
auto h1 = deparabolic13(h);
|
||||||
|
@ -837,6 +846,19 @@ EX hyperpoint orthogonal_move(const hyperpoint& h, ld z) {
|
||||||
hf[3] = cosh(z0 + z);
|
hf[3] = cosh(z0 + z);
|
||||||
return hf;
|
return hf;
|
||||||
}
|
}
|
||||||
|
if(geom3::euc_in_sph()) {
|
||||||
|
// cspin(0,2,x) * cspin(1,3,y) * cspin0(2, 3, z)
|
||||||
|
ld tx = hypot(h[0], h[2]);
|
||||||
|
ld ty = hypot(h[1], h[3]);
|
||||||
|
ld z0 = atan2(ty, tx);
|
||||||
|
z0 -= z;
|
||||||
|
hyperpoint hf;
|
||||||
|
hf[0] = h[0] / tx * cos(z0);
|
||||||
|
hf[1] = h[1] / ty * sin(z0);
|
||||||
|
hf[2] = h[2] / tx * cos(z0);
|
||||||
|
hf[3] = h[3] / ty * sin(z0);
|
||||||
|
return hf;
|
||||||
|
}
|
||||||
if(GDIM == 2) return scale_point(h, geom3::scale_at_lev(z));
|
if(GDIM == 2) return scale_point(h, geom3::scale_at_lev(z));
|
||||||
if(gproduct) return scale_point(h, exp(z));
|
if(gproduct) return scale_point(h, exp(z));
|
||||||
if(sl2) return slr::translate(h) * cpush0(2, z);
|
if(sl2) return slr::translate(h) * cpush0(2, z);
|
||||||
|
@ -874,6 +896,11 @@ EX transmatrix matrix4(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i, ld
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX void euc_in_sph_rescale(hyperpoint& h) {
|
||||||
|
h[0] *= TAU * geom3::euclid_embed_scale;
|
||||||
|
h[1] *= TAU * geom3::euclid_embed_scale;
|
||||||
|
}
|
||||||
|
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
/** Transform a matrix between the 'embedded_plane' and underlying representation. Switches to the current variant. */
|
/** Transform a matrix between the 'embedded_plane' and underlying representation. Switches to the current variant. */
|
||||||
EX void swapmatrix(transmatrix& T) {
|
EX void swapmatrix(transmatrix& T) {
|
||||||
|
@ -916,6 +943,11 @@ EX void swapmatrix(transmatrix& T) {
|
||||||
else if(geom3::in_product()) {
|
else if(geom3::in_product()) {
|
||||||
/* just do nothing */
|
/* just do nothing */
|
||||||
}
|
}
|
||||||
|
else if(geom3::euc_in_sph()) {
|
||||||
|
hyperpoint h1 = get_column(T, 2);
|
||||||
|
euc_in_sph_rescale(h1);
|
||||||
|
T = cspin(0, 2, h1[0]) * cspin(1, 3, h1[1]);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
for(int i=0; i<4; i++) swap(T[i][2], T[i][3]);
|
for(int i=0; i<4; i++) swap(T[i][2], T[i][3]);
|
||||||
for(int i=0; i<4; i++) swap(T[2][i], T[3][i]);
|
for(int i=0; i<4; i++) swap(T[2][i], T[3][i]);
|
||||||
|
@ -934,6 +966,10 @@ EX void swapmatrix(hyperpoint& h) {
|
||||||
if(geom3::sph_in_euc()) { h[3] = 1; return; }
|
if(geom3::sph_in_euc()) { h[3] = 1; return; }
|
||||||
if(geom3::sph_in_hyp()) { h[0] *= sinh(1); h[1] *= sinh(1); h[2] *= sinh(1); h[3] = cosh(1); return; }
|
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_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_sph()) {
|
||||||
|
euc_in_sph_rescale(h); h = cspin(0, 2, h[0]) * cspin(1, 3, h[1]) * lzpush(1) * C0;
|
||||||
|
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::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()) {
|
if(geom3::hyp_in_solnih()) {
|
||||||
// copied from deparabolic13
|
// copied from deparabolic13
|
||||||
|
@ -1524,12 +1560,14 @@ EX hyperpoint scale_point(const hyperpoint& h, ld scale_factor) {
|
||||||
EX bool moved_center() {
|
EX bool moved_center() {
|
||||||
if(geom3::sph_in_euc()) return true;
|
if(geom3::sph_in_euc()) return true;
|
||||||
if(geom3::sph_in_hyp()) return true;
|
if(geom3::sph_in_hyp()) return true;
|
||||||
|
if(geom3::euc_in_sph()) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the intended center of the tile, relative to its local matrix. Usually C0 but may be different, e.g. when embedding a sphere in E3 or H3. */
|
/** Returns the intended center of the tile, relative to its local matrix. Usually C0 but may be different, e.g. when embedding a sphere in E3 or H3. */
|
||||||
EX hyperpoint tile_center() {
|
EX hyperpoint tile_center() {
|
||||||
if(geom3::sph_in_euc()) return C02 + C03;
|
if(geom3::sph_in_euc()) return C02 + C03;
|
||||||
|
if(geom3::euc_in_sph()) return zpush0(1);
|
||||||
if(geom3::sph_in_hyp()) return zpush0(1);
|
if(geom3::sph_in_hyp()) return zpush0(1);
|
||||||
return C0;
|
return C0;
|
||||||
}
|
}
|
||||||
|
|
11
hypgraph.cpp
11
hypgraph.cpp
|
@ -2028,7 +2028,7 @@ EX void adjust_eye(transmatrix& T, cell *c, ld sign) {
|
||||||
geom3::do_auto_eye();
|
geom3::do_auto_eye();
|
||||||
int sl = snakelevel(c);
|
int sl = snakelevel(c);
|
||||||
if(isWorm(c->monst) && sl < 3) sl++;
|
if(isWorm(c->monst) && sl < 3) sl++;
|
||||||
int i = geom3::sph_in_low() ? 1 : 0;
|
int i = moved_center() ? 1 : 0;
|
||||||
if(sl || vid.eye || i)
|
if(sl || vid.eye || i)
|
||||||
T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i));
|
T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i));
|
||||||
}
|
}
|
||||||
|
@ -2917,7 +2917,7 @@ EX namespace dq {
|
||||||
EX set<unsigned> visited_by_matrix;
|
EX set<unsigned> visited_by_matrix;
|
||||||
EX void enqueue_by_matrix(heptagon *h, const shiftmatrix& T) {
|
EX void enqueue_by_matrix(heptagon *h, const shiftmatrix& T) {
|
||||||
if(!h) return;
|
if(!h) return;
|
||||||
unsigned b = bucketer(tC0(T));
|
unsigned b = bucketer(T * tile_center());
|
||||||
if(visited_by_matrix.count(b)) { return; }
|
if(visited_by_matrix.count(b)) { return; }
|
||||||
visited_by_matrix.insert(b);
|
visited_by_matrix.insert(b);
|
||||||
drawqueue.emplace(h, T);
|
drawqueue.emplace(h, T);
|
||||||
|
@ -2934,7 +2934,7 @@ EX namespace dq {
|
||||||
|
|
||||||
EX void enqueue_by_matrix_c(cell *c, const shiftmatrix& T) {
|
EX void enqueue_by_matrix_c(cell *c, const shiftmatrix& T) {
|
||||||
if(!c) return;
|
if(!c) return;
|
||||||
unsigned b = bucketer(tC0(T));
|
unsigned b = bucketer(T * tile_center());
|
||||||
if(visited_by_matrix.count(b)) { return; }
|
if(visited_by_matrix.count(b)) { return; }
|
||||||
visited_by_matrix.insert(b);
|
visited_by_matrix.insert(b);
|
||||||
drawqueue_c.emplace(c, T);
|
drawqueue_c.emplace(c, T);
|
||||||
|
@ -3368,6 +3368,11 @@ EX transmatrix map_relative_push(hyperpoint h) {
|
||||||
geom3::light_flip(false);
|
geom3::light_flip(false);
|
||||||
return T * zpush(z);
|
return T * zpush(z);
|
||||||
}
|
}
|
||||||
|
if(geom3::euc_in_sph()) {
|
||||||
|
ld tx = hypot(h[0], h[2]);
|
||||||
|
ld ty = hypot(h[1], h[3]);
|
||||||
|
return cspin(0, 2, atan2(h[0], h[2])) * cspin(1, 3, atan2(h[1], h[3])) * cspin(2, 3, atan2(tx, ty));
|
||||||
|
}
|
||||||
return rgpushxto0(h);
|
return rgpushxto0(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue