From 804b489ebffd2ab98fa70b68b500e224b38309da Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Thu, 25 Oct 2018 19:58:38 +0200 Subject: [PATCH] improved hemisphere model; nicer handling of ballangle --- basegraph.cpp | 2 +- conformal.cpp | 3 +++ graph.cpp | 4 ++-- hyper.h | 3 +++ hypgraph.cpp | 35 ++++++++++++++++------------------- polygons.cpp | 24 +++++++++++++++--------- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index d9323489..dd45cf09 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -255,7 +255,7 @@ void stereo::set_viewport(int ed) { } bool model_needs_depth() { - return pmodel == mdBall || pmodel == mdHemisphere; + return pmodel == mdBall; } void setGLProjection(color_t col) { diff --git a/conformal.cpp b/conformal.cpp index 5b30e623..743f2b26 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -296,6 +296,7 @@ namespace conformal { int do_rotate = 1; ld model_orientation, halfplane_scale; ld ocos, osin; + ld cos_ball, sin_ball; bool model_straight; ld top_z = 5; @@ -413,6 +414,8 @@ namespace conformal { } void configure() { + ld ball = -vid.ballangle * M_PI / 180; + cos_ball = cos(ball), sin_ball = sin(ball); ocos = cos(model_orientation * M_PI / 180); osin = sin(model_orientation * M_PI / 180); model_straight = (ocos > 1 - 1e-9); diff --git a/graph.cpp b/graph.cpp index f575a838..5b37f82f 100644 --- a/graph.cpp +++ b/graph.cpp @@ -5572,8 +5572,8 @@ void drawfullmap() { ld z = acosh(tz); hyperpoint a = xpush0(z); - ld ball = -vid.ballangle * M_PI / 180; - ld cb = cos(ball), sb = sin(ball); + ld cb = conformal::cos_ball; + ld sb = conformal::sin_ball; a[1] = sb * a[2] / -cb; a[0] = sqrt(-1 + a[2] * a[2] - a[1] * a[1]); diff --git a/hyper.h b/hyper.h index 479e6596..b4e02c6c 100644 --- a/hyper.h +++ b/hyper.h @@ -1279,6 +1279,7 @@ namespace conformal { extern ld model_orientation; extern ld halfplane_scale; extern ld ocos, osin; + extern ld cos_ball, sin_ball; extern bool model_straight; extern ld top_z; @@ -1286,6 +1287,8 @@ namespace conformal { // logical coordinates back to screen coordinates: apply_orientation(y,x) template void apply_orientation(A& x, A& y) { if(!model_straight) tie(x,y) = make_pair(x*ocos + y*osin, y*ocos - x*osin); } + template + 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(); diff --git a/hypgraph.cpp b/hypgraph.cpp index e4a19632..2bbc01a0 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -78,14 +78,14 @@ void ballmodel(hyperpoint& ret, double alpha, double d, double zl) { ld tzh = vid.ballproj + H[2]; ld ax = H[0] / tzh; ld ay = H[1] / tzh; - ld ball = vid.ballangle * M_PI / 180; ld ca = cos(alpha), sa = sin(alpha); - ld cb = cos(ball), sb = sin(ball); - + ret[0] = ax * ca; - ret[1] = ay * cb + ax * sa * sb; - ret[2] = ax * sa * cb - ay * sb; + ret[1] = ay; + ret[2] = ax * sa; + + conformal::apply_ball(ret[2], ret[1]); } void apply_depth(hyperpoint &f, ld z) { @@ -154,7 +154,6 @@ void applymodel(hyperpoint H, hyperpoint& ret) { } if(pmodel == mdHemisphere) { - ld ball = vid.ballangle * M_PI / 180; using namespace hyperpoint_vec; 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); return; @@ -198,13 +199,11 @@ void applymodel(hyperpoint H, hyperpoint& ret) { H[1] /= H[2]; 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[1] = (1 - H[2]) / 3 * cb - H[1] / 3 * sb; - ret[2] = -(-H[1] / 3 * cb - (1 - H[2]) / 3 * sb); - + ret[1] = (1 - H[2]) / 3; + ret[2] = H[1] / 3; + + conformal::apply_ball(ret[2], ret[1]); ghcheck(ret,H); return; } @@ -218,13 +217,11 @@ void applymodel(hyperpoint H, hyperpoint& ret) { H[2] = tz; } - ld ball = -vid.ballangle * M_PI / 180; - ld cb = cos(ball), sb = sin(ball); - ret[0] = H[0] / 3; - ret[1] = (1 - H[2]) / 3 * cb - H[1] / 3 * sb; - ret[2] = -(-H[1] / 3 * cb - (1 - H[2]) / 3 * sb); - + ret[1] = (1 - H[2]) / 3; + ret[2] = H[1] / 3; + + conformal::apply_ball(ret[2], ret[1]); ghcheck(ret,H); return; } diff --git a/polygons.cpp b/polygons.cpp index b31e62d7..402782d6 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -187,23 +187,29 @@ bool two_sided_model() { if(pmodel == mdHyperboloid) return !euclid; // if(pmodel == mdHemisphere) return true; if(pmodel == mdDisk) return sphere; + if(pmodel == mdHemisphere) return !euclid; return false; } -bool correct_side(const hyperpoint& H) { +int get_side(const hyperpoint& H) { if(pmodel == mdDisk && sphere) { double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2]; double horizon = curnorm / vid.alpha; - return (spherespecial>0) ^ (H[2] <= -horizon); + return (H[2] <= -horizon) ? -1 : 1; + ; } - if(pmodel == mdHyperboloid && hyperbolic) { - ld ball = -vid.ballangle * M_PI / 180; - ld cb = cos(ball), sb = sin(ball); - return (spherespecial > 0) ^ ( - sb * H[2] > -cb * H[1] - ); + if(pmodel == mdHyperboloid && hyperbolic) + return (conformal::sin_ball * H[2] > -conformal::cos_ball * H[1]) ? -1 : 1; + if(pmodel == mdHemisphere || pmodel == mdHyperboloid) { + hyperpoint res; + 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& hscr, hyperpoint H) {