3d:: 2D/3D is now selectable at runtime

This commit is contained in:
? 2019-02-24 19:40:01 +01:00 committed by Zeno Rogue
parent 1f8510bc71
commit d08e58f404
17 changed files with 208 additions and 232 deletions

View File

@ -4,7 +4,6 @@ namespace hr {
namespace binary { namespace binary {
#if CAP_BT #if CAP_BT
#if DIM == 2
enum bindir { enum bindir {
bd_right = 0, bd_right = 0,
bd_up_right = 1, bd_up_right = 1,
@ -15,20 +14,16 @@ namespace binary {
bd_down_left = 5, /* for cells of degree 7 */ bd_down_left = 5, /* for cells of degree 7 */
bd_down_right = 6 /* for cells of degree 7 */ bd_down_right = 6 /* for cells of degree 7 */
}; };
#endif
int type_of(heptagon *h) { int type_of(heptagon *h) {
return h->c7->type; return h->c7->type;
} }
#if DIM == 2
// 0 - central, -1 - left, +1 - right // 0 - central, -1 - left, +1 - right
int mapside(heptagon *h) { int mapside(heptagon *h) {
return h->zebraval; return h->zebraval;
} }
#endif
#if DIM == 2
#if DEBUG_BINARY_TILING #if DEBUG_BINARY_TILING
map<heptagon*, long long> xcode; map<heptagon*, long long> xcode;
map<long long, heptagon*> rxcode; map<long long, heptagon*> rxcode;
@ -46,7 +41,6 @@ namespace binary {
breakhere(); breakhere();
} }
#endif #endif
#endif
void breakhere() { void breakhere() {
exit(1); exit(1);
@ -83,16 +77,7 @@ namespace binary {
return h1; return h1;
} }
#if DIM == 2
heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) { heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
#else
heptagon *build(heptagon *parent, int d, int d1, int delta) {
int t = 9;
int side = 0;
if(d < 4) side = (parent->zebraval * 2 + d) % 5;
if(d == 8) side = ((parent->zebraval-d1) * 3) % 5;
#endif
auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1); auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1);
h->distance = parent->distance + delta; h->distance = parent->distance + delta;
h->c7 = newCell(t, h); h->c7 = newCell(t, h);
@ -108,8 +93,16 @@ namespace binary {
#endif #endif
return h; return h;
} }
#if MAXDIM==4
heptagon *build3(heptagon *parent, int d, int d1, int delta) {
int side = 0;
if(d < 4) side = (parent->zebraval * 2 + d) % 5;
if(d == 8) side = ((parent->zebraval-d1) * 3) % 5;
return build(parent, d, d1, 9, side, delta);
}
#endif
#if DIM == 2
heptagon *createStep(heptagon *parent, int d) { heptagon *createStep(heptagon *parent, int d) {
auto h = parent; auto h = parent;
switch(d) { switch(d) {
@ -163,15 +156,16 @@ namespace binary {
breakhere(); breakhere();
return NULL; return NULL;
} }
#else
heptagon *createStep(heptagon *parent, int d) { #if MAXDIM==4
heptagon *createStep3(heptagon *parent, int d) {
auto h = parent; auto h = parent;
switch(d) { switch(d) {
case 0: case 1: case 0: case 1:
case 2: case 3: case 2: case 3:
return build(parent, d, 8, 1); return build3(parent, d, 8, 1);
case 8: case 8:
return build(parent, 8, hrand(4), -1); return build3(parent, 8, hrand(4), -1);
case 4: case 4:
parent->cmove(8); parent->cmove(8);
if(parent->c.spin(8) & 1) if(parent->c.spin(8) & 1)
@ -227,7 +221,7 @@ namespace binary {
return direct_tmatrix[dir]; return direct_tmatrix[dir];
} }
#if DIM == 3 #if MAXDIM == 4
void queuecube(const transmatrix& V, ld size, color_t linecolor, color_t facecolor) { void queuecube(const transmatrix& V, ld size, color_t linecolor, color_t facecolor) {
ld yy = log(2) / 2; ld yy = log(2) / 2;
@ -287,29 +281,28 @@ namespace binary {
cell *c = h->c7; cell *c = h->c7;
#if DIM==2 if(DIM == 2 && !do_draw(c, V)) continue;
if(!do_draw(c, V)) continue; if(DIM == 3) {
#endif if(V[DIM][DIM] > btrange_cosh) continue;
#if DIM==3 setdist(c, 7, c);
if(V[DIM][DIM] > btrange_cosh) continue; }
setdist(c, 7, c);
#endif
drawcell(c, V, 0, false); drawcell(c, V, 0, false);
#if DIM==2 if(DIM == 2) {
dq::enqueue(h->move(bd_up), V * xpush(-log(2))); dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
dq::enqueue(h->move(bd_right), V * parabolic(1)); dq::enqueue(h->move(bd_right), V * parabolic(1));
dq::enqueue(h->move(bd_left), V * parabolic(-1)); dq::enqueue(h->move(bd_left), V * parabolic(-1));
if(c->type == 6) if(c->type == 6)
dq::enqueue(h->move(bd_down), V * xpush(log(2))); dq::enqueue(h->move(bd_down), V * xpush(log(2)));
if(c->type == 7) { if(c->type == 7) {
dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2))); 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))); dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2)));
}
}
else {
for(int i=0; i<9; i++)
dq::enqueue(h->move(i), V * tmatrix(h, i));
} }
#else
for(int i=0; i<9; i++)
dq::enqueue(h->move(i), V * tmatrix(h, i));
#endif
} }
} }
@ -319,28 +312,28 @@ namespace binary {
transmatrix gm = Id, where = Id; transmatrix gm = Id, where = Id;
while(h1 != h2) { while(h1 != h2) {
if(h1->distance <= h2->distance) { if(h1->distance <= h2->distance) {
#if DIM==2 if(DIM == 3)
if(type_of(h2) == 6) h2 = hr::createStep(h2, 8), where = inverse(tmatrix(h2, 8)) * where;
h2 = hr::createStep(h2, bd_down), where = xpush(-log(2)) * where; else {
else if(mapside(h2) == 1) if(type_of(h2) == 6)
h2 = hr::createStep(h2, bd_left), where = parabolic(+1) * where; h2 = hr::createStep(h2, bd_down), where = xpush(-log(2)) * where;
else if(mapside(h2) == -1) else if(mapside(h2) == 1)
h2 = hr::createStep(h2, bd_right), where = parabolic(-1) * where; h2 = hr::createStep(h2, bd_left), where = parabolic(+1) * where;
#else else if(mapside(h2) == -1)
h2 = hr::createStep(h2, 8), where = inverse(tmatrix(h2, 8)) * where; h2 = hr::createStep(h2, bd_right), where = parabolic(-1) * where;
#endif }
} }
else { else {
#if DIM==2 if(DIM == 3)
if(type_of(h1) == 6) h1 = hr::createStep(h1, 8), where = where * tmatrix(h1, 8);
h1 = hr::createStep(h1, bd_down), gm = gm * xpush(log(2)); else {
else if(mapside(h1) == 1) if(type_of(h1) == 6)
h1 = hr::createStep(h1, bd_left), gm = gm * parabolic(-1); h1 = hr::createStep(h1, bd_down), gm = gm * xpush(log(2));
else if(mapside(h1) == -1) else if(mapside(h1) == 1)
h1 = hr::createStep(h1, bd_right), gm = gm * parabolic(+1); h1 = hr::createStep(h1, bd_left), gm = gm * parabolic(-1);
#else else if(mapside(h1) == -1)
h1 = hr::createStep(h1, 8), where = where * tmatrix(h1, 8); h1 = hr::createStep(h1, bd_right), gm = gm * parabolic(+1);
#endif }
} }
} }
return gm * where; return gm * where;
@ -360,9 +353,8 @@ auto bt_config = addHook(hooks_args, 0, [] () {
return 1; return 1;
}); });
#endif #endif
#endif
int celldistance(cell *c1, cell *c2) { int celldistance3(cell *c1, cell *c2) {
int steps = 0; int steps = 0;
while(c1 != c2) { while(c1 != c2) {
int d1 = celldistAlt(c1), d2 = celldistAlt(c2); int d1 = celldistAlt(c1), d2 = celldistAlt(c2);
@ -371,6 +363,8 @@ int celldistance(cell *c1, cell *c2) {
} }
return steps; return steps;
} }
#endif
} }
} }

View File

@ -1868,9 +1868,9 @@ int celldistance(cell *c1, cell *c2) {
return 64; return 64;
} }
#if DIM == 3 if(binarytiling && DIM == 3)
if(binarytiling) return binary::celldistance(c1, c2); return binary::celldistance3(c1, c2);
#endif
return hyperbolic_celldistance(c1, c2); return hyperbolic_celldistance(c1, c2);
} }

View File

@ -1757,11 +1757,7 @@ vector<geometryinfo> ginf = {
{"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, gcHyperbolic, 0x18200, {{6, 4}}, eVariation::bitruncated}, {"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, gcHyperbolic, 0x18200, {{6, 4}}, eVariation::bitruncated},
{"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, gcHyperbolic, 0x18400, {{6, 4}}, eVariation::bitruncated}, {"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, gcHyperbolic, 0x18400, {{6, 4}}, eVariation::bitruncated},
{"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, gcHyperbolic, 0x18600, {{7, 5}}, eVariation::bitruncated}, {"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, gcHyperbolic, 0x18600, {{7, 5}}, eVariation::bitruncated},
#if DIM == 2
{"binary","none", "variant of the binary tiling", "binary", 7, 3, 0,gcHyperbolic, 0, {{7, 5}}, eVariation::pure}, {"binary","none", "variant of the binary tiling", "binary", 7, 3, 0,gcHyperbolic, 0, {{7, 5}}, eVariation::pure},
#else
{"binary","none", "variant of the binary tiling", "binary", 9, 3, 0,gcHyperbolic, 0, {{7, 3}}, eVariation::pure},
#endif
{"Arch", "none", "Archimedean", "A", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure}, {"Arch", "none", "Archimedean", "A", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure},
{"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, gcHyperbolic, 0x20000, {{7, 5}}, eVariation::bitruncated}, {"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, gcHyperbolic, 0x20000, {{7, 5}}, eVariation::bitruncated},
{"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, gcHyperbolic, 0x20200, {{6, 4}}, eVariation::bitruncated}, {"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, gcHyperbolic, 0x20200, {{6, 4}}, eVariation::bitruncated},
@ -1769,6 +1765,7 @@ vector<geometryinfo> ginf = {
{"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated}, {"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated},
{"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ, gcHyperbolic, 0x28000, {{5, 3}}, eVariation::pure}, {"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ, gcHyperbolic, 0x28000, {{5, 3}}, eVariation::pure},
{"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, gcSphere, 0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, {"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, gcSphere, 0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"bin3", "none", "3D binary tiling", "binary3", 9, 3, 0, gcHyperbolic, 0, {{7, 3}}, eVariation::pure},
}; };
// remember to match the following mask when specifying codes for extra geometries: 0x78600 // remember to match the following mask when specifying codes for extra geometries: 0x78600

View File

@ -214,7 +214,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
enum eGeometry { enum eGeometry {
gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic, gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean, gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,
gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3,
gGUARD}; gGUARD};
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };

View File

@ -177,7 +177,6 @@ void closeJoysticks() {
} }
void checkjoy() { void checkjoy() {
#if DIM == 2
DEBB(DF_GRAPH, (debugfile,"check joy\n")); DEBB(DF_GRAPH, (debugfile,"check joy\n"));
if(!DEFAULTCONTROL) return; if(!DEFAULTCONTROL) return;
ld joyvalue1 = sqr(vid.joyvalue); ld joyvalue1 = sqr(vid.joyvalue);
@ -200,11 +199,9 @@ void checkjoy() {
} }
joydir = vectodir(hpxy(jx, jy)); joydir = vectodir(hpxy(jx, jy));
#endif
} }
void checkpanjoy(double t) { void checkpanjoy(double t) {
#if DIM == 2
if(shmup::on) return; if(shmup::on) return;
if(vid.joypanspeed < 1e-7) return; if(vid.joypanspeed < 1e-7) return;
@ -217,7 +214,6 @@ void checkpanjoy(double t) {
playermoved = false; playermoved = false;
View = gpushxto0(hpxy(jx, jy)) * View; View = gpushxto0(hpxy(jx, jy)) * View;
#endif
} }
#endif #endif
@ -305,7 +301,6 @@ void handlePanning(int sym, int uni) {
if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN) if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN)
if(isGravityLand(cwt.at->land)) playermoved = false; if(isGravityLand(cwt.at->land)) playermoved = false;
#if DIM == 2
if(sym == PSEUDOKEY_WHEELUP) { if(sym == PSEUDOKEY_WHEELUP) {
ld jx = (mousex - current_display->xcenter - .0) / current_display->radius / 10; ld jx = (mousex - current_display->xcenter - .0) / current_display->radius / 10;
ld jy = (mousey - current_display->ycenter - .0) / current_display->radius / 10; ld jy = (mousey - current_display->ycenter - .0) / current_display->radius / 10;
@ -313,7 +308,6 @@ void handlePanning(int sym, int uni) {
View = gpushxto0(hpxy(jx, jy)) * View; View = gpushxto0(hpxy(jx, jy)) * View;
sym = 1; sym = 1;
} }
#endif
} }
#ifdef SCALETUNER #ifdef SCALETUNER
@ -587,7 +581,7 @@ void mainloopiter() {
SDL_Event ev; SDL_Event ev;
DEBB(DF_GRAPH, (debugfile,"polling for events\n")); DEBB(DF_GRAPH, (debugfile,"polling for events\n"));
if(smooth_movement && DEFAULTNOR) { if(smooth_movement) {
static int lastticks; static int lastticks;
ld t = (ticks - lastticks) * shiftmul / 1000.; ld t = (ticks - lastticks) * shiftmul / 1000.;
lastticks = ticks; lastticks = ticks;
@ -940,11 +934,11 @@ bool haveMobileCompass() {
#else #else
if(forcetarget) return false; if(forcetarget) return false;
#endif #endif
if(DIM == 3) return false;
return canmove && !shmup::on && vid.mobilecompasssize > 0 && isize(screens) == 1; return canmove && !shmup::on && vid.mobilecompasssize > 0 && isize(screens) == 1;
} }
bool handleCompass() { bool handleCompass() {
#if DIM == 2
if(!haveMobileCompass()) return false; if(!haveMobileCompass()) return false;
using namespace shmupballs; using namespace shmupballs;
@ -966,9 +960,6 @@ bool handleCompass() {
} }
return false; return false;
#else
return false;
#endif
} }
// orientation sensitivity // orientation sensitivity

View File

@ -477,9 +477,7 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
void generate_floorshapes() { void generate_floorshapes() {
if(0); if(DIM == 3) ;
else if(binarytiling && DIM == 3) ;
#if CAP_IRR #if CAP_IRR
else if(IRREGULAR) { else if(IRREGULAR) {
@ -625,9 +623,7 @@ void set_floor(const transmatrix& spin, hpcshape& sh) {
void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio = PPR::DEFAULT) { void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio = PPR::DEFAULT) {
if(!c) queuepolyat(V, shv[0], col, prio); if(!c) queuepolyat(V, shv[0], col, prio);
#if CAP_BT
else if(DIM == 3) ; else if(DIM == 3) ;
#endif
#if CAP_GP #if CAP_GP
else if(GOLDBERG) { else if(GOLDBERG) {
int id = gp::get_plainshape_id(c); int id = gp::get_plainshape_id(c);

View File

@ -371,7 +371,7 @@ void ge_land_selection() {
vector<eGeometry> tilinglist = { vector<eGeometry> tilinglist = {
gTinySphere, gSmallSphere, gSphere, gEuclid, gNormal, gOctagon, gTinySphere, gSmallSphere, gSphere, gEuclid, gNormal, gOctagon,
gOctahedron, gEuclidSquare, g45, g46, g47, gOctahedron, gEuclidSquare, g45, g46, g47,
gArchimedean, gBinaryTiling gArchimedean, gBinaryTiling, gBinary3
}; };
vector<eGeometry> quotientlist = { vector<eGeometry> quotientlist = {

View File

@ -457,7 +457,10 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
#endif #endif
#if CAP_BT #if CAP_BT
if(binarytiling) { if(binarytiling) {
#if DIM == 2 if(DIM == 3) {
println(hlog, "get_corner_position called");
return C0;
}
ld yx = log(2) / 2; ld yx = log(2) / 2;
ld yy = yx; ld yy = yx;
ld xx = 1 / sqrt(2)/2; ld xx = 1 / sqrt(2)/2;
@ -470,10 +473,6 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
vertices[5] = get_horopoint(-yy, -xx); vertices[5] = get_horopoint(-yy, -xx);
vertices[6] = get_horopoint(-yy, 0); vertices[6] = get_horopoint(-yy, 0);
return mid_at_actual(vertices[cid], 3/cf); return mid_at_actual(vertices[cid], 3/cf);
#else
println(hlog, "get_corner_position called");
return C0;
#endif
} }
#endif #endif
#if CAP_ARCM #if CAP_ARCM
@ -547,7 +546,10 @@ hyperpoint nearcorner(cell *c, int i) {
#endif #endif
#if CAP_BT #if CAP_BT
if(binarytiling) { if(binarytiling) {
#if DIM == 2 if(DIM == 3) {
println(hlog, "nearcorner called");
return Hypc;
}
ld yx = log(2) / 2; ld yx = log(2) / 2;
ld yy = yx; ld yy = yx;
// ld xx = 1 / sqrt(2)/2; // ld xx = 1 / sqrt(2)/2;
@ -563,10 +565,6 @@ hyperpoint nearcorner(cell *c, int i) {
else else
neis[5] = get_horopoint(-yy*2, 0); neis[5] = get_horopoint(-yy*2, 0);
return neis[i]; return neis[i];
#else
println(hlog, "nearcorner called");
return Hypc;
#endif
} }
#endif #endif
double d = cellgfxdist(c, i); double d = cellgfxdist(c, i);

View File

@ -5128,8 +5128,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(0); if(0);
#if CAP_BT #if CAP_BT
else if(binarytiling) { else if(binarytiling && DIM == 2) {
#if DIM == 2
ld yx = log(2) / 2; ld yx = log(2) / 2;
ld yy = yx; ld yy = yx;
ld xx = 1 / sqrt(2)/2; ld xx = 1 / sqrt(2)/2;
@ -5143,9 +5142,11 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
horizontal(yy, 2*xx, xx, 4, binary::bd_up_right); horizontal(yy, 2*xx, xx, 4, binary::bd_up_right);
horizontal(yy, xx, -xx, 8, binary::bd_up); horizontal(yy, xx, -xx, 8, binary::bd_up);
horizontal(yy, -xx, -2*xx, 4, binary::bd_up_left); horizontal(yy, -xx, -2*xx, 4, binary::bd_up_left);
#else }
#endif
#if CAP_BT && MAXDIM == 4
else if(binarytiling && DIM == 3) {
binary::queuecube(V, 1, 0xC0C0C080, 0); binary::queuecube(V, 1, 0xC0C0C080, 0);
#endif
} }
#endif #endif
else if(isWarped(c) && has_nice_dual()) { else if(isWarped(c) && has_nice_dual()) {

View File

@ -224,9 +224,13 @@ heptagon *createStep(heptagon *h, int d) {
crystal::create_step(h, d); crystal::create_step(h, d);
#endif #endif
#if CAP_BT #if CAP_BT
if(!h->move(d) && binarytiling) if(!h->move(d) && binarytiling && DIM == 2)
return binary::createStep(h, d); return binary::createStep(h, d);
#endif #endif
#if CAP_BT && MAXDIM == 4
if(!h->move(d) && binarytiling && DIM == 3)
return binary::createStep3(h, d);
#endif
#if CAP_ARCM #if CAP_ARCM
if(!h->move(d) && archimedean) { if(!h->move(d) && archimedean) {
arcm::create_adjacent(h, d); arcm::create_adjacent(h, d);

51
hyper.h
View File

@ -94,7 +94,7 @@ void addMessage(string s, char spamtype = 0);
#define weirdhyperbolic ((S7 > 7 || S3 > 3 || !STDVAR || binarytiling || archimedean) && hyperbolic) #define weirdhyperbolic ((S7 > 7 || S3 > 3 || !STDVAR || binarytiling || archimedean) && hyperbolic)
#define stdhyperbolic (S7 == 7 && S3 == 3 && STDVAR && !binarytiling && !archimedean) #define stdhyperbolic (S7 == 7 && S3 == 3 && STDVAR && !binarytiling && !archimedean)
#define binarytiling (geometry == gBinaryTiling) #define binarytiling (geometry == gBinaryTiling || geometry == gBinary3)
#define archimedean (geometry == gArchimedean) #define archimedean (geometry == gArchimedean)
#define eubinary (euclid || binarytiling || geometry == gCrystal) #define eubinary (euclid || binarytiling || geometry == gCrystal)
@ -189,18 +189,24 @@ typedef complex<ld> cld;
#define DEBSM(x) #define DEBSM(x)
#if MAXDIM == 3
#define DIM 2
#else
#define DIM (geometry == gBinary3 ? 3 : 2)
#endif
#define MDIM (DIM+1) #define MDIM (DIM+1)
struct hyperpoint : array<ld, MDIM> { struct hyperpoint : array<ld, MAXDIM> {
hyperpoint() {} hyperpoint() {}
hyperpoint(ld x, ld y, ld z, ld w) { hyperpoint(ld x, ld y, ld z, ld w) {
(*this)[0] = x; (*this)[1] = y; (*this)[2] = z; (*this)[0] = x; (*this)[1] = y; (*this)[2] = z;
if(DIM == 3) (*this)[3] = w; if(MAXDIM == 4) (*this)[3] = w;
} }
}; };
struct transmatrix { struct transmatrix {
ld tab[MDIM][MDIM]; ld tab[MAXDIM][MAXDIM];
ld * operator [] (int i) { return tab[i]; } ld * operator [] (int i) { return tab[i]; }
const ld * operator [] (int i) const { return tab[i]; } const ld * operator [] (int i) const { return tab[i]; }
}; };
@ -225,7 +231,7 @@ inline transmatrix operator * (const transmatrix& T, const transmatrix& U) {
} }
constexpr transmatrix diag(ld a, ld b, ld c, ld d) { constexpr transmatrix diag(ld a, ld b, ld c, ld d) {
#if DIM==2 #if MAXDIM==3
return transmatrix{{{a,0,0}, {0,b,0}, {0,0,c}}}; return transmatrix{{{a,0,0}, {0,b,0}, {0,0,c}}};
#else #else
return transmatrix{{{a,0,0,0}, {0,b,0,0}, {0,0,c,0}, {0,0,0,d}}}; return transmatrix{{{a,0,0,0}, {0,b,0,0}, {0,0,c,0}, {0,0,0,d}}};
@ -254,18 +260,10 @@ const static transmatrix pispin = diag(-1,-1,1,1);
// central symmetry // central symmetry
const static transmatrix centralsym = diag(-1,-1,-1,-1); const static transmatrix centralsym = diag(-1,-1,-1,-1);
#if DIM == 3 inline hyperpoint hpxyz(ld x, ld y, ld z) { return DIM == 2 ? hyperpoint(x,y,z,0) : hyperpoint(x,y,0,z); }
inline hyperpoint hpxyz(ld x, ld y, ld z) { return hyperpoint(x,y,0,z); } inline hyperpoint hpxyz3(ld x, ld y, ld z, ld w) { return DIM == 2 ? hyperpoint(x,y,w,0) : hyperpoint(x,y,z,w); }
inline hyperpoint hpxyz3(ld x, ld y, ld z, ld w) { return hyperpoint(x,y,z,w); }
inline hyperpoint point3(ld x, ld y, ld z) { return hyperpoint(x,y,z,0); } inline hyperpoint point3(ld x, ld y, ld z) { return hyperpoint(x,y,z,0); }
inline hyperpoint point2(ld x, ld y) { return hyperpoint(x,y,0,0); } inline hyperpoint point2(ld x, ld y) { return hyperpoint(x,y,0,0); }
#else
#define point3 hpxyz
inline hyperpoint hpxyz(ld x, ld y, ld z) { return hyperpoint(x,y,z); }
inline hyperpoint hpxyz3(ld x, ld y, ld z, ld w) { return hyperpoint(x,y,w); }
inline hyperpoint point2(ld x, ld y) { return hyperpoint(x,y,0); }
inline hyperpoint point3(ld x, ld y, ld z) { return hyperpoint(x,y,z); }
#endif
namespace hyperpoint_vec { namespace hyperpoint_vec {
@ -2785,7 +2783,14 @@ typedef float GLfloat;
typedef array<GLfloat, 2> glvec2; typedef array<GLfloat, 2> glvec2;
typedef array<GLfloat, 3> glvec3; typedef array<GLfloat, 3> glvec3;
typedef array<GLfloat, 4> glvec4; typedef array<GLfloat, 4> glvec4;
#if MAXDIM == 4
#define SHDIM 4
typedef glvec4 glvertex; typedef glvec4 glvertex;
#else
#define SHDIM 3
typedef glvec3 glvertex;
#endif
struct texture_triangle { struct texture_triangle {
array<hyperpoint, 3> v; array<hyperpoint, 3> v;
@ -3787,7 +3792,6 @@ hyperpoint normalize(hyperpoint H);
extern ld hrandf(); extern ld hrandf();
namespace glhr { namespace glhr {
static const int SHDIM = 4;
struct glmatrix { struct glmatrix {
GLfloat a[4][4]; GLfloat a[4][4];
@ -3811,11 +3815,15 @@ namespace glhr {
glvertex pointtogl(const hyperpoint& t); glvertex pointtogl(const hyperpoint& t);
inline glvertex makevertex(GLfloat x, GLfloat y, GLfloat z) { inline glvertex makevertex(GLfloat x, GLfloat y, GLfloat z) {
#if SHDIM == 3
return glvertex({x,y,z});
#else
return glvertex({x,y,z,1}); return glvertex({x,y,z,1});
#endif
} }
struct colored_vertex { struct colored_vertex {
glvec3 coords; glvertex coords;
glvec4 color; glvec4 color;
colored_vertex(GLfloat x, GLfloat y, GLfloat r, GLfloat g, GLfloat b) { colored_vertex(GLfloat x, GLfloat y, GLfloat r, GLfloat g, GLfloat b) {
coords[0] = x; coords[0] = x;
@ -3829,12 +3837,12 @@ namespace glhr {
}; };
struct textured_vertex { struct textured_vertex {
glvec4 coords; glvertex coords;
glvec2 texture; glvec2 texture;
}; };
struct ct_vertex { struct ct_vertex {
glvec4 coords; glvertex coords;
glvec4 color; glvec4 color;
glvec2 texture; glvec2 texture;
ct_vertex(const hyperpoint& h, ld x1, ld y1, ld col) { ct_vertex(const hyperpoint& h, ld x1, ld y1, ld col) {
@ -4221,6 +4229,9 @@ hyperpoint get_horopoint3(ld y, ld x, ld z);
namespace binary { namespace binary {
heptagon *createStep(heptagon *parent, int d); heptagon *createStep(heptagon *parent, int d);
#if MAXDIM == 4
heptagon *createStep3(heptagon *parent, int d);
#endif
transmatrix parabolic(ld u); transmatrix parabolic(ld u);
transmatrix parabolic3(ld u, ld v); transmatrix parabolic3(ld u, ld v);
extern ld btrange, btrange_cosh; extern ld btrange, btrange_cosh;
@ -4480,7 +4491,7 @@ struct comma_printer {
template<class T, size_t X> void print(hstream& hs, const array<T, X>& a) { print(hs, "("); comma_printer c(hs); for(const T& t: a) c(t); print(hs, ")"); } template<class T, size_t X> void print(hstream& hs, const array<T, X>& a) { print(hs, "("); comma_printer c(hs); for(const T& t: a) c(t); print(hs, ")"); }
template<class T> void print(hstream& hs, const vector<T>& a) { print(hs, "("); comma_printer c(hs); for(const T& t: a) c(t); print(hs, ")"); } template<class T> void print(hstream& hs, const vector<T>& a) { print(hs, "("); comma_printer c(hs); for(const T& t: a) c(t); print(hs, ")"); }
inline void print(hstream& hs, const hyperpoint h) { print(hs, (const array<ld, MDIM>&)h); } inline void print(hstream& hs, const hyperpoint h) { print(hs, (const array<ld, MAXDIM>&)h); }
inline void print(hstream& hs, const transmatrix T) { inline void print(hstream& hs, const transmatrix T) {
print(hs, "("); comma_printer c(hs); print(hs, "("); comma_printer c(hs);
for(int i=0; i<MDIM; i++) for(int i=0; i<MDIM; i++)

View File

@ -4,13 +4,8 @@
namespace hr { namespace hr {
#if DIM == 3
eGeometry geometry = gBinaryTiling;
eVariation variation = eVariation::pure;
#else
eGeometry geometry; eGeometry geometry;
eVariation variation; eVariation variation;
#endif
// hyperbolic points and matrices // hyperbolic points and matrices
@ -304,7 +299,7 @@ inline hyperpoint xspinpush0(ld alpha, ld x) {
transmatrix ypush(ld alpha) { return cpush(1, alpha); } transmatrix ypush(ld alpha) { return cpush(1, alpha); }
transmatrix matrix3(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i) { transmatrix matrix3(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i) {
#if DIM==2 #if MAXDIM==3
return transmatrix {{{a,b,c},{d,e,f},{g,h,i}}}; return transmatrix {{{a,b,c},{d,e,f},{g,h,i}}};
#else #else
return transmatrix {{{a,b,0,c},{d,e,0,f},{0,0,1,0},{g,h,0,i}}}; return transmatrix {{{a,b,0,c},{d,e,0,f},{0,0,1,0},{g,h,0,i}}};
@ -312,7 +307,7 @@ transmatrix matrix3(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i) {
} }
transmatrix matrix4(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i, ld j, ld k, ld l, ld m, ld n, ld o, ld p) { transmatrix matrix4(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i, ld j, ld k, ld l, ld m, ld n, ld o, ld p) {
#if DIM==2 #if MAXDIM==3
return transmatrix {{{a,b,d},{e,f,h},{m,n,p}}}; return transmatrix {{{a,b,d},{e,f,h},{m,n,p}}};
#else #else
return transmatrix {{{a,b,c,d},{e,f,g,h},{i,j,k,l},{m,n,o,p}}}; return transmatrix {{{a,b,c,d},{e,f,g,h},{i,j,k,l},{m,n,o,p}}};
@ -368,12 +363,9 @@ transmatrix rspintoc(const hyperpoint& H, int t, int f) {
// rotate the hyperbolic plane around C0 such that H[1] == 0 and H[0] >= 0 // rotate the hyperbolic plane around C0 such that H[1] == 0 and H[0] >= 0
transmatrix spintox(const hyperpoint& H) { transmatrix spintox(const hyperpoint& H) {
#if DIM==2 if(DIM == 2) return spintoc(H, 0, 1);
return spintoc(H, 0, 1);
#else
transmatrix T1 = spintoc(H, 0, 1); transmatrix T1 = spintoc(H, 0, 1);
return spintoc(T1*H, 0, 2) * T1; return spintoc(T1*H, 0, 2) * T1;
#endif
} }
void set_column(transmatrix& T, int i, const hyperpoint& H) { void set_column(transmatrix& T, int i, const hyperpoint& H) {
@ -392,12 +384,9 @@ transmatrix build_matrix(hyperpoint h1, hyperpoint h2, hyperpoint h3) {
// reverse of spintox(H) // reverse of spintox(H)
transmatrix rspintox(const hyperpoint& H) { transmatrix rspintox(const hyperpoint& H) {
#if DIM==2 if(DIM == 2) return rspintoc(H, 0, 1);
return rspintoc(H, 0, 1);
#else
transmatrix T1 = spintoc(H, 0, 1); transmatrix T1 = spintoc(H, 0, 1);
return rspintoc(H, 0, 1) * rspintoc(T1*H, 0, 2); return rspintoc(H, 0, 1) * rspintoc(T1*H, 0, 2);
#endif
} }
// for H such that H[1] == 0, this matrix pushes H to C0 // for H such that H[1] == 0, this matrix pushes H to C0
@ -474,31 +463,33 @@ void fixmatrix(transmatrix& T) {
// show the matrix on screen // show the matrix on screen
ld det(const transmatrix& T) { ld det(const transmatrix& T) {
#if DIM == 2 if(DIM == 2) {
ld det = 0; ld det = 0;
for(int i=0; i<3; i++) for(int i=0; i<3; i++)
det += T[0][i] * T[1][(i+1)%3] * T[2][(i+2)%3]; det += T[0][i] * T[1][(i+1)%3] * T[2][(i+2)%3];
for(int i=0; i<3; i++) for(int i=0; i<3; i++)
det -= T[0][i] * T[1][(i+2)%3] * T[2][(i+1)%3]; det -= T[0][i] * T[1][(i+2)%3] * T[2][(i+1)%3];
#else return det;
ld det = 1; }
transmatrix M = T; else {
for(int a=0; a<MDIM; a++) { ld det = 1;
for(int b=a; b<=DIM; b++) transmatrix M = T;
if(M[b][a]) { for(int a=0; a<MDIM; a++) {
if(b != a) for(int b=a; b<=DIM; b++)
for(int c=a; c<MDIM; c++) tie(M[b][c], M[a][c]) = make_pair(-M[a][c], M[b][c]); if(M[b][a]) {
break; if(b != a)
} for(int c=a; c<MDIM; c++) tie(M[b][c], M[a][c]) = make_pair(-M[a][c], M[b][c]);
if(!M[a][a]) return 0; break;
for(int b=a+1; b<=DIM; b++) { }
ld co = -M[b][a] / M[a][a]; if(!M[a][a]) return 0;
for(int c=a; c<MDIM; c++) M[b][c] += M[a][c] * co; for(int b=a+1; b<=DIM; b++) {
} ld co = -M[b][a] / M[a][a];
det *= M[a][a]; for(int c=a; c<MDIM; c++) M[b][c] += M[a][c] * co;
}
det *= M[a][a];
}
return det;
} }
#endif
return det;
} }
void inverse_error(const transmatrix& T) { void inverse_error(const transmatrix& T) {
@ -506,51 +497,48 @@ void inverse_error(const transmatrix& T) {
} }
transmatrix inverse(const transmatrix& T) { transmatrix inverse(const transmatrix& T) {
profile_start(7); if(DIM == 2) {
ld d = det(T);
#if DIM == 2 transmatrix T2;
ld d = det(T); if(d == 0) {
transmatrix T2; inverse_error(T);
if(d == 0) { return Id;
inverse_error(T); }
return Id;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
T2[j][i] = (T[(i+1)%3][(j+1)%3] * T[(i+2)%3][(j+2)%3] - T[(i+1)%3][(j+2)%3] * T[(i+2)%3][(j+1)%3]) / d;
return T2;
} }
else {
transmatrix T1 = T;
transmatrix T2 = Id;
for(int i=0; i<3; i++) for(int a=0; a<MDIM; a++) {
for(int j=0; j<3; j++) for(int b=a; b<=DIM; b++)
T2[j][i] = (T[(i+1)%3][(j+1)%3] * T[(i+2)%3][(j+2)%3] - T[(i+1)%3][(j+2)%3] * T[(i+2)%3][(j+1)%3]) / d; if(T1[b][a]) {
if(b != a)
#else for(int c=0; c<MDIM; c++)
transmatrix T1 = T; swap(T1[b][c], T1[a][c]), swap(T2[b][c], T2[a][c]);
transmatrix T2 = Id; break;
}
for(int a=0; a<MDIM; a++) { if(!T1[a][a]) { inverse_error(T); return Id; }
for(int b=a; b<=DIM; b++) for(int b=a+1; b<=DIM; b++) {
if(T1[b][a]) { ld co = -T1[b][a] / T1[a][a];
if(b != a) for(int c=0; c<MDIM; c++) T1[b][c] += T1[a][c] * co, T2[b][c] += T2[a][c] * co;
for(int c=0; c<MDIM; c++)
swap(T1[b][c], T1[a][c]), swap(T2[b][c], T2[a][c]);
break;
} }
if(!T1[a][a]) { inverse_error(T); return Id; }
for(int b=a+1; b<=DIM; b++) {
ld co = -T1[b][a] / T1[a][a];
for(int c=0; c<MDIM; c++) T1[b][c] += T1[a][c] * co, T2[b][c] += T2[a][c] * co;
} }
}
for(int a=MDIM-1; a>=0; a--) {
for(int a=MDIM-1; a>=0; a--) { for(int b=0; b<a; b++) {
for(int b=0; b<a; b++) { ld co = -T1[b][a] / T1[a][a];
ld co = -T1[b][a] / T1[a][a]; for(int c=0; c<MDIM; c++) T1[b][c] += T1[a][c] * co, T2[b][c] += T2[a][c] * co;
for(int c=0; c<MDIM; c++) T1[b][c] += T1[a][c] * co, T2[b][c] += T2[a][c] * co; }
ld co = 1 / T1[a][a];
for(int c=0; c<MDIM; c++) T1[a][c] *= co, T2[a][c] *= co;
} }
ld co = 1 / T1[a][a]; return T2;
for(int c=0; c<MDIM; c++) T1[a][c] *= co, T2[a][c] *= co;
} }
#endif
profile_stop(7);
return T2;
} }
// distance between mh and 0 // distance between mh and 0

View File

@ -642,16 +642,13 @@ void dqi_poly::gldraw() {
#endif #endif
double scale_at(const transmatrix& T) { double scale_at(const transmatrix& T) {
#if DIM==3 if(DIM == 3) return 1 / (tC0(T))[2];
return 1 / (tC0(T))[2];
#else
using namespace hyperpoint_vec; using namespace hyperpoint_vec;
hyperpoint h1, h2, h3; hyperpoint h1, h2, h3;
applymodel(tC0(T), h1); applymodel(tC0(T), h1);
applymodel(T * xpush0(.01), h2); applymodel(T * xpush0(.01), h2);
applymodel(T * ypush(.01) * C0, h3); applymodel(T * ypush(.01) * C0, h3);
return sqrt(hypot2(h2-h1) * hypot2(h3-h1) / .0001); return sqrt(hypot_d(h2-h1, 2) * hypot_d(h3-h1, 2) / .0001);
#endif
} }
double linewidthat(const hyperpoint& h) { double linewidthat(const hyperpoint& h) {

View File

@ -599,14 +599,15 @@ void init() {
hyperpoint gltopoint(const glvertex& t) { hyperpoint gltopoint(const glvertex& t) {
hyperpoint h; hyperpoint h;
h[0] = t[0]; h[1] = t[1]; h[2] = t[2]; h[3] = t[3]; h[0] = t[0]; h[1] = t[1]; h[2] = t[2];
// if(DIM == 3) h[3] = 0; if(SHDIM == 4 && MAXDIM == 4) h[3] = t[3];
return h; return h;
} }
glvertex pointtogl(const hyperpoint& t) { glvertex pointtogl(const hyperpoint& t) {
glvertex h; glvertex h;
h[0] = t[0]; h[1] = t[1]; h[2] = t[2]; h[3] = t[3]; h[0] = t[0]; h[1] = t[1]; h[2] = t[2];
if(SHDIM == 4) h[3] = (DIM == 3) ? t[3] : 1;
return h; return h;
} }

View File

@ -845,15 +845,13 @@ void handleInput(int delta) {
multi::mdx[i] = multi::mdx[i] * (1 - delta / 1000.) + mdx * delta / 2000.; multi::mdx[i] = multi::mdx[i] * (1 - delta / 1000.) + mdx * delta / 2000.;
multi::mdy[i] = multi::mdy[i] * (1 - delta / 1000.) + mdy * delta / 2000.; multi::mdy[i] = multi::mdy[i] * (1 - delta / 1000.) + mdy * delta / 2000.;
#if DIM == 2 if(DIM == 2) {
if(mdx != 0 || mdy != 0) if(!multi::combo[i]) { if(mdx != 0 || mdy != 0) if(!multi::combo[i]) {
cwtV = multi::whereis[i]; cwt = multi::player[i]; cwtV = multi::whereis[i]; cwt = multi::player[i];
flipplayer = multi::flipped[i]; flipplayer = multi::flipped[i];
multi::whereto[i] = vectodir(hpxy(multi::mdx[i], multi::mdy[i])); multi::whereto[i] = vectodir(hpxy(multi::mdx[i], multi::mdy[i]));
}
} }
#else
ignore(mdx); ignore(mdy);
#endif
if(multi::actionspressed[b+pcFire] || if(multi::actionspressed[b+pcFire] ||
(multi::actionspressed[b+pcMoveLeft] && multi::actionspressed[b+pcMoveRight])) (multi::actionspressed[b+pcMoveLeft] && multi::actionspressed[b+pcMoveRight]))
@ -1626,21 +1624,21 @@ void movePlayer(monster *m, int delta) {
playerturn[cpid] = mturn * delta / 150.0; playerturn[cpid] = mturn * delta / 150.0;
#if DIM == 2 if(DIM == 2) {
double mdd = hypot(mdx, mdy); double mdd = hypot(mdx, mdy);
if(mdd > 1e-6) {
hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
hyperpoint ctr = m->pat * C0;
if(sphere && vid.alpha > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
hyperpoint h = inverse(m->pat) * rgpushxto0(ctr) * jh;
playerturn[cpid] = -atan2(h[1], h[0]); if(mdd > 1e-6) {
mgo += mdd; hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
hyperpoint ctr = m->pat * C0;
if(sphere && vid.alpha > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
hyperpoint h = inverse(m->pat) * rgpushxto0(ctr) * jh;
playerturn[cpid] = -atan2(h[1], h[0]);
mgo += mdd;
}
} }
#endif
#if CAP_SDL #if CAP_SDL
Uint8 *keystate = SDL_GetKeyState(NULL); Uint8 *keystate = SDL_GetKeyState(NULL);

View File

@ -443,7 +443,7 @@ union SDL_Event;
#endif #endif
#endif #endif
#define DIM 3 #define MAXDIM 4
#ifndef CAP_GEOMETRY #ifndef CAP_GEOMETRY
#define CAP_GEOMETRY (!(ISMINI)) #define CAP_GEOMETRY (!(ISMINI))

View File

@ -1194,7 +1194,7 @@ void set_geometry(eGeometry target) {
if(DUAL && geometry != gArchimedean) if(DUAL && geometry != gArchimedean)
variation = ginf[geometry].default_variation; variation = ginf[geometry].default_variation;
#if CAP_BT #if CAP_BT
if(geometry == gBinaryTiling) variation = eVariation::pure; if(among(geometry, gBinaryTiling, gBinary3)) variation = eVariation::pure;
#endif #endif
need_reset_geometry = true; need_reset_geometry = true;