mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-07-05 03:02:49 +00:00
Hypersian Rug now works with other tori/Klein bottles
This commit is contained in:
parent
ead56c9c33
commit
7685868fb2
@ -505,3 +505,15 @@ transmatrix pushone() { return euclid ? eupush(1, 0) : xpush(sphere?.5 : 1); }
|
|||||||
bool operator == (hyperpoint h1, hyperpoint h2) {
|
bool operator == (hyperpoint h1, hyperpoint h2) {
|
||||||
return h1[0] == h2[0] && h1[1] == h2[1] && h1[2] == h2[2];
|
return h1[0] == h2[0] && h1[1] == h2[1] && h1[2] == h2[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rotation matrix in R^3
|
||||||
|
|
||||||
|
transmatrix rotmatrix(double rotation, int c0, int c1) {
|
||||||
|
transmatrix t = Id;
|
||||||
|
t[c0][c0] = cos(rotation);
|
||||||
|
t[c1][c1] = cos(rotation);
|
||||||
|
t[c0][c1] = sin(rotation);
|
||||||
|
t[c1][c0] = -sin(rotation);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
74
rug.cpp
74
rug.cpp
@ -300,7 +300,7 @@ rugpoint *addRugpoint(hyperpoint h, double dist) {
|
|||||||
|
|
||||||
rugpoint *findRugpoint(hyperpoint h) {
|
rugpoint *findRugpoint(hyperpoint h) {
|
||||||
for(int i=0; i<size(points); i++)
|
for(int i=0; i<size(points); i++)
|
||||||
if(intval(points[i]->h, h) < 1e-5) return points[i];
|
if(intvalxyz(points[i]->h, h) < 1e-5) return points[i];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ void buildTorusRug() {
|
|||||||
|
|
||||||
struct toruspoint {
|
struct toruspoint {
|
||||||
int x,y;
|
int x,y;
|
||||||
toruspoint() { x=qty; y=qty; }
|
toruspoint() { x=y=getqty(); }
|
||||||
toruspoint(int _x, int _y) : x(_x), y(_y) {}
|
toruspoint(int _x, int _y) : x(_x), y(_y) {}
|
||||||
int d2() {
|
int d2() {
|
||||||
return x*x+(euclid6?x*y:0)+y*y;
|
return x*x+(euclid6?x*y:0)+y*y;
|
||||||
@ -381,6 +381,13 @@ void buildTorusRug() {
|
|||||||
vector<toruspoint> zeropoints;
|
vector<toruspoint> zeropoints;
|
||||||
vector<toruspoint> tps(qty);
|
vector<toruspoint> tps(qty);
|
||||||
|
|
||||||
|
auto& mode = tmodes[torus_mode];
|
||||||
|
bool single = mode.flags & TF_SINGLE;
|
||||||
|
bool klein = mode.flags & TF_KLEIN;
|
||||||
|
|
||||||
|
pair<toruspoint, toruspoint> solution;
|
||||||
|
|
||||||
|
if(single) {
|
||||||
for(int ax=-qty; ax<qty; ax++)
|
for(int ax=-qty; ax<qty; ax++)
|
||||||
for(int ay=-qty; ay<qty; ay++) {
|
for(int ay=-qty; ay<qty; ay++) {
|
||||||
int v = (ax*dx + ay*dy) % qty;
|
int v = (ax*dx + ay*dy) % qty;
|
||||||
@ -391,7 +398,6 @@ void buildTorusRug() {
|
|||||||
zeropoints.emplace_back(ax, ay);
|
zeropoints.emplace_back(ax, ay);
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<toruspoint, toruspoint> solution;
|
|
||||||
ld bestsol = 1e12;
|
ld bestsol = 1e12;
|
||||||
|
|
||||||
for(auto p1: zeropoints)
|
for(auto p1: zeropoints)
|
||||||
@ -407,11 +413,25 @@ void buildTorusRug() {
|
|||||||
|
|
||||||
if(solution.first.d2() > solution.second.d2())
|
if(solution.first.d2() > solution.second.d2())
|
||||||
swap(solution.first, solution.second);
|
swap(solution.first, solution.second);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(klein)
|
||||||
|
solution.first = toruspoint(2*sdx, 0);
|
||||||
|
else
|
||||||
|
solution.first = toruspoint(sdx, 0);
|
||||||
|
if(mode.flags & TF_WEIRD)
|
||||||
|
solution.second = toruspoint(sdy/2, sdy);
|
||||||
|
else
|
||||||
|
solution.second = toruspoint(0, sdy);
|
||||||
|
|
||||||
|
if(solution.first.d2() > solution.second.d2())
|
||||||
|
swap(solution.first, solution.second);
|
||||||
|
}
|
||||||
|
|
||||||
ld factor = sqrt(ld(solution.second.d2()) / solution.first.d2());
|
ld factor = sqrt(ld(solution.second.d2()) / solution.first.d2());
|
||||||
|
|
||||||
printf("factor = %lf\n", factor);
|
printf("factor = %lf\n", factor);
|
||||||
if(factor < 2) factor = 2.2;
|
if(factor <= 2.05) factor = 2.2;
|
||||||
factor -= 1;
|
factor -= 1;
|
||||||
|
|
||||||
// 22,1
|
// 22,1
|
||||||
@ -421,6 +441,8 @@ void buildTorusRug() {
|
|||||||
transmatrix z1 = {{{(ld)solution.first.x,(ld)solution.second.x,0}, {(ld)solution.first.y,(ld)solution.second.y,0}, {0,0,1}}};
|
transmatrix z1 = {{{(ld)solution.first.x,(ld)solution.second.x,0}, {(ld)solution.first.y,(ld)solution.second.y,0}, {0,0,1}}};
|
||||||
transmatrix z2 = inverse(z1);
|
transmatrix z2 = inverse(z1);
|
||||||
|
|
||||||
|
map<pair<int, int>, rugpoint*> glues;
|
||||||
|
|
||||||
auto addToruspoint = [&] (ld x, ld y) {
|
auto addToruspoint = [&] (ld x, ld y) {
|
||||||
auto r = addRugpoint(C0, 0);
|
auto r = addRugpoint(C0, 0);
|
||||||
hyperpoint onscreen;
|
hyperpoint onscreen;
|
||||||
@ -439,11 +461,15 @@ void buildTorusRug() {
|
|||||||
double beta = -h2[1] * 2 * M_PI;
|
double beta = -h2[1] * 2 * M_PI;
|
||||||
// r->flat = {alpha, beta, 0};
|
// r->flat = {alpha, beta, 0};
|
||||||
double sc = (factor+1)/4;
|
double sc = (factor+1)/4;
|
||||||
|
|
||||||
r->flat = r->h = hpxyz((factor+cos(alpha)) * cos(beta) * sc, (factor+cos(alpha)) * sin(beta) * sc, -sin(alpha) * sc);
|
r->flat = r->h = hpxyz((factor+cos(alpha)) * cos(beta) * sc, (factor+cos(alpha)) * sin(beta) * sc, -sin(alpha) * sc);
|
||||||
r->valid = true;
|
r->valid = true;
|
||||||
rugpoint *r2 = findRugpoint(r->flat);
|
|
||||||
printf("(%lf %lf) %p .. %p\n", x, y, r, r2);
|
static const int X = 100003; // a prime
|
||||||
if(r2 && r2 != r) r->glueto(r2);
|
auto gluefun = [] (ld z) { return int(frac(z + .5/X) * X); };
|
||||||
|
auto p = make_pair(gluefun(h2[0]), gluefun(h2[1]));
|
||||||
|
auto& r2 = glues[p];
|
||||||
|
if(r2) r->glueto(r2); else r2 = r;
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -453,12 +479,30 @@ void buildTorusRug() {
|
|||||||
|
|
||||||
ld rmd = rugmax;
|
ld rmd = rugmax;
|
||||||
|
|
||||||
for(int i=0; i<qty; i++) {
|
for(int leaf=0; leaf<(klein ? 2 : 1); leaf++)
|
||||||
int x = tps[i].x, y = tps[i].y;
|
for(int i=0; i<getqty(); i++) {
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if(single) {
|
||||||
|
x = tps[i].x;
|
||||||
|
y = tps[i].y;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = i % sdx;
|
||||||
|
y = i / sdx;
|
||||||
|
if(x > sdx/2) x -= sdx;
|
||||||
|
if(y > sdy/2) y -= sdy;
|
||||||
|
|
||||||
|
if(leaf) {
|
||||||
|
x += sdx;
|
||||||
|
if(x > sdx) x -= 2 * sdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rugpoint *rugarr[32][32];
|
rugpoint *rugarr[32][32];
|
||||||
for(int yy=0; yy<=rugmax; yy++)
|
for(int yy=0; yy<=rugmax; yy++)
|
||||||
for(int xx=0; xx<=rugmax; xx++)
|
for(int xx=0; xx<=rugmax; xx++)
|
||||||
rugarr[yy][xx] = addToruspoint(x+(xx-yy)/rmd, y+yy/rmd);
|
rugarr[yy][xx] = addToruspoint(x+xx/rmd, y+(yy-xx)/rmd);
|
||||||
|
|
||||||
for(int yy=0; yy<rugmax; yy++)
|
for(int yy=0; yy<rugmax; yy++)
|
||||||
for(int xx=0; xx<rugmax; xx++)
|
for(int xx=0; xx<rugmax; xx++)
|
||||||
@ -1104,15 +1148,6 @@ void drawRugScene() {
|
|||||||
// organization
|
// organization
|
||||||
//--------------
|
//--------------
|
||||||
|
|
||||||
transmatrix rotmatrix(double rotation, int c0, int c1) {
|
|
||||||
transmatrix t = Id;
|
|
||||||
t[c0][c0] = cos(rotation);
|
|
||||||
t[c1][c1] = cos(rotation);
|
|
||||||
t[c0][c1] = sin(rotation);
|
|
||||||
t[c1][c0] = -sin(rotation);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
transmatrix currentrot;
|
transmatrix currentrot;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
@ -1167,7 +1202,6 @@ void actDraw() {
|
|||||||
Uint8 *keystate = SDL_GetKeyState(NULL);
|
Uint8 *keystate = SDL_GetKeyState(NULL);
|
||||||
int qm = 0;
|
int qm = 0;
|
||||||
double alpha = (ticks - lastticks) / 1000.0;
|
double alpha = (ticks - lastticks) / 1000.0;
|
||||||
alpha /= 2.5;
|
|
||||||
lastticks = ticks;
|
lastticks = ticks;
|
||||||
|
|
||||||
transmatrix t = Id;
|
transmatrix t = Id;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user