1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-07-06 11:32:49 +00:00

improved hemisphere model; nicer handling of ballangle

This commit is contained in:
Zeno Rogue 2018-10-25 19:58:38 +02:00
parent 9ad39df2c0
commit 804b489ebf
6 changed files with 40 additions and 31 deletions

View File

@ -255,7 +255,7 @@ void stereo::set_viewport(int ed) {
} }
bool model_needs_depth() { bool model_needs_depth() {
return pmodel == mdBall || pmodel == mdHemisphere; return pmodel == mdBall;
} }
void setGLProjection(color_t col) { void setGLProjection(color_t col) {

View File

@ -296,6 +296,7 @@ namespace conformal {
int do_rotate = 1; int do_rotate = 1;
ld model_orientation, halfplane_scale; ld model_orientation, halfplane_scale;
ld ocos, osin; ld ocos, osin;
ld cos_ball, sin_ball;
bool model_straight; bool model_straight;
ld top_z = 5; ld top_z = 5;
@ -413,6 +414,8 @@ namespace conformal {
} }
void configure() { void configure() {
ld ball = -vid.ballangle * M_PI / 180;
cos_ball = cos(ball), sin_ball = sin(ball);
ocos = cos(model_orientation * M_PI / 180); ocos = cos(model_orientation * M_PI / 180);
osin = sin(model_orientation * M_PI / 180); osin = sin(model_orientation * M_PI / 180);
model_straight = (ocos > 1 - 1e-9); model_straight = (ocos > 1 - 1e-9);

View File

@ -5572,8 +5572,8 @@ void drawfullmap() {
ld z = acosh(tz); ld z = acosh(tz);
hyperpoint a = xpush0(z); hyperpoint a = xpush0(z);
ld ball = -vid.ballangle * M_PI / 180; ld cb = conformal::cos_ball;
ld cb = cos(ball), sb = sin(ball); ld sb = conformal::sin_ball;
a[1] = sb * a[2] / -cb; a[1] = sb * a[2] / -cb;
a[0] = sqrt(-1 + a[2] * a[2] - a[1] * a[1]); a[0] = sqrt(-1 + a[2] * a[2] - a[1] * a[1]);

View File

@ -1279,6 +1279,7 @@ namespace conformal {
extern ld model_orientation; extern ld model_orientation;
extern ld halfplane_scale; extern ld halfplane_scale;
extern ld ocos, osin; extern ld ocos, osin;
extern ld cos_ball, sin_ball;
extern bool model_straight; extern bool model_straight;
extern ld top_z; extern ld top_z;
@ -1286,6 +1287,8 @@ namespace conformal {
// logical coordinates back to screen coordinates: apply_orientation(y,x) // logical coordinates back to screen coordinates: apply_orientation(y,x)
template<class A> template<class A>
void apply_orientation(A& x, A& y) { if(!model_straight) tie(x,y) = make_pair(x*ocos + y*osin, y*ocos - x*osin); } void apply_orientation(A& x, A& y) { if(!model_straight) tie(x,y) = make_pair(x*ocos + y*osin, y*ocos - x*osin); }
template<class A>
void apply_ball(A& x, A& y) { tie(x,y) = make_pair(x*cos_ball + y*sin_ball, y*cos_ball - x*sin_ball); }
void configure(); void configure();

View File

@ -78,14 +78,14 @@ void ballmodel(hyperpoint& ret, double alpha, double d, double zl) {
ld tzh = vid.ballproj + H[2]; ld tzh = vid.ballproj + H[2];
ld ax = H[0] / tzh; ld ax = H[0] / tzh;
ld ay = H[1] / tzh; ld ay = H[1] / tzh;
ld ball = vid.ballangle * M_PI / 180;
ld ca = cos(alpha), sa = sin(alpha); ld ca = cos(alpha), sa = sin(alpha);
ld cb = cos(ball), sb = sin(ball);
ret[0] = ax * ca; ret[0] = ax * ca;
ret[1] = ay * cb + ax * sa * sb; ret[1] = ay;
ret[2] = ax * sa * cb - ay * sb; ret[2] = ax * sa;
conformal::apply_ball(ret[2], ret[1]);
} }
void apply_depth(hyperpoint &f, ld z) { void apply_depth(hyperpoint &f, ld z) {
@ -154,7 +154,6 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
} }
if(pmodel == mdHemisphere) { if(pmodel == mdHemisphere) {
ld ball = vid.ballangle * M_PI / 180;
using namespace hyperpoint_vec; using namespace hyperpoint_vec;
switch(cgclass) { switch(cgclass) {
@ -186,7 +185,9 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
} }
} }
ret = rotmatrix(M_PI/2 + ball, 1, 2) * ret; swap(ret[1], ret[2]);
conformal::apply_ball(ret[2], ret[1]);
ghcheck(ret, H); ghcheck(ret, H);
return; return;
@ -198,13 +199,11 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
H[1] /= H[2]; H[1] /= H[2];
H[2] = 1 - vid.alpha; H[2] = 1 - vid.alpha;
ld ball = -vid.ballangle * M_PI / 180;
ld cb = cos(ball), sb = sin(ball);
ret[0] = H[0] / 3; ret[0] = H[0] / 3;
ret[1] = (1 - H[2]) / 3 * cb - H[1] / 3 * sb; ret[1] = (1 - H[2]) / 3;
ret[2] = -(-H[1] / 3 * cb - (1 - H[2]) / 3 * sb); ret[2] = H[1] / 3;
conformal::apply_ball(ret[2], ret[1]);
ghcheck(ret,H); ghcheck(ret,H);
return; return;
} }
@ -218,13 +217,11 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
H[2] = tz; H[2] = tz;
} }
ld ball = -vid.ballangle * M_PI / 180;
ld cb = cos(ball), sb = sin(ball);
ret[0] = H[0] / 3; ret[0] = H[0] / 3;
ret[1] = (1 - H[2]) / 3 * cb - H[1] / 3 * sb; ret[1] = (1 - H[2]) / 3;
ret[2] = -(-H[1] / 3 * cb - (1 - H[2]) / 3 * sb); ret[2] = H[1] / 3;
conformal::apply_ball(ret[2], ret[1]);
ghcheck(ret,H); ghcheck(ret,H);
return; return;
} }

View File

@ -187,23 +187,29 @@ bool two_sided_model() {
if(pmodel == mdHyperboloid) return !euclid; if(pmodel == mdHyperboloid) return !euclid;
// if(pmodel == mdHemisphere) return true; // if(pmodel == mdHemisphere) return true;
if(pmodel == mdDisk) return sphere; if(pmodel == mdDisk) return sphere;
if(pmodel == mdHemisphere) return !euclid;
return false; return false;
} }
bool correct_side(const hyperpoint& H) { int get_side(const hyperpoint& H) {
if(pmodel == mdDisk && sphere) { if(pmodel == mdDisk && sphere) {
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2]; double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
double horizon = curnorm / vid.alpha; double horizon = curnorm / vid.alpha;
return (spherespecial>0) ^ (H[2] <= -horizon); return (H[2] <= -horizon) ? -1 : 1;
;
} }
if(pmodel == mdHyperboloid && hyperbolic) { if(pmodel == mdHyperboloid && hyperbolic)
ld ball = -vid.ballangle * M_PI / 180; return (conformal::sin_ball * H[2] > -conformal::cos_ball * H[1]) ? -1 : 1;
ld cb = cos(ball), sb = sin(ball); if(pmodel == mdHemisphere || pmodel == mdHyperboloid) {
return (spherespecial > 0) ^ ( hyperpoint res;
sb * H[2] > -cb * H[1] applymodel(H, res);
); return res[2] < 0 ? -1 : 1;
} }
return true; return 0;
}
bool correct_side(const hyperpoint& H) {
return get_side(H) == spherespecial;
} }
void fixpoint(array<float, 3>& hscr, hyperpoint H) { void fixpoint(array<float, 3>& hscr, hyperpoint H) {