mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-22 23:17:04 +00:00
refactored map functions: ddspin, iddspin, spacedist, spin_angle, virtualRebase[simple], adj
This commit is contained in:
parent
4e534261f0
commit
aeaaf7586a
@ -555,7 +555,7 @@ struct hrmap_archimedean : hrmap {
|
||||
dynamicval<eGeometry> g(geometry, gNormal);
|
||||
dynamicval<hrmap*> cm(currentmap, current_altmap);
|
||||
U = T;
|
||||
virtualRebaseSimple(alt, T);
|
||||
current_altmap->virtualRebase(alt, T);
|
||||
U = U * inverse(T);
|
||||
}
|
||||
|
||||
@ -655,7 +655,21 @@ struct hrmap_archimedean : hrmap {
|
||||
}
|
||||
return gm * where;
|
||||
}
|
||||
|
||||
|
||||
ld spin_angle(cell *c, int d) {
|
||||
if(PURE) {
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d-1);
|
||||
return -(t1.first + M_PI / c->type);
|
||||
}
|
||||
else if(DUAL) {
|
||||
auto& t1 = arcm::current.get_triangle(c->master, 2*d);
|
||||
return -t1.first;
|
||||
}
|
||||
else { /* BITRUNCATED */
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d);
|
||||
return -t1.first;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EX hrmap *new_map() { return new hrmap_archimedean; }
|
||||
|
@ -586,7 +586,7 @@ EX void resetGL() {
|
||||
}
|
||||
#endif
|
||||
check_cgi();
|
||||
cgi.require_shapes();
|
||||
if(currentmap) cgi.require_shapes();
|
||||
#if MAXMDIM >= 4
|
||||
if(GDIM == 3 && !floor_textures) make_floor_textures();
|
||||
#endif
|
||||
|
@ -192,6 +192,8 @@ EX namespace binary {
|
||||
|
||||
int nextdir(int choices) { return directions_generator() % choices; }
|
||||
|
||||
heptagon *getOrigin() override { return origin; }
|
||||
|
||||
hrmap_binary() {
|
||||
set_seed();
|
||||
origin = hyperbolic_origin();
|
||||
@ -427,58 +429,38 @@ EX namespace binary {
|
||||
if(!do_draw(c, V)) continue;
|
||||
drawcell(c, V);
|
||||
|
||||
if(geometry == gBinaryTiling) {
|
||||
dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
|
||||
dq::enqueue(h->move(bd_right), V * parabolic(1));
|
||||
dq::enqueue(h->move(bd_left), V * parabolic(-1));
|
||||
if(c->type == 6)
|
||||
dq::enqueue(h->move(bd_down), V * xpush(log(2)));
|
||||
if(c->type == 7) {
|
||||
dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2)));
|
||||
dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i=0; i<S7; i++)
|
||||
dq::enqueue(h->move(i), V * tmatrix(h, i));
|
||||
}
|
||||
for(int i=0; i<h->type; i++)
|
||||
dq::enqueue(h->cmove(i), V * adj(h, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// hrmap_standard overrides hrmap's default, override it back
|
||||
virtual transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override {
|
||||
return relative_matrix(c2->master, c1->master);
|
||||
}
|
||||
|
||||
int updir_at(heptagon *h) {
|
||||
if(geometry != gBinaryTiling) return updir();
|
||||
else if(type_of(h) == 6) return bd_down;
|
||||
else if(mapside(h) == 1) return bd_left;
|
||||
else if(mapside(h) == -1) return bd_right;
|
||||
else throw "unknown updir";
|
||||
}
|
||||
|
||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) override {
|
||||
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
||||
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
|
||||
transmatrix gm = Id, where = Id;
|
||||
while(h1 != h2) {
|
||||
int up_step = updir();
|
||||
if(h1->distance <= h2->distance) {
|
||||
if(geometry != gBinaryTiling)
|
||||
where = itmatrix(h2, up_step) * where, h2 = may_create_step(h2, up_step);
|
||||
else {
|
||||
if(type_of(h2) == 6)
|
||||
h2 = may_create_step(h2, bd_down), where = xpush(-log(2)) * where;
|
||||
else if(mapside(h2) == 1)
|
||||
h2 = may_create_step(h2, bd_left), where = parabolic(+1) * where;
|
||||
else if(mapside(h2) == -1)
|
||||
h2 = may_create_step(h2, bd_right), where = parabolic(-1) * where;
|
||||
}
|
||||
int d = updir_at(h2);
|
||||
where = iadj(h2, d) * where;
|
||||
h2 = may_create_step(h2, d);
|
||||
}
|
||||
else {
|
||||
if(geometry != gBinaryTiling)
|
||||
gm = gm * tmatrix(h1, up_step), h1 = may_create_step(h1, up_step);
|
||||
else {
|
||||
if(type_of(h1) == 6)
|
||||
h1 = may_create_step(h1, bd_down), gm = gm * xpush(log(2));
|
||||
else if(mapside(h1) == 1)
|
||||
h1 = may_create_step(h1, bd_left), gm = gm * parabolic(-1);
|
||||
else if(mapside(h1) == -1)
|
||||
h1 = may_create_step(h1, bd_right), gm = gm * parabolic(+1);
|
||||
}
|
||||
int d = updir_at(h1);
|
||||
gm = gm * adj(h1, d);
|
||||
h1 = may_create_step(h1, d);
|
||||
}
|
||||
}
|
||||
return gm * where;
|
||||
@ -525,6 +507,79 @@ EX namespace binary {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ld spin_angle(cell *c, int d) {
|
||||
if(WDIM == 3 || geometry == gBinary4 || geometry == gTernary) {
|
||||
return hrmap::spin_angle(c, d);
|
||||
}
|
||||
if(d == NODIR) return 0;
|
||||
if(d == c->type-1) d++;
|
||||
return -(d+2)*M_PI/4;
|
||||
}
|
||||
|
||||
const transmatrix adj(heptagon *h, int dir) {
|
||||
if(geometry == gBinaryTiling) switch(dir) {
|
||||
case bd_up: return xpush(-log(2));
|
||||
case bd_left: return parabolic(-1);
|
||||
case bd_right: return parabolic(+1);
|
||||
case bd_down:
|
||||
if(h->type == 6) return xpush(log(2));
|
||||
/* case bd_down_left: */
|
||||
return parabolic(-1) * xpush(log(2));
|
||||
case bd_down_right:
|
||||
return parabolic(+1) * xpush(log(2));
|
||||
case bd_up_left:
|
||||
return xpush(-log(2)) * parabolic(-1);
|
||||
case bd_up_right:
|
||||
return xpush(-log(2)) * parabolic(1);
|
||||
default:
|
||||
throw "unknown direction";
|
||||
}
|
||||
else if(use_direct_for(dir))
|
||||
return direct_tmatrix[dir];
|
||||
else {
|
||||
h->cmove(dir);
|
||||
return inverse_tmatrix[h->c.spin(dir)];
|
||||
}
|
||||
}
|
||||
|
||||
const transmatrix iadj(heptagon *h, int dir) { heptagon *h1 = h->cmove(dir); return adj(h1, h->c.spin(dir)); }
|
||||
|
||||
transmatrix adj(cell *c, int dir) { return adj(c->master, dir); }
|
||||
|
||||
void virtualRebase(heptagon*& base, transmatrix& at) override {
|
||||
|
||||
while(true) {
|
||||
|
||||
double currz = at[LDIM][LDIM];
|
||||
|
||||
heptagon *h = base;
|
||||
|
||||
heptagon *newbase = NULL;
|
||||
|
||||
transmatrix bestV;
|
||||
|
||||
for(int d=0; d<S7; d++) {
|
||||
transmatrix V2 = iadj(h, d) * at;
|
||||
double newz = V2[LDIM][LDIM];
|
||||
if(newz < currz) {
|
||||
currz = newz;
|
||||
bestV = V2;
|
||||
newbase = h->cmove(d);
|
||||
}
|
||||
}
|
||||
|
||||
if(newbase) {
|
||||
base = newbase;
|
||||
at = bestV;
|
||||
continue;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
~hrmap_binary() { clearfrom(origin); }
|
||||
};
|
||||
|
||||
EX hrmap *new_map() { return new hrmap_binary; }
|
||||
@ -537,8 +592,8 @@ EX namespace binary {
|
||||
|
||||
EX hrmap *new_alt_map(heptagon *o) { return new hrmap_binary(o); }
|
||||
|
||||
transmatrix direct_tmatrix[14];
|
||||
transmatrix inverse_tmatrix[14];
|
||||
EX transmatrix direct_tmatrix[14];
|
||||
EX transmatrix inverse_tmatrix[14];
|
||||
|
||||
int use_direct;
|
||||
// directions in the 'use_direct' mask are taken from direct_tmatrix;
|
||||
@ -663,24 +718,6 @@ EX namespace binary {
|
||||
inverse_tmatrix[i] = inverse(direct_tmatrix[i]);
|
||||
}
|
||||
|
||||
EX const transmatrix& tmatrix(heptagon *h, int dir) {
|
||||
if(use_direct_for(dir))
|
||||
return direct_tmatrix[dir];
|
||||
else {
|
||||
h->cmove(dir);
|
||||
return inverse_tmatrix[h->c.spin(dir)];
|
||||
}
|
||||
}
|
||||
|
||||
EX const transmatrix& itmatrix(heptagon *h, int dir) {
|
||||
if(use_direct_for(dir))
|
||||
return inverse_tmatrix[dir];
|
||||
else {
|
||||
h->cmove(dir);
|
||||
return h->cmove(dir), direct_tmatrix[h->c.spin(dir)];
|
||||
}
|
||||
}
|
||||
|
||||
#if MAXMDIM == 4
|
||||
|
||||
EX void queuecube(const transmatrix& V, ld size, color_t linecolor, color_t facecolor) {
|
||||
@ -927,38 +964,6 @@ EX int celldistance3(heptagon *c1, heptagon *c2) {
|
||||
}
|
||||
|
||||
EX int celldistance3(cell *c1, cell *c2) { return celldistance3(c1->master, c2->master); }
|
||||
|
||||
EX void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
|
||||
|
||||
while(true) {
|
||||
|
||||
double currz = at[LDIM][LDIM];
|
||||
|
||||
heptagon *h = base;
|
||||
|
||||
heptagon *newbase = NULL;
|
||||
|
||||
transmatrix bestV;
|
||||
|
||||
for(int d=0; d<S7; d++) {
|
||||
transmatrix V2 = itmatrix(h, d) * at;
|
||||
double newz = V2[LDIM][LDIM];
|
||||
if(newz < currz) {
|
||||
currz = newz;
|
||||
bestV = V2;
|
||||
newbase = h->cmove(d);
|
||||
}
|
||||
}
|
||||
|
||||
if(newbase) {
|
||||
base = newbase;
|
||||
at = bestV;
|
||||
continue;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
EX hyperpoint get_horopoint(ld y, ld x) {
|
||||
|
43
cell.cpp
43
cell.cpp
@ -35,11 +35,37 @@ struct hrmap {
|
||||
return relative_matrix(c2->master, c1->master);
|
||||
}
|
||||
virtual struct transmatrix adj(cell *c, int i);
|
||||
virtual struct transmatrix iadj(cell *c, int i) { return adj(c->cmove(i), c->c.spin(i)); }
|
||||
struct transmatrix iadj(cell *c, int i) { cell *c1 = c->cmove(i); return adj(c1, c->c.spin(i)); }
|
||||
virtual void draw() {
|
||||
printf("undrawable\n");
|
||||
}
|
||||
virtual vector<hyperpoint> get_vertices(cell*);
|
||||
|
||||
virtual void virtualRebase(heptagon*& base, transmatrix& at) {
|
||||
printf("virtualRebase called unexpectedly\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static constexpr ld SPIN_NOT_AVAILABLE = 1e5;
|
||||
virtual ld spin_angle(cell *c, int d) { return SPIN_NOT_AVAILABLE; }
|
||||
|
||||
virtual transmatrix spin_to(cell *c, int d, ld bonus=0) {
|
||||
ld sa = spin_angle(c, d);
|
||||
if(sa != SPIN_NOT_AVAILABLE) { return spin(bonus + sa); }
|
||||
transmatrix T = rspintox(tC0(adj(c, d)));
|
||||
if(WDIM == 3) return T * cspin(2, 0, bonus);
|
||||
return T * spin(bonus);
|
||||
}
|
||||
|
||||
virtual transmatrix spin_from(cell *c, int d, ld bonus=0) {
|
||||
ld sa = spin_angle(c, d);
|
||||
if(sa != SPIN_NOT_AVAILABLE) { return spin(bonus - sa); }
|
||||
transmatrix T = spintox(tC0(iadj(c, d)));
|
||||
if(WDIM == 3) return T * cspin(2, 0, bonus);
|
||||
return T * spin(bonus);
|
||||
}
|
||||
|
||||
virtual double spacedist(cell *c, int i) { return hdist0(tC0(adj(c, i))); }
|
||||
};
|
||||
|
||||
/** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient */
|
||||
@ -47,6 +73,11 @@ struct hrmap_standard : hrmap {
|
||||
void draw() override;
|
||||
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override;
|
||||
heptagon *create_step(heptagon *h, int direction) override;
|
||||
transmatrix adj(cell *c, int d);
|
||||
transmatrix adj(heptagon *h, int d);
|
||||
transmatrix iadj(heptagon *h, int d) { return adj(h->cmove(d), h->c.spin(d)); }
|
||||
ld spin_angle(cell *c, int d);
|
||||
double spacedist(cell *c, int i) override;
|
||||
};
|
||||
|
||||
void clearfrom(heptagon*);
|
||||
@ -54,20 +85,21 @@ void verifycells(heptagon*);
|
||||
|
||||
struct hrmap_hyperbolic : hrmap_standard {
|
||||
heptagon *origin;
|
||||
eVariation mvar;
|
||||
hrmap_hyperbolic();
|
||||
hrmap_hyperbolic(heptagon *origin);
|
||||
heptagon *getOrigin() override { return origin; }
|
||||
~hrmap_hyperbolic() {
|
||||
// verifycells(origin);
|
||||
// printf("Deleting hyperbolic map: %p\n", this);
|
||||
dynamicval<eVariation> ph(variation, mvar);
|
||||
clearfrom(origin);
|
||||
}
|
||||
void verify() override { verifycells(origin); }
|
||||
void virtualRebase(heptagon*& base, transmatrix& at) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
transmatrix hrmap::adj(cell *c, int i) { return calc_relative_matrix(c->cmove(i), c, C0); }
|
||||
|
||||
vector<cell*>& hrmap::allcells() {
|
||||
static vector<cell*> default_allcells;
|
||||
if(bounded) {
|
||||
@ -109,7 +141,8 @@ EX vector<hrmap*> allmaps;
|
||||
EX hrmap *newAltMap(heptagon *o) { return new hrmap_hyperbolic(o); }
|
||||
// --- hyperbolic geometry ---
|
||||
|
||||
heptagon* hyperbolic_origin() {
|
||||
EX heptagon* hyperbolic_origin() {
|
||||
int odegree = geometry == gBinaryTiling ? 6 : S7;
|
||||
heptagon *origin = tailored_alloc<heptagon> (odegree);
|
||||
heptagon& h = *origin;
|
||||
h.s = hsOrigin;
|
||||
@ -122,7 +155,7 @@ heptagon* hyperbolic_origin() {
|
||||
h.alt = NULL;
|
||||
h.distance = 0;
|
||||
if(IRREGULAR) irr::link_start(origin);
|
||||
h.c7 = newCell(geometry == gBinaryTiling ? 6 : S7, origin);
|
||||
h.c7 = newCell(odegree, origin);
|
||||
return origin;
|
||||
}
|
||||
|
||||
|
@ -2047,7 +2047,7 @@ void celldrawer::draw_wall_full() {
|
||||
color_t col = (highwall(c) || c->wall == waTower) ? wcol : fcol;
|
||||
if(!chasmg) {
|
||||
|
||||
#define D(v) darkena(gradient(0, col, 0, v * (sphere ? spherity(V * cellrelmatrix(c,i)) : 1), 1), fd, 0xFF)
|
||||
#define D(v) darkena(gradient(0, col, 0, v * (sphere ? spherity(V * currentmap->adj(c,i)) : 1), 1), fd, 0xFF)
|
||||
// #define D(v) darkena(col, fd, 0xFF)
|
||||
|
||||
if(sha & 1) {
|
||||
@ -2242,9 +2242,8 @@ void celldrawer::add_map_effects() {
|
||||
if(tim > 1000) tim = 800;
|
||||
if(elec::havecharge && tim > 400) tim = 400;
|
||||
for(int t=0; t<c->type; t++) if(c->move(t) && c->move(t)->ligon) {
|
||||
ld hdir = displayspin(c, t);
|
||||
int lcol = darkena(gradient(iinf[itOrbLightning].color, 0, 0, tim, 1100), 0, 0xFF);
|
||||
queueline(V*chei(xspinpush(ticks * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(xspinpush(hdir, cgi.crossf), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality);
|
||||
queueline(V*chei(xspinpush(ticks * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(currentmap->adj(c, t), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2252,8 +2251,9 @@ void celldrawer::add_map_effects() {
|
||||
whirlwind::calcdirs(c);
|
||||
|
||||
for(int i=0; i<whirlwind::qdirs; i++) {
|
||||
ld hdir0 = displayspin(c, whirlwind::dfrom[i]) + M_PI;
|
||||
ld hdir1 = displayspin(c, whirlwind::dto[i]);
|
||||
ld hdir0 = currentmap->spin_angle(c, whirlwind::dfrom[i]) + M_PI;
|
||||
ld hdir1 = currentmap->spin_angle(c, whirlwind::dto[i]);
|
||||
/* todo what if no spin_angle */
|
||||
|
||||
double ph1 = fractick(PURE ? 150 : 75);
|
||||
|
||||
|
@ -342,7 +342,7 @@ template<class T> void build_euclidean_moves(cell *c, int vec, const T& builder)
|
||||
}
|
||||
}
|
||||
|
||||
struct hrmap_euclid_any : hrmap {
|
||||
struct hrmap_euclid_any : hrmap_standard {
|
||||
void draw() override;
|
||||
};
|
||||
|
||||
@ -396,7 +396,7 @@ struct hrmap_torus : hrmap_euclid_any {
|
||||
forCellIdEx(cc, i, c1) {
|
||||
int d1 = celldistance(cc, c2);
|
||||
if(d1 < d) {
|
||||
t = t * cellrelmatrix(c1, i);
|
||||
t = t * adj(c1, i);
|
||||
c1 = cc;
|
||||
d = d1;
|
||||
goto again;
|
||||
|
@ -611,6 +611,17 @@ void geometry_information::generate_floorshapes() {
|
||||
|
||||
DEBBI(DF_POLY, ("generate_floorshapes"));
|
||||
|
||||
heptagon modelh;
|
||||
cell model;
|
||||
model.master = &modelh;
|
||||
model.type = modelh.type = S7;
|
||||
for(int i=0; i<S7; i++) {
|
||||
model.move(i) = &model;
|
||||
modelh.move(i) = &modelh;
|
||||
model.c.setspin(i, i, false);
|
||||
modelh.c.setspin(i, i, false);
|
||||
}
|
||||
|
||||
if(WDIM == 3) ;
|
||||
|
||||
#if CAP_IRR
|
||||
@ -639,12 +650,8 @@ void geometry_information::generate_floorshapes() {
|
||||
#if CAP_BT
|
||||
else if(penrose) {
|
||||
dynamicval<bool> ncor(approx_nearcorner, true);
|
||||
heptagon master;
|
||||
cell model;
|
||||
model.master = &master;
|
||||
model.type = 4;
|
||||
for(int i=0; i<2; i++) {
|
||||
master.s = hstate(i); /* kite/dart shape */
|
||||
modelh.s = hstate(i); /* kite/dart shape */
|
||||
generate_floorshapes_for(i, &model, 0, 0);
|
||||
}
|
||||
}
|
||||
@ -652,15 +659,12 @@ void geometry_information::generate_floorshapes() {
|
||||
|
||||
#if CAP_ARCM
|
||||
else if(archimedean) {
|
||||
heptagon master;
|
||||
cell model;
|
||||
model.master = &master;
|
||||
arcm::parent_index_of(&master) = 0;
|
||||
arcm::parent_index_of(&modelh) = 0;
|
||||
auto &ac = arcm::current;
|
||||
for(int i=0; i<2*ac.N + 2; i++) {
|
||||
arcm::id_of(&master) = i;
|
||||
arcm::id_of(&modelh) = i;
|
||||
model.type = isize(ac.triangles[i]);
|
||||
if(DUAL) model.type /= 2, arcm::parent_index_of(&master) = !(i&1);
|
||||
if(DUAL) model.type /= 2, arcm::parent_index_of(&modelh) = !(i&1);
|
||||
|
||||
if(BITRUNCATED)
|
||||
generate_floorshapes_for(i, &model, !arcm::pseudohept(&model), arcm::pseudohept(&model) ? 0 : 1^(i&1));
|
||||
@ -673,10 +677,6 @@ void geometry_information::generate_floorshapes() {
|
||||
#endif
|
||||
|
||||
else if(geometry == gBinary4) {
|
||||
heptagon modelh;
|
||||
cell model;
|
||||
model.master = &modelh;
|
||||
model.type = S7;
|
||||
for(int i: {0,1}) {
|
||||
modelh.zebraval = i;
|
||||
generate_floorshapes_for(i, &model, 1, 0);
|
||||
@ -684,10 +684,6 @@ void geometry_information::generate_floorshapes() {
|
||||
}
|
||||
|
||||
else if(geometry == gTernary) {
|
||||
heptagon modelh;
|
||||
cell model;
|
||||
model.master = &modelh;
|
||||
model.type = S7;
|
||||
for(int i: {0,1,2}) {
|
||||
modelh.zebraval = i;
|
||||
generate_floorshapes_for(i, &model, 1, 0);
|
||||
@ -695,8 +691,6 @@ void geometry_information::generate_floorshapes() {
|
||||
}
|
||||
|
||||
else if(PURE && geometry != gBinaryTiling && geosupport_football() < 2) {
|
||||
cell model;
|
||||
model.type = S7;
|
||||
generate_floorshapes_for(0, &model, 1, 0);
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ struct geometry_information {
|
||||
ld rhexf;
|
||||
|
||||
transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
|
||||
transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE];
|
||||
transmatrix invhexmove[MAX_EDGE];
|
||||
|
||||
int base_distlimit;
|
||||
|
||||
@ -521,7 +521,6 @@ void geometry_information::prepare_basics() {
|
||||
for(int d=0; d<S7; d++)
|
||||
hexmove[d] = spin(hexshift-d * ALPHA) * xpush(-crossf)* spin(M_PI);
|
||||
|
||||
for(int d=0; d<S7; d++) invheptmove[d] = inverse(heptmove[d]);
|
||||
for(int d=0; d<S7; d++) invhexmove[d] = inverse(hexmove[d]);
|
||||
|
||||
hexhexdist = hdist(xpush0(crossf), xspinpush0(M_PI*2/S7, crossf));
|
||||
|
216
geometry2.cpp
216
geometry2.cpp
@ -69,6 +69,14 @@ EX transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_
|
||||
namespace gp { extern gp::local_info draw_li; }
|
||||
#endif
|
||||
|
||||
transmatrix hrmap_standard::adj(heptagon *h, int d) {
|
||||
transmatrix T = cgi.heptmove[d];
|
||||
if(h->c.mirror(d)) T = T * Mirror;
|
||||
int sp = h->c.spin(d);
|
||||
if(sp) T = T * spin(2*M_PI*sp/S7);
|
||||
return T;
|
||||
}
|
||||
|
||||
transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
|
||||
|
||||
heptagon *h1 = c1->master;
|
||||
@ -91,64 +99,57 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint
|
||||
if(bounded) {
|
||||
transmatrix T;
|
||||
ld bestdist = 1e9;
|
||||
for(int d=0; d<S7; d++) if(h2->move(d)) {
|
||||
int sp = h2->c.spin(d);
|
||||
transmatrix S = cgi.heptmove[sp] * spin(2*M_PI*d/S7);
|
||||
if(h2->c.mirror(d)) S = cgi.heptmove[sp] * Mirror * spin(2*M_PI*d/S7);
|
||||
if(h2->move(d) == h1) {
|
||||
for(int d=0; d<S7; d++) {
|
||||
auto hm = h1->move(d);
|
||||
if(!hm) continue;
|
||||
transmatrix S = adj(h1, d);
|
||||
if(hm == h2) {
|
||||
transmatrix T1 = gm * S * where;
|
||||
auto curdist = hdist(tC0(T1), point_hint);
|
||||
if(curdist < bestdist) T = T1, bestdist = curdist;
|
||||
}
|
||||
if(geometry != gMinimal) for(int e=0; e<S7; e++) if(h2->move(d)->move(e) == h1) {
|
||||
int sp2 = h2->move(d)->c.spin(e);
|
||||
transmatrix T1 = gm * cgi.heptmove[sp2] * spin(2*M_PI*e/S7) * S * where;
|
||||
if(geometry != gMinimal) for(int e=0; e<S7; e++) if(hm->move(e) == h2) {
|
||||
transmatrix T1 = gm * S * adj(hm, e) * where;
|
||||
auto curdist = hdist(tC0(T1), point_hint);
|
||||
if(curdist < bestdist) T = T1, bestdist = curdist;
|
||||
}
|
||||
}
|
||||
if(bestdist < 1e8) return T;
|
||||
}
|
||||
for(int d=0; d<S7; d++) if(h2->move(d) == h1) {
|
||||
int sp = h2->c.spin(d);
|
||||
return gm * cgi.heptmove[sp] * spin(2*M_PI*d/S7) * where;
|
||||
for(int d=0; d<S7; d++) if(h1->move(d) == h2) {
|
||||
return gm * adj(h1, d) * where;
|
||||
}
|
||||
if(among(geometry, gFieldQuotient, gBring, gMacbeath)) {
|
||||
int bestdist = 1000000, bestd = 0;
|
||||
for(int d=0; d<S7; d++) {
|
||||
int dist = celldistance(h2->cmove(d)->c7, c1);
|
||||
int dist = celldistance(h1->cmove(d)->c7, h2->c7);
|
||||
if(dist < bestdist) bestdist = dist, bestd = d;
|
||||
}
|
||||
int sp = h2->c.spin(bestd);
|
||||
where = cgi.heptmove[sp] * spin(2*M_PI*bestd/S7) * where;
|
||||
h2 = h2->move(bestd);
|
||||
gm = gm * adj(h1, bestd);
|
||||
h1 = h1->move(bestd);
|
||||
}
|
||||
#if CAP_CRYSTAL
|
||||
else if(cryst) {
|
||||
for(int d3=0; d3<S7; d3++) {
|
||||
auto h3 = h2->cmove(d3);
|
||||
if(visited.count(h3)) continue;
|
||||
visited.insert(h3);
|
||||
int sp3 = h2->c.spin(d3);
|
||||
transmatrix where3 = cgi.heptmove[sp3] * spin(2*M_PI*d3/S7) * where;
|
||||
ld dist = crystal::space_distance(h3->c7, c1);
|
||||
hbdist[dist].emplace_back(h3, where3);
|
||||
auto hm = h1->cmove(d3);
|
||||
if(visited.count(hm)) continue;
|
||||
visited.insert(hm);
|
||||
ld dist = crystal::space_distance(hm->c7, c2);
|
||||
hbdist[dist].emplace_back(hm, gm * adj(h1, d3));
|
||||
}
|
||||
auto &bestv = hbdist.begin()->second;
|
||||
tie(h2, where) = bestv.back();
|
||||
tie(h1, gm) = bestv.back();
|
||||
bestv.pop_back();
|
||||
if(bestv.empty()) hbdist.erase(hbdist.begin());
|
||||
}
|
||||
#endif
|
||||
else if(h1->distance < h2->distance) {
|
||||
int sp = h2->c.spin(0);
|
||||
where = iadj(h2, 0) * where;
|
||||
h2 = h2->move(0);
|
||||
where = cgi.heptmove[sp] * where;
|
||||
}
|
||||
else {
|
||||
int sp = h1->c.spin(0);
|
||||
gm = gm * adj(h1, 0);
|
||||
h1 = h1->move(0);
|
||||
gm = gm * cgi.invheptmove[sp];
|
||||
}
|
||||
}
|
||||
return gm * where;
|
||||
@ -169,40 +170,6 @@ EX transmatrix &ggmatrix(cell *c) {
|
||||
return t;
|
||||
}
|
||||
|
||||
EX transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) {
|
||||
transmatrix gm = Id;
|
||||
heptagon *h2 = c->master;
|
||||
transmatrix where = Id;
|
||||
if(0);
|
||||
#if CAP_GP
|
||||
else if(GOLDBERG && c != c->master->c7) {
|
||||
auto li = gp::get_local_info(c);
|
||||
where = cgi.gpdata->Tf[li.last_dir][li.relative.first&31][li.relative.second&31][gmod(li.total_dir, S6)];
|
||||
}
|
||||
#endif
|
||||
else if(BITRUNCATED) for(int d=0; d<S7; d++) if(h2->c7->move(d) == c)
|
||||
where = cgi.hexmove[d];
|
||||
// always add to last!
|
||||
while(h1 != h2) {
|
||||
for(int d=0; d<S7; d++) if(h1->move(d) == h2) printf("(adj) ");
|
||||
if(h1->distance < h2->distance) {
|
||||
int sp = h2->c.spin(0);
|
||||
printf("A%d ", sp);
|
||||
h2 = h2->move(0);
|
||||
where = cgi.heptmove[sp] * where;
|
||||
}
|
||||
else {
|
||||
int sp = h1->c.spin(0);
|
||||
printf("B%d ", sp);
|
||||
h1 = h1->move(0);
|
||||
gm = gm * cgi.invheptmove[sp];
|
||||
}
|
||||
}
|
||||
println(hlog, "OK");
|
||||
println(hlog, gm * where);
|
||||
return gm * where;
|
||||
}
|
||||
|
||||
#if HDR
|
||||
struct horo_distance {
|
||||
ld a, b;
|
||||
@ -288,10 +255,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
|
||||
base = hybrid::get_at(w.first, w.second);
|
||||
return;
|
||||
}
|
||||
if(sl2) {
|
||||
virtualRebase_cell(base, at, check);
|
||||
return;
|
||||
}
|
||||
|
||||
if((euclid || sphere) && WDIM == 2) {
|
||||
again:
|
||||
if(euwrap) for(int i=0; i<6; i++) {
|
||||
@ -316,57 +280,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
|
||||
return;
|
||||
}
|
||||
|
||||
at = master_relative(base) * at;
|
||||
base = base->master->c7;
|
||||
|
||||
while(true) {
|
||||
|
||||
horo_distance currz(check(at));
|
||||
|
||||
heptagon *h = base->master;
|
||||
|
||||
cell *newbase = NULL;
|
||||
|
||||
transmatrix bestV;
|
||||
|
||||
if(WDIM == 2 && !binarytiling && !penrose) for(int d=0; d<h->degree(); d++) {
|
||||
heptspin hs(h, d, false);
|
||||
heptspin hs2 = hs + wstep;
|
||||
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * cgi.invheptmove[d];
|
||||
horo_distance newz(check(V2 * at));
|
||||
if(newz < currz) {
|
||||
currz = newz;
|
||||
bestV = V2;
|
||||
newbase = hs2.at->c7;
|
||||
}
|
||||
}
|
||||
|
||||
if(newbase) {
|
||||
base = newbase;
|
||||
at = bestV * at;
|
||||
}
|
||||
else {
|
||||
if(tohex && BITRUNCATED) for(int d=0; d<base->type; d++) {
|
||||
cell *c = createMov(base, d);
|
||||
transmatrix V2 = spin(-base->c.spin(d)*2*M_PI/S6) * cgi.invhexmove[d];
|
||||
horo_distance newz(check(V2 * at));
|
||||
if(newz < currz) {
|
||||
currz = newz;
|
||||
bestV = V2;
|
||||
newbase = c;
|
||||
}
|
||||
}
|
||||
if(newbase) {
|
||||
base = newbase;
|
||||
at = bestV * at;
|
||||
}
|
||||
else at = master_relative(base, true) * at;
|
||||
if(binarytiling || (tohex && (GOLDBERG || IRREGULAR)) || WDIM == 3 || penrose)
|
||||
virtualRebase_cell(base, at, check);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtualRebase_cell(base, at, check);
|
||||
}
|
||||
|
||||
EX void virtualRebase(cell*& base, transmatrix& at, bool tohex) {
|
||||
@ -382,8 +296,7 @@ EX void virtualRebase(cell*& base, hyperpoint& h, bool tohex) {
|
||||
});
|
||||
}
|
||||
|
||||
// works only in geometries similar to the standard one, and only on heptagons
|
||||
EX void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
|
||||
void hrmap_hyperbolic::virtualRebase(heptagon*& base, transmatrix& at) {
|
||||
|
||||
while(true) {
|
||||
|
||||
@ -398,7 +311,7 @@ EX void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
|
||||
for(int d=0; d<S7; d++) {
|
||||
heptspin hs(h, d, false);
|
||||
heptspin hs2 = hs + wstep;
|
||||
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * cgi.invheptmove[d] * at;
|
||||
transmatrix V2 = iadj(h, d) * at;
|
||||
double newz = V2[LDIM][LDIM];
|
||||
if(newz < currz) {
|
||||
currz = newz;
|
||||
@ -421,46 +334,37 @@ EX bool no_easy_spin() {
|
||||
return NONSTDVAR || archimedean || WDIM == 3 || binarytiling || penrose;
|
||||
}
|
||||
|
||||
double hexshiftat(cell *c) {
|
||||
if(binarytiling) return 0;
|
||||
if(ctof(c) && S7==6 && S3 == 4 && BITRUNCATED) return cgi.hexshift + 2*M_PI/S7;
|
||||
if(ctof(c) && (S7==8 || S7 == 4) && S3 == 3 && BITRUNCATED) return cgi.hexshift + 2*M_PI/S7;
|
||||
if(cgi.hexshift && ctof(c)) return cgi.hexshift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EX transmatrix ddspin(cell *c, int d, ld bonus IS(0)) {
|
||||
if(no_easy_spin()) {
|
||||
if(hybri) return PIU( ddspin(c, d, bonus) );
|
||||
transmatrix T = rspintox(tC0(currentmap->adj(c, d)));
|
||||
if(WDIM == 3) return T * cspin(2, 0, bonus);
|
||||
return T * spin(bonus);
|
||||
ld hrmap_standard::spin_angle(cell *c, int d) {
|
||||
ld hexshift = 0;
|
||||
if(ctof(c) && S7==6 && S3 == 4 && BITRUNCATED) hexshift = cgi.hexshift + 2*M_PI/S7;
|
||||
else if(ctof(c) && (S7==8 || S7 == 4) && S3 == 3 && BITRUNCATED) hexshift = cgi.hexshift + 2*M_PI/S7;
|
||||
else if(cgi.hexshift && ctof(c)) hexshift = cgi.hexshift;
|
||||
if(IRREGULAR) {
|
||||
auto id = irr::cellindex[c];
|
||||
auto& vs = irr::cells[id];
|
||||
if(d < 0 || d >= c->type) return 0;
|
||||
auto& p = vs.jpoints[vs.neid[d]];
|
||||
return -atan2(p[1], p[0]) - hexshift;
|
||||
}
|
||||
return spin(displayspin(c, d) + bonus - hexshiftat(c));
|
||||
else if(masterless)
|
||||
return - d * 2 * M_PI / c->type - hexshift;
|
||||
else
|
||||
return M_PI - d * 2 * M_PI / c->type - hexshift;
|
||||
}
|
||||
|
||||
EX transmatrix iddspin(cell *c, int d, ld bonus IS(0)) {
|
||||
if(no_easy_spin()) {
|
||||
if(hybri) return PIU( iddspin(c, d, bonus) );
|
||||
transmatrix T = spintox(tC0(currentmap->iadj(c, d)));
|
||||
if(WDIM == 3) return T * cspin(2, 0, bonus);
|
||||
return T * spin(bonus);
|
||||
}
|
||||
return spin(hexshiftat(c) - displayspin(c, d) + bonus);
|
||||
EX transmatrix ddspin(cell *c, int d, ld bonus IS(0)) { return currentmap->spin_to(c, d, bonus); }
|
||||
EX transmatrix iddspin(cell *c, int d, ld bonus IS(0)) { return currentmap->spin_from(c, d, bonus); }
|
||||
EX ld cellgfxdist(cell *c, int d) { return currentmap->spacedist(c, d); }
|
||||
|
||||
double hrmap_standard::spacedist(cell *c, int i) {
|
||||
if(NONSTDVAR) return hrmap::spacedist(c, i);
|
||||
if(!BITRUNCATED) return cgi.tessf;
|
||||
if(c->type == S6 && (i&1)) return cgi.hexhexdist;
|
||||
return cgi.crossf;
|
||||
}
|
||||
|
||||
EX double cellgfxdist(cell *c, int i) {
|
||||
if(no_easy_spin())
|
||||
return hdist0(tC0(currentmap->adj(c, i)));
|
||||
if(euclid) {
|
||||
if(c->type == 8 && (i&1)) return cgi.crossf * sqrt(2);
|
||||
return cgi.crossf;
|
||||
}
|
||||
return !BITRUNCATED ? cgi.tessf : (c->type == 6 && (i&1)) ? cgi.hexhexdist : cgi.crossf;
|
||||
}
|
||||
|
||||
transmatrix hrmap::adj(cell *c, int i) {
|
||||
if(no_easy_spin()) return calc_relative_matrix(c->move(i), c, i);
|
||||
transmatrix hrmap_standard::adj(cell *c, int i) {
|
||||
if(NONSTDVAR) return calc_relative_matrix(c->cmove(i), c, i);
|
||||
double d = cellgfxdist(c, i);
|
||||
transmatrix T = ddspin(c, i) * xpush(d);
|
||||
if(c->c.mirror(i)) T = T * Mirror;
|
||||
@ -469,8 +373,6 @@ transmatrix hrmap::adj(cell *c, int i) {
|
||||
return T;
|
||||
}
|
||||
|
||||
EX transmatrix cellrelmatrix(cell *c, int i) { return currentmap->adj(c, i); }
|
||||
|
||||
EX double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
|
||||
|
||||
EX hyperpoint randomPointIn(int t) {
|
||||
@ -695,7 +597,7 @@ EX hyperpoint farcorner(cell *c, int i, int which) {
|
||||
}
|
||||
#endif
|
||||
|
||||
return cellrelmatrix(c, i) * get_corner_position(c->move(i), (cellwalker(c, i) + wstep + (which?-1:2)).spin);
|
||||
return currentmap->adj(c, i) * get_corner_position(c->move(i), (cellwalker(c, i) + wstep + (which?-1:2)).spin);
|
||||
}
|
||||
|
||||
EX hyperpoint midcorner(cell *c, int i, ld v) {
|
||||
|
80
graph.cpp
80
graph.cpp
@ -305,46 +305,6 @@ void drawLightning(const transmatrix& V) {
|
||||
#endif
|
||||
}
|
||||
|
||||
EX ld displayspin(cell *c, int d) {
|
||||
if(0);
|
||||
#if CAP_ARCM
|
||||
else if(archimedean) {
|
||||
if(PURE) {
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d-1);
|
||||
return -(t1.first + M_PI / c->type);
|
||||
}
|
||||
else if(DUAL) {
|
||||
auto& t1 = arcm::current.get_triangle(c->master, 2*d);
|
||||
return -t1.first;
|
||||
}
|
||||
else { /* BITRUNCATED */
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d);
|
||||
return -t1.first;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
else if(IRREGULAR) {
|
||||
auto id = irr::cellindex[c];
|
||||
auto& vs = irr::cells[id];
|
||||
if(d < 0 || d >= c->type) return 0;
|
||||
auto& p = vs.jpoints[vs.neid[d]];
|
||||
return -atan2(p[1], p[0]);
|
||||
}
|
||||
#endif
|
||||
#if CAP_BT
|
||||
else if(binarytiling) {
|
||||
if(d == NODIR) return 0;
|
||||
if(d == c->type-1) d++;
|
||||
return -(d+2)*M_PI/4;
|
||||
}
|
||||
#endif
|
||||
else if(masterless)
|
||||
return - d * 2 * M_PI / c->type;
|
||||
else
|
||||
return M_PI - d * 2 * M_PI / c->type;
|
||||
}
|
||||
|
||||
#define UNTRANS (GDIM == 3 ? 0x000000FF : 0)
|
||||
|
||||
EX void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
|
||||
@ -386,7 +346,7 @@ EX void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
|
||||
ang %= sword::sword_angles;
|
||||
|
||||
#if CAP_QUEUE || CAP_SHAPES
|
||||
transmatrix Vnow = gmatrix[c] * rgpushxto0(inverse(gmatrix[c]) * tC0(V)) * ddspin(c,0,M_PI); // (IRREGULAR ? ddspin(c,0,M_PI) : spin(-hexshiftat(c)));
|
||||
transmatrix Vnow = gmatrix[c] * rgpushxto0(inverse(gmatrix[c]) * tC0(V)) * ddspin(c,0,M_PI);
|
||||
#endif
|
||||
|
||||
int adj = 1 - ((sword_angles/cwt.at->type)&1);
|
||||
@ -2301,15 +2261,10 @@ double chainAngle(cell *c, transmatrix& V, cell *c2, double dft, const transmatr
|
||||
}
|
||||
|
||||
// equivalent to V = V * spin(-chainAngle(c,V,c2,dft));
|
||||
bool chainAnimation(cell *c, transmatrix& V, cell *c2, int i, ld bonus, const transmatrix &Vwhere, ld& length) {
|
||||
if(!gmatrix0.count(c2)) {
|
||||
V = V * ddspin(c,i,bonus);
|
||||
length = cellgfxdist(c,i);
|
||||
return false;
|
||||
}
|
||||
bool chainAnimation(cell *c, cell *c2, transmatrix& V, const transmatrix &Vwhere, ld& length) {
|
||||
hyperpoint h = C0;
|
||||
if(animations[LAYER_BIG].count(c2)) h = animations[LAYER_BIG][c2].wherenow * h;
|
||||
h = inverse(V) * Vwhere * calc_relative_matrix(c2, c, C0) * h;
|
||||
h = inverse(V) * Vwhere * h;
|
||||
length = hdist0(h);
|
||||
V = V * rspintox(h);
|
||||
return true;
|
||||
@ -2413,15 +2368,17 @@ EX bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, boo
|
||||
|
||||
transmatrix Vb0 = Vb;
|
||||
if(c->mondir != NODIR && GDIM == 3 && isAnyIvy(c)) {
|
||||
queueline(tC0(Vparam), Vparam * tC0(calc_relative_matrix(c->move(c->mondir), c, C0)), (col << 8) + 0xFF, 0);
|
||||
queueline(tC0(Vparam), Vparam * tC0(currentmap->adj(c, c->mondir)), (col << 8) + 0xFF, 0);
|
||||
}
|
||||
else if(c->mondir != NODIR) {
|
||||
|
||||
if(mmmon) {
|
||||
ld length;
|
||||
// cell *c2 = c->move(c->mondir);
|
||||
if(nospinb)
|
||||
chainAnimation(c, Vb, c->move(c->mondir), c->mondir, 0, Vparam, length);
|
||||
cell *c2 = c->move(c->mondir);
|
||||
|
||||
if(nospinb) {
|
||||
chainAnimation(c, c2, Vb, Vparam * currentmap->adj(c, c->mondir), length);
|
||||
}
|
||||
else {
|
||||
Vb = Vb * ddspin(c, c->mondir);
|
||||
length = cellgfxdist(c, c->mondir);
|
||||
@ -2489,10 +2446,10 @@ EX bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, boo
|
||||
}
|
||||
|
||||
else {
|
||||
int hdir = displayspin(c, c->mondir);
|
||||
transmatrix T = Vparam * ddspin(c, c->mondir);
|
||||
color_t col = darkena(0x606020, 0, 0xFF);
|
||||
for(int u=-1; u<=1; u++)
|
||||
queueline(Vparam*xspinpush0(hdir+M_PI/2, u*cgi.crossf/5), Vparam*xspinpush(hdir, cgi.crossf)*xspinpush0(hdir+M_PI/2, u*cgi.crossf/5), col, 2 + vid.linequality);
|
||||
queueline(T*xspinpush0(M_PI/2, u*cgi.crossf/5), T*xspinpush(0, cgi.crossf)*xspinpush0(M_PI/2, u*cgi.crossf/5), col, 2 + vid.linequality);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2550,7 +2507,7 @@ EX bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, boo
|
||||
if(part == 't') {
|
||||
if(nospinb) {
|
||||
ld length;
|
||||
chainAnimation(c, Vb, c2, nd, 0, Vparam, length);
|
||||
chainAnimation(c, c2, Vb, Vparam * currentmap->adj(c, nd), length);
|
||||
Vb = Vb * pispin;
|
||||
}
|
||||
else {
|
||||
@ -2564,15 +2521,16 @@ EX bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, boo
|
||||
else if(true) {
|
||||
if(nospinb) {
|
||||
ld length;
|
||||
chainAnimation(c, Vb, c2, nd, 0, Vparam, length);
|
||||
chainAnimation(c, c2, Vb, Vparam * currentmap->adj(c, nd), length);
|
||||
Vb = Vb * pispin;
|
||||
double ang = chainAngle(c, Vb, c->move(c->mondir), displayspin(c, c->mondir) - displayspin(c, nd), Vparam);
|
||||
double ang = chainAngle(c, Vb, c->move(c->mondir), currentmap->spin_angle(c, c->mondir) - currentmap->spin_angle(c, nd), Vparam);
|
||||
ang /= 2;
|
||||
Vb = Vb * spin(M_PI-ang);
|
||||
}
|
||||
else {
|
||||
ld hdir0 = displayspin(c, nd) + M_PI;
|
||||
ld hdir1 = displayspin(c, c->mondir);
|
||||
/* todo what if no spin_angle */
|
||||
ld hdir0 = currentmap->spin_angle(c, nd) + M_PI;
|
||||
ld hdir1 = currentmap->spin_angle(c, c->mondir);
|
||||
while(hdir1 > hdir0 + M_PI) hdir1 -= 2*M_PI;
|
||||
while(hdir1 < hdir0 - M_PI) hdir1 += 2*M_PI;
|
||||
Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI);
|
||||
@ -2599,7 +2557,7 @@ EX bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, boo
|
||||
int nd = neighborId(c, c2);
|
||||
if(nospinb) {
|
||||
ld length;
|
||||
chainAnimation(c, Vb, c2, nd, 0, Vparam, length);
|
||||
chainAnimation(c, c2, Vb, Vparam * currentmap->adj(c, nd), length);
|
||||
Vb = Vb * pispin;
|
||||
}
|
||||
else {
|
||||
@ -2687,7 +2645,7 @@ EX bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, boo
|
||||
if(c->hitpoints == 0) col = 0x404040;
|
||||
if(nospinb) {
|
||||
ld length;
|
||||
chainAnimation(c, Vb, c->move(c->mondir), c->mondir, 0, Vparam, length);
|
||||
chainAnimation(c, c->move(c->mondir), Vb, Vparam * currentmap->adj(c, c->mondir), length);
|
||||
Vb = Vb * pispin;
|
||||
Vb = Vb * xpush(cgi.tentacle_length - cellgfxdist(c, c->mondir));
|
||||
}
|
||||
|
@ -84,9 +84,7 @@ EX namespace netgen {
|
||||
if(c->type == S7) {
|
||||
for(int i=0; i<c->type; i++) {
|
||||
|
||||
int hdir = displayspin(c, i) + M_PI / S7;
|
||||
|
||||
transmatrix V2 = V * spin(hdir) * xpush(cgi.hexf);
|
||||
transmatrix V2 = V * ddspin(c, i, M_PI/S7) * xpush(cgi.hexf);
|
||||
|
||||
hcenter[ii][i] = V2 * C0;
|
||||
}
|
||||
@ -95,10 +93,8 @@ EX namespace netgen {
|
||||
if(c->type == S6) {
|
||||
for(int i=0; i<c->type; i++) {
|
||||
|
||||
int hdir = displayspin(c, i);
|
||||
|
||||
transmatrix V2 =
|
||||
V * spin(hdir) * xpush(cgi.crossf) * spin(M_PI+M_PI/S7) * xpush(cgi.hexf);
|
||||
V * ddspin(c, i, 0) * xpush(cgi.crossf) * spin(M_PI+M_PI/S7) * xpush(cgi.hexf);
|
||||
|
||||
hcenter[ii][i] = V2 * C0;
|
||||
}
|
||||
|
@ -372,6 +372,10 @@ EX namespace solnihv {
|
||||
default: throw "not nihsolv";
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix adj(cell *c, int d) override {
|
||||
return adjmatrix(d, c->c.spin(d));
|
||||
}
|
||||
|
||||
virtual transmatrix relative_matrix(heptagon *h2, heptagon *h1) override {
|
||||
for(int i=0; i<h1->type; i++) if(h1->move(i) == h2) return adjmatrix(i, h1->c.spin(i));
|
||||
@ -1035,6 +1039,9 @@ EX namespace hybrid {
|
||||
for(auto& p: at) tailored_delete(p.second);
|
||||
}
|
||||
|
||||
virtual transmatrix spin_to(cell *c, int d, ld bonus) { return PIU( currentmap->spin_to(c, d, bonus) ); }
|
||||
virtual transmatrix spin_from(cell *c, int d, ld bonus) { return PIU( currentmap->spin_from(c, d, bonus) ); }
|
||||
|
||||
};
|
||||
|
||||
hrmap_hybrid* hmap() { return (hrmap_hybrid*) currentmap; }
|
||||
@ -1558,7 +1565,7 @@ EX namespace rots {
|
||||
transmatrix Spin;
|
||||
cell *cw = where[c1].first;
|
||||
in_underlying([&] {
|
||||
transmatrix T = cellrelmatrix(cw, i);
|
||||
transmatrix T = adj(cw, i);
|
||||
hyperpoint h = tC0(T);
|
||||
Spin = inverse(gpushxto0(h) * T);
|
||||
d = hr::inverse_exp(h, iTable);
|
||||
|
27
reg3.cpp
27
reg3.cpp
@ -213,6 +213,9 @@ EX namespace reg3 {
|
||||
struct hrmap_quotient3 : hrmap {
|
||||
vector<heptagon*> allh;
|
||||
vector<vector<transmatrix>> tmatrices;
|
||||
|
||||
transmatrix adj(heptagon *h, int d) { return tmatrices[h->fieldval][d]; }
|
||||
transmatrix adj(cell *c, int d) override { return adj(c->master, d); }
|
||||
};
|
||||
|
||||
int encode_coord(const crystal::coord& co) {
|
||||
@ -570,13 +573,13 @@ EX namespace reg3 {
|
||||
dq::enqueue_by_matrix(h->move(d), V * tmatrices[h->fieldval][d]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) override {
|
||||
if(h1 == h2) return Id;
|
||||
int d = hr::celldistance(h2->c7, h1->c7);
|
||||
|
||||
for(int a=0; a<S7; a++) if(hr::celldistance(h1->move(a)->c7, h2->c7) < d)
|
||||
return tmatrices[h1->fieldval][a] * relative_matrix(h2, h1->move(a));
|
||||
return adj(h1, a) * relative_matrix(h2, h1->move(a));
|
||||
|
||||
println(hlog, "error in hrmap_field3:::relative_matrix");
|
||||
return Id;
|
||||
@ -723,7 +726,7 @@ EX namespace reg3 {
|
||||
if(hyperbolic) {
|
||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||
binary::virtualRebaseSimple(alt, T);
|
||||
binary_map->virtualRebase(alt, T);
|
||||
}
|
||||
|
||||
fixmatrix(T);
|
||||
@ -861,15 +864,21 @@ EX namespace reg3 {
|
||||
if(wallopt && isWall3(c) && isize(dq::drawqueue) > 1000) continue;
|
||||
|
||||
for(int i=0; i<S7; i++) if(h->move(i)) {
|
||||
#if CAP_FIELD
|
||||
if(quotient_map) dq::enqueue(h->move(i), V * quotient_map->tmatrices[h->fieldval][i]);
|
||||
else
|
||||
#endif
|
||||
dq::enqueue(h->move(i), V * relative_matrix(h->move(i), h));
|
||||
dq::enqueue(h->move(i), V * adj(h, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix adj(heptagon *h, int d) {
|
||||
#if CAP_FIELD
|
||||
if(quotient_map) return quotient_map->adj(h, d);
|
||||
else
|
||||
#endif
|
||||
return relative_matrix(h->cmove(d), h);
|
||||
}
|
||||
|
||||
transmatrix adj(cell *c, int d) override { return adj(c->master, d); }
|
||||
|
||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) override {
|
||||
auto p1 = reg_gmatrix[h1];
|
||||
auto p2 = reg_gmatrix[h2];
|
||||
@ -1073,7 +1082,7 @@ int dist_alt(cell *c) {
|
||||
#if MAXMDIM >= 4
|
||||
EX cellwalker strafe(cellwalker cw, int j) {
|
||||
hyperpoint hfront = tC0(adjmoves[cw.spin]);
|
||||
transmatrix T = currentmap->relative_matrix(cw.at->cmove(j)->master, cw.at->master);
|
||||
transmatrix T = currentmap->adj(cw.at, j);
|
||||
for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j))
|
||||
if(hdist(hfront, T * tC0(adjmoves[i])) < strafedist + .01)
|
||||
return cellwalker(cw.at->move(j), i);
|
||||
|
2
sky.cpp
2
sky.cpp
@ -85,7 +85,7 @@ void dqi_sky::draw() {
|
||||
transmatrix T1 = Tsh * si.T;
|
||||
do {
|
||||
this_poly.emplace_back(T1 * skypoint, colors[cw.at]);
|
||||
T1 = T1 * cellrelmatrix(cw.at, cw.spin);
|
||||
T1 = T1 * currentmap->adj(cw.at, cw.spin);
|
||||
cw += wstep; cw++;
|
||||
}
|
||||
while(cw != cw0);
|
||||
|
@ -24,10 +24,8 @@ EX vector<int> siblings;
|
||||
|
||||
struct hrmap_spherical : hrmap_standard {
|
||||
heptagon *dodecahedron[12];
|
||||
eVariation mvar;
|
||||
|
||||
hrmap_spherical() {
|
||||
mvar = variation;
|
||||
for(int i=0; i<spherecells(); i++) {
|
||||
heptagon& h = *(dodecahedron[i] = tailored_alloc<heptagon> (S7));
|
||||
h.s = hsOrigin;
|
||||
@ -147,7 +145,6 @@ struct hrmap_spherical : hrmap_standard {
|
||||
heptagon *getOrigin() { return dodecahedron[0]; }
|
||||
|
||||
~hrmap_spherical() {
|
||||
dynamicval<eVariation> ph(variation, mvar);
|
||||
for(int i=0; i<spherecells(); i++) clearHexes(dodecahedron[i]);
|
||||
for(int i=0; i<spherecells(); i++) tailored_delete(dodecahedron[i]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user