From cbb53cfe68e5e439b2601cc91fb781aab41bf93b Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Thu, 25 Oct 2018 02:44:35 +0200 Subject: [PATCH] Joukowsky transform, and better inverted Poincare --- basegraph.cpp | 2 +- conformal.cpp | 2 +- hyper.h | 2 +- hypgraph.cpp | 19 +++++++++ polygons.cpp | 116 +++++++++++++++++++++++++++----------------------- 5 files changed, 84 insertions(+), 57 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index 7836c3e7..d9323489 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -195,7 +195,7 @@ void eyewidth_translate(int ed) { void stereo::set_projection(int ed) { DEBB(DF_GRAPH, (debugfile,"stereo::set_projection\n")); - start_projection(ed, pmodel == mdDisk && !spherespecial); + start_projection(ed, pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1)); if(!using_perspective) { glhr::projection_multiply(glhr::ortho(vid.xres/2, -vid.yres/2, abs(stereo::scrdist) + 30000)); diff --git a/conformal.cpp b/conformal.cpp index ea5b5d3f..dc70b6a7 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -578,7 +578,7 @@ namespace conformal { "azimuthal equidistant", "azimuthal equi-area", "ball model", "Minkowski hyperboloid", "hemisphere", "band equidistant", "band equi-area", "sinusoidal", "two-point equidistant", - "fisheye" + "fisheye", "Joukovsky", "Joukovsky/inversion" }; string get_model_name(eModel pm) { diff --git a/hyper.h b/hyper.h index 12be8514..479e6596 100644 --- a/hyper.h +++ b/hyper.h @@ -1264,7 +1264,7 @@ enum eModel { mdDisk, mdHalfplane, mdBand, mdPolygonal, mdPolynomial, mdEquidistant, mdEquiarea, mdBall, mdHyperboloid, mdHemisphere, mdBandEquidistant, mdBandEquiarea, mdSinusoidal, mdTwoPoint, - mdFisheye, + mdFisheye, mdJoukowsky, mdJoukowskyInverted, mdGUARD, mdUnchanged, mdHyperboloidFlat }; namespace conformal { diff --git a/hypgraph.cpp b/hypgraph.cpp index 280d0e2d..937a03d0 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -406,6 +406,25 @@ void applymodel(hyperpoint H, hyperpoint& ret) { return; } + if(among(pmodel, mdJoukowsky, mdJoukowskyInverted)) { + ld x0, y0; + x0 = H[0] / tz; + y0 = H[1] / tz; + ld r = hypot(x0, y0); + ld c = x0 / r; + ld s = y0 / r; + ret[0] = (r + 1/r) * c / 2; + ret[1] = (r - 1/r) * s / 2; + ret[2] = 0; + if(pmodel == mdJoukowskyInverted) { + ld r2 = sqhypot2(ret); + ret[0] = ret[0] / r2; + ret[1] = -ret[1] / r2; + } + ghcheck(ret,H); + return; + } + if(pmodel == mdHalfplane) { // Poincare to half-plane diff --git a/polygons.cpp b/polygons.cpp index 9ed165ea..b31e62d7 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -722,6 +722,60 @@ ld glhypot2(glvertex a, glvertex b) { return (a[0]-b[0]) * (a[0]-b[0]) + (a[1]-b[1]) * (a[1]-b[1]) + (a[2]-b[2]) * (a[2]-b[2]); } +void compute_side_by_centerin(dqi_poly *p, bool& nofill) { + + hyperpoint hscr; + hyperpoint h1 = p->V * p->intester; + if(is_behind(h1)) { + if(sphere) { + for(int i=0; i<3; i++) h1[i] = -h1[i]; + poly_flags &= ~POLY_CENTERIN; + } + else + nofill = true; + } + applymodel(h1, hscr); hscr[0] *= vid.radius; hscr[1] *= vid.radius * vid.stretch; + for(int i=0; i(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); + glcoords.push_back(make_array(hscr[0], hscr[1]*vid.stretch+10, hscr[2])); + glcoords.push_back(make_array(hscr[0]-10, hscr[1]*vid.stretch, hscr[2])); + glcoords.push_back(make_array(hscr[0], hscr[1]*vid.stretch-10, hscr[2])); + glcoords.push_back(make_array(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); + } */ + } + +void compute_side_by_area() { + + double rarea = 0; + for(int i=0; i0) + poly_flags ^= POLY_INVERSE; + } + void dqi_poly::draw() { if(!hyperbolic && among(pmodel, mdPolygonal, mdPolynomial)) { @@ -899,67 +953,21 @@ void dqi_poly::draw() { if(around_center) return; } - if(sphere && (spherespecial > 0 || equi) && !(poly_flags & POLY_ISSIDE)) { + if(((sphere && (spherespecial > 0 || equi)) || (pmodel == mdJoukowsky && hyperbolic) || (pmodel == mdDisk && hyperbolic && vid.alpha <= -1)) && !(poly_flags & POLY_ISSIDE)) { - if(!tinf) { - - hyperpoint hscr; - hyperpoint h1 = V * intester; - if(is_behind(h1)) { - if(sphere) { - for(int i=0; i<3; i++) h1[i] = -h1[i]; - poly_flags &= ~POLY_CENTERIN; - } - else - nofill = true; - } - applymodel(h1, hscr); hscr[0] *= vid.radius; hscr[1] *= vid.radius * vid.stretch; - for(int i=0; i(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); - glcoords.push_back(make_array(hscr[0], hscr[1]*vid.stretch+10, hscr[2])); - glcoords.push_back(make_array(hscr[0]-10, hscr[1]*vid.stretch, hscr[2])); - glcoords.push_back(make_array(hscr[0], hscr[1]*vid.stretch-10, hscr[2])); - glcoords.push_back(make_array(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); - } */ - } - + if(!tinf) + compute_side_by_centerin(this, nofill); + else { - - double rarea = 0; - for(int i=0; i0) - poly_flags ^= POLY_INVERSE; + if(d < 0) poly_flags ^= POLY_INVERSE; + compute_side_by_area(); } if(poly_flags & POLY_INVERSE) { if(curradius < vid.alpha - 1e-6) return; + if(!sphere) return; } + } else poly_flags &=~ POLY_INVERSE;