mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-09-28 22:10:40 +00:00
flocking:: product geometries
This commit is contained in:
parent
e3a1079a32
commit
2cc1de4a02
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
// press 'o' when flocking active to change the parameters.
|
// press 'o' when flocking active to change the parameters.
|
||||||
|
|
||||||
// (does not yet work in product geometries)
|
|
||||||
|
|
||||||
#ifdef USE_THREADS
|
#ifdef USE_THREADS
|
||||||
#include <thread>
|
#include <thread>
|
||||||
int threads = 1;
|
int threads = 1;
|
||||||
@ -112,7 +110,10 @@ namespace flocking {
|
|||||||
for(int i=0; i<N; i++) {
|
for(int i=0; i<N; i++) {
|
||||||
vertexdata& vd = vdata[i];
|
vertexdata& vd = vdata[i];
|
||||||
// set initial base and at to random cell and random position there
|
// set initial base and at to random cell and random position there
|
||||||
createViz(i, v[hrand(isize(v))], random_spin() * xpush(hrand(100) / 200.));
|
createViz(i, v[hrand(isize(v))], Id);
|
||||||
|
rotate_object(vd.m->pat, vd.m->ori, random_spin());
|
||||||
|
apply_parallel_transport(vd.m->pat, vd.m->ori, xtangent(hrand(100) / 200.));
|
||||||
|
|
||||||
vd.name = its(i+1);
|
vd.name = its(i+1);
|
||||||
vd.cp = dftcolor;
|
vd.cp = dftcolor;
|
||||||
vd.cp.color2 = ((hrand(0x1000000) << 8) + 0xFF) | 0x808080FF;
|
vd.cp.color2 = ((hrand(0x1000000) << 8) + 0xFF) | 0x808080FF;
|
||||||
@ -154,14 +155,20 @@ namespace flocking {
|
|||||||
auto m = vd.m;
|
auto m = vd.m;
|
||||||
|
|
||||||
transmatrix I, Rot;
|
transmatrix I, Rot;
|
||||||
|
bool use_rot = true;
|
||||||
|
|
||||||
if(nonisotropic) {
|
if(prod) {
|
||||||
|
I = inverse(m->at);
|
||||||
|
Rot = inverse(m->ori);
|
||||||
|
}
|
||||||
|
else if(nonisotropic) {
|
||||||
I = gpushxto0(tC0(m->at));
|
I = gpushxto0(tC0(m->at));
|
||||||
Rot = inverse(I * m->at);
|
Rot = inverse(I * m->at);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
I = inverse(m->at);
|
I = inverse(m->at);
|
||||||
Rot = Id;
|
Rot = Id;
|
||||||
|
use_rot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we do all the computations here in the frame of reference
|
// we do all the computations here in the frame of reference
|
||||||
@ -188,7 +195,7 @@ namespace flocking {
|
|||||||
|
|
||||||
// m2's position relative to m (tC0 means *(0,0,1))
|
// m2's position relative to m (tC0 means *(0,0,1))
|
||||||
hyperpoint ac = inverse_exp(tC0(at2), iTable, false);
|
hyperpoint ac = inverse_exp(tC0(at2), iTable, false);
|
||||||
if(nonisotropic) ac = Rot * ac;
|
if(use_rot) ac = Rot * ac;
|
||||||
|
|
||||||
// distance and azimuth to m2
|
// distance and azimuth to m2
|
||||||
ld di = hypot_d(WDIM, ac);
|
ld di = hypot_d(WDIM, ac);
|
||||||
@ -247,6 +254,13 @@ namespace flocking {
|
|||||||
apply_parallel_transport(pats[i], oris[i], xtangent(vels[i] * d));
|
apply_parallel_transport(pats[i], oris[i], xtangent(vels[i] * d));
|
||||||
fixmatrix(pats[i]);
|
fixmatrix(pats[i]);
|
||||||
|
|
||||||
|
/* RogueViz does not correctly rotate them */
|
||||||
|
if(prod) {
|
||||||
|
hyperpoint h = oris[i] * xtangent(1);
|
||||||
|
pats[i] = pats[i] * spin(-atan2(h[1], h[0]));
|
||||||
|
oris[i] = spin(+atan2(h[1], h[0])) * oris[i];
|
||||||
|
}
|
||||||
|
|
||||||
} return 0; });
|
} return 0; });
|
||||||
|
|
||||||
for(int i=0; i<N; i++) {
|
for(int i=0; i<N; i++) {
|
||||||
@ -271,11 +285,24 @@ namespace flocking {
|
|||||||
if(follow == 1) {
|
if(follow == 1) {
|
||||||
gmatrix.clear();
|
gmatrix.clear();
|
||||||
vdata[0].m->pat = View * calc_relative_matrix(vdata[0].m->base, centerover, C0) * vdata[0].m->at;
|
vdata[0].m->pat = View * calc_relative_matrix(vdata[0].m->base, centerover, C0) * vdata[0].m->at;
|
||||||
View = spin(90 * degree) * inverse(vdata[0].m->pat) * View;
|
View = inverse(vdata[0].m->pat) * View;
|
||||||
|
if(prod) {
|
||||||
|
NLP = inverse(vdata[0].m->ori);
|
||||||
|
|
||||||
|
NLP = hr::cspin(1, 2, 90 * degree) * spin(90 * degree) * NLP;
|
||||||
|
|
||||||
|
if(NLP[0][2]) {
|
||||||
|
auto downspin = -atan2(NLP[0][2], NLP[1][2]);
|
||||||
|
NLP = spin(downspin) * NLP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
View =spin(90 * degree) * View;
|
||||||
if(GDIM == 3) {
|
if(GDIM == 3) {
|
||||||
View = hr::cspin(1, 2, 90 * degree) * View;
|
View = hr::cspin(1, 2, 90 * degree) * View;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(follow == 2) {
|
if(follow == 2) {
|
||||||
// we take the average in R^3 of all the boid positions of the Minkowski hyperboloid
|
// we take the average in R^3 of all the boid positions of the Minkowski hyperboloid
|
||||||
@ -283,14 +310,23 @@ namespace flocking {
|
|||||||
// are taken), and normalize the result to project it back to the hyperboloid
|
// are taken), and normalize the result to project it back to the hyperboloid
|
||||||
// (the same method is commonly used on the sphere AFAIK)
|
// (the same method is commonly used on the sphere AFAIK)
|
||||||
hyperpoint h = Hypc;
|
hyperpoint h = Hypc;
|
||||||
bool ok = false;
|
int cnt = 0;
|
||||||
|
ld lev = 0;
|
||||||
for(int i=0; i<N; i++) if(gmatrix.count(vdata[i].m->base)) {
|
for(int i=0; i<N; i++) if(gmatrix.count(vdata[i].m->base)) {
|
||||||
ok = true;
|
|
||||||
vdata[i].m->pat = gmatrix[vdata[i].m->base] * vdata[i].m->at;
|
vdata[i].m->pat = gmatrix[vdata[i].m->base] * vdata[i].m->at;
|
||||||
h += tC0(vdata[i].m->pat);
|
auto h1 = tC0(vdata[i].m->pat);
|
||||||
|
cnt++;
|
||||||
|
if(prod) {
|
||||||
|
auto d1 = product_decompose(h1);
|
||||||
|
lev += d1.first;
|
||||||
|
h += d1.second;
|
||||||
}
|
}
|
||||||
if(ok) {
|
else
|
||||||
h = normalize(h);
|
h += h1;
|
||||||
|
}
|
||||||
|
if(cnt) {
|
||||||
|
h = normalize_flat(h);
|
||||||
|
if(prod) h = zshift(h, lev / cnt);
|
||||||
View = inverse(actual_view_transform) * gpushxto0(h) * actual_view_transform * View;
|
View = inverse(actual_view_transform) * gpushxto0(h) * actual_view_transform * View;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user