mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
125 lines
3.1 KiB
C++
125 lines
3.1 KiB
C++
|
// Hyperbolic Rogue
|
||
|
// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details
|
||
|
|
||
|
// geometrical constants
|
||
|
|
||
|
ld tessf, crossf, hexf;
|
||
|
|
||
|
#define ALPHA (M_PI*2/7)
|
||
|
|
||
|
hyperpoint Crad[42];
|
||
|
|
||
|
transmatrix heptmove[7], hexmove[7];
|
||
|
|
||
|
void precalc() {
|
||
|
|
||
|
ld fmin = 1, fmax = 2;
|
||
|
|
||
|
for(int p=0; p<100; p++) {
|
||
|
ld f = (fmin+fmax) / 2;
|
||
|
hyperpoint H = xpush(f) * C0;
|
||
|
ld v1 = intval(H, C0), v2 = intval(H, spin(2*M_PI/7)*H);
|
||
|
if(v1 > v2) fmin = f; else fmax = f;
|
||
|
}
|
||
|
tessf = fmin;
|
||
|
|
||
|
fmin = 0, fmax = 2;
|
||
|
for(int p=0; p<100; p++) {
|
||
|
ld f = (fmin+fmax) / 2;
|
||
|
hyperpoint H = spin(M_PI/7) * xpush(f) * C0;
|
||
|
ld v1 = intval(H, C0), v2 = intval(H, xpush(tessf) * C0);
|
||
|
if(v1 < v2) fmin = f; else fmax = f;
|
||
|
}
|
||
|
crossf = fmin;
|
||
|
|
||
|
fmin = 0, fmax = tessf;
|
||
|
for(int p=0; p<100; p++) {
|
||
|
ld f = (fmin+fmax) / 2;
|
||
|
hyperpoint H = xpush(f) * C0;
|
||
|
hyperpoint H1 = spin(2*M_PI/7) * H;
|
||
|
hyperpoint H2 = xpush(tessf-f) * C0;
|
||
|
ld v1 = intval(H, H1), v2 = intval(H, H2);
|
||
|
if(v1 < v2) fmin = f; else fmax = f;
|
||
|
}
|
||
|
hexf = fmin;
|
||
|
|
||
|
for(int i=0; i<42; i++)
|
||
|
Crad[i] = spin(2*M_PI*i/42) * xpush(.4) * C0;
|
||
|
for(int d=0; d<7; d++)
|
||
|
heptmove[d] = spin(-d * ALPHA) * xpush(tessf) * spin(M_PI);
|
||
|
for(int d=0; d<7; d++)
|
||
|
hexmove[d] = spin(-d * ALPHA) * xpush(-crossf)* spin(M_PI);
|
||
|
|
||
|
}
|
||
|
|
||
|
transmatrix ddi(ld dir, ld dist) {
|
||
|
// EUCLIDEAN
|
||
|
if(euclid)
|
||
|
return eupush(cos(M_PI*dir/42) * dist, -sin(M_PI*dir/42) * dist);
|
||
|
else
|
||
|
return spin(M_PI*dir/42) * xpush(dist) * spin(-M_PI*dir/42);
|
||
|
}
|
||
|
|
||
|
// tesselation drawing
|
||
|
|
||
|
#define NUMFACE 500
|
||
|
transmatrix tess[NUMFACE];
|
||
|
|
||
|
void genTesselation() {
|
||
|
int N = 1;
|
||
|
tess[0] = Id;
|
||
|
for(int i=0; i<N; i++) {
|
||
|
for(int t=0; t<7; t++) {
|
||
|
ld trot = (t % 8) * M_PI * 2 / 7.0;
|
||
|
transmatrix T = spin(trot) * xpush(tessf) * /*spin(-trot) */ spin(M_PI) * tess[i];
|
||
|
for(int j=0; j<N; j++) if(intval(T*C0, tess[j]*C0) < 0.1) goto nextt;
|
||
|
// printf("%d:%d -> %d\n", i,t, N);
|
||
|
tess[N] = T; N++;
|
||
|
if(N == NUMFACE) return;
|
||
|
nextt: ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct ltd {
|
||
|
hyperpoint P1;
|
||
|
hyperpoint P2;
|
||
|
int col;
|
||
|
};
|
||
|
|
||
|
vector<ltd> lines;
|
||
|
|
||
|
void addline(hyperpoint P1, hyperpoint P2, int col) {
|
||
|
ltd L;
|
||
|
L.P1 = P1; L.P2 = P2; L.col = col;
|
||
|
lines.push_back(L);
|
||
|
}
|
||
|
|
||
|
void addlines() {
|
||
|
|
||
|
// change the if(0) conditions to see the underlying structure
|
||
|
|
||
|
if(0) for(int t =0; t<NUMFACE; t++) for(int u=1; u<8; u++) {
|
||
|
addline(View * tess[t] * C0, View * tess[t] * tess[u] * C0, u==1 ? 0xA000 : 0x4000);
|
||
|
}
|
||
|
|
||
|
if(0) for(int t =0; t<NUMFACE; t++) for(int r=0; r<7; r++) {
|
||
|
addline(
|
||
|
View * tess[t] * spin((2*r+1)*M_PI/7) * xpush(crossf) * C0,
|
||
|
View * tess[t] * spin((2*r+3)*M_PI/7) * xpush(crossf) * C0,
|
||
|
0x808080);
|
||
|
}
|
||
|
|
||
|
if(1) for(int t =0; t<NUMFACE; t++) for(int r=0; r<7; r++) {
|
||
|
addline(tess[t] * spin(M_PI*2*(r+1)/7) * xpush(hexf) * C0, tess[t] * spin(M_PI*2*r/7) * xpush(hexf) * C0, 0x404040);
|
||
|
addline(tess[t] * spin(M_PI*2*r/7) * xpush(hexf) * C0, tess[t] * spin(M_PI*2*r/7) * xpush(tessf/2) * C0, 0x404040);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void initgeo() {
|
||
|
precalc();
|
||
|
genTesselation();
|
||
|
addlines();
|
||
|
}
|