// Hyperbolic Rogue // geometrical constants // Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details namespace hr { bool debug_geometry = false; ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf; // tessf: distance from heptagon center to another heptagon center // hexf: distance from heptagon center to small heptagon vertex // hcrossf: distance from heptagon center to big heptagon vertex // crossf: distance from heptagon center to adjacent cell center (either hcrossf or tessf) // hexhexdist: distance between adjacent hexagon vertices // hexvdist: distance between hexagon vertex and hexagon center // hepvdist: distance between heptagon vertex and hexagon center (either hcrossf or something else) // rhexf: distance from heptagon center to heptagon vertex (either hexf or hcrossf) int base_distlimit; transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE]; transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE]; ld hexshift; // the results are: // hexf = 0.378077 hcrossf = 0.620672 tessf = 1.090550 // hexhexdist = 0.566256 ld hcrossf7 = 0.620672; ld hexf7 = 0.378077; ld scalefactor, orbsize, floorrad0, floorrad1, zhexf; // the distance between two hexagon centers void precalc() { DEBB(DF_INIT, (debugfile,"precalc\n")); hexshift = 0; int vertexdegree = S6/2; ld fmin, fmax; if(archimedean) ginf[gArchimedean].cclass = gcHyperbolic; if(euclid) { // dynamicval g(geometry, gNormal); // precalc(); } // for(int i=0; i v2) fmin = f; else fmax = f; } tessf = fmin; if(elliptic && S7 == 4) tessf = M_PI/2; if(vertexdegree == 3) { fmin = 0, fmax = sphere ? M_PI / 2 : 2; for(int p=0; p<100; p++) { ld f = (fmin+fmax) / 2; hyperpoint H = xspinpush0(M_PI/S7, f); ld v1 = intval(H, C0), v2 = intval(H, xpush0(tessf)); if(v1 < v2) fmin = f; else fmax = f; } hcrossf = fmin; } else { hcrossf = hdist(xpush0(tessf), xspinpush0(2*M_PI/S7, tessf)) / 2; } crossf = BITRUNCATED ? hcrossf : tessf; fmin = 0, fmax = tessf; for(int p=0; p<100; p++) { ld f = (fmin+fmax) / 2; hyperpoint H = xpush0(f); hyperpoint H1 = spin(2*M_PI/S7) * H; hyperpoint H2 = xpush0(tessf-f); ld v1 = intval(H, H1), v2 = intval(H, H2); if(v1 < v2) fmin = f; else fmax = f; } hexf = fmin; rhexf = BITRUNCATED ? hexf : hcrossf; if(!euclid && BITRUNCATED && !(S7&1)) hexshift = ALPHA/2 + ALPHA * ((S7-1)/2) + M_PI; finish: for(int d=0; d(4 / hypot_d(2, gp::next), 1); #endif return wall_height; } void compute() { // tanh(depth) / tanh(camera) == vid.alpha invalid = ""; if(tc_alpha < tc_depth && tc_alpha < tc_camera) vid.alpha = tan_auto(depth) / tan_auto(camera); else if(tc_depth < tc_alpha && tc_depth < tc_camera) { ld v = vid.alpha * tan_auto(camera); if(hyperbolic && (v<1e-6-12 || v>1-1e-12)) invalid = "cannot adjust depth", depth = camera; else depth = atan_auto(v); } else { ld v = tan_auto(depth) / vid.alpha; if(hyperbolic && (v<1e-12-1 || v>1-1e-12)) invalid = "cannot adjust camera", camera = depth; else camera = atan_auto(v); } if(fabs(vid.alpha) < 1e-6) invalid = "does not work with perfect Klein"; if(invalid != "") { INFDEEP = .7; BOTTOM = .8; HELLSPIKE = .85; LAKE = .9; WALL = 1.25; SLEV[0] = 1; SLEV[1] = 1.08; SLEV[2] = 1.16; SLEV[3] = 1.24; FLATEYE = 1.03; LEG1 = 1.025; LEG = 1.05; LEG3 = 1.075; GROIN = 1.09; GROIN1 = 1.105; GHOST = 1.1; BODY = 1.15; BODY1 = 1.151; BODY2 = 1.152; BODY3 = 1.153; NECK1 = 1.16; NECK = 1.17; NECK3 = 1.18; HEAD = 1.188; HEAD1= 1.189; HEAD2= 1.190; ABODY = 1.08; AHEAD = 1.12; BIRD = 1.20; } else { INFDEEP = (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(camera); ld wh = actual_wall_height(); WALL = lev_to_factor(wh); human_height = human_wall_ratio * wh; if(DIM == 3) human_height *= 1.5; ld reduce = (DIM == 3 ? human_height / 2 : 0); LEG0 = lev_to_factor(human_height * .0 - reduce); LEG1 = lev_to_factor(human_height * .1 - reduce); LEG = lev_to_factor(human_height * .2 - reduce); LEG3 = lev_to_factor(human_height * .3 - reduce); GROIN = lev_to_factor(human_height * .4 - reduce); GROIN1= lev_to_factor(human_height * .5 - reduce); BODY = lev_to_factor(human_height * .6 - reduce); BODY1 = lev_to_factor(human_height * .61 - reduce); BODY2 = lev_to_factor(human_height * .62 - reduce); BODY3 = lev_to_factor(human_height * .63 - reduce); NECK1 = lev_to_factor(human_height * .7 - reduce); NECK = lev_to_factor(human_height * .8 - reduce); NECK3 = lev_to_factor(human_height * .9 - reduce); HEAD = lev_to_factor(human_height * .98 - reduce); HEAD1 = lev_to_factor(human_height * .99 - reduce); HEAD2 = lev_to_factor(human_height); reduce = (DIM == 3 ? human_height * .3 : 0); ABODY = lev_to_factor(human_height * .4 - reduce); ALEG0 = lev_to_factor(human_height * .0 - reduce); ALEG = lev_to_factor(human_height * .2 - reduce); AHEAD = lev_to_factor(human_height * .6 - reduce); BIRD = lev_to_factor(DIM == 3 ? 0 : (human_wall_ratio+1)/2 * wh * .8); GHOST = lev_to_factor(DIM == 3 ? 0 : human_height * .5); FLATEYE = lev_to_factor(human_height * .15); slev = rock_wall_ratio * wh / 3; for(int s=0; s<=3; s++) SLEV[s] = lev_to_factor(rock_wall_ratio * wh * s/3); LAKE = lev_to_factor(-lake_top); HELLSPIKE = lev_to_factor(-(lake_top+lake_bottom)/2); BOTTOM = lev_to_factor(-lake_bottom); } } } void initgeo() { // printf("%Lf\n", (ld) hdist0(xpush(-1)*ypush(0.01)*xpush(1)*C0)); precalc(); } }