From 542e80081fddbec8aff9a182ca833e5e66f62770 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 7 Nov 2018 00:52:48 +0100 Subject: [PATCH] conformal:: new models: formula and rotated hyperboles --- config.cpp | 3 +++ conformal.cpp | 56 +++++++++++++++++++++++++-------------------------- hyper.h | 13 +++++++++--- hypgraph.cpp | 37 ++++++++++++++++++++++++++++++++++ polygons.cpp | 3 +++ 5 files changed, 80 insertions(+), 32 deletions(-) diff --git a/config.cpp b/config.cpp index 716ec2f9..d0a2002f 100644 --- a/config.cpp +++ b/config.cpp @@ -295,6 +295,9 @@ void initConfig() { addsaver(vid.cells_drawn_limit, "limit on cells drawn", 10000); addsaver(vid.skiprope, "mobius", 0); + + addsaver(conformal::formula, "formula"); + addsaverenum(conformal::basic_model, "basic model"); #if CAP_SHMUP shmup::initConfig(); diff --git a/conformal.cpp b/conformal.cpp index e6287e40..12bbc6fe 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -258,6 +258,9 @@ bool isbad(ld z) { return !isfinite(z) || fabs(z) > 1e6; } namespace conformal { + string formula = "z^2"; + eModel basic_model; + void handleKeyC(int sym, int uni); int lastprogress; @@ -578,11 +581,11 @@ namespace conformal { #endif const char *modelnames[MODELCOUNT] = { - "disk", "half-plane", "band", "polygonal", "polynomial", + "disk", "half-plane", "band", "polygonal", "formula", "azimuthal equidistant", "azimuthal equi-area", "ball model", "Minkowski hyperboloid", "hemisphere", "band equidistant", "band equi-area", "sinusoidal", "two-point equidistant", - "fisheye", "Joukowsky transform", "Joukowsky+inversion" + "fisheye", "Joukowsky transform", "Joukowsky+inversion", "rotated hyperboles" }; string get_model_name(eModel pm) { @@ -610,14 +613,34 @@ namespace conformal { return among(pmodel, mdJoukowsky, mdJoukowskyInverted, mdBand); } + int editpos = 0; + void model_menu() { cmode = sm::SIDE | sm::MAYDARK | sm::CENTER; gamescreen(0); dialog::init(XLAT("models of hyperbolic geometry")); for(int i=0; i= '0' && uni <= '9') { - pmodel = eModel(uni - '0'); - polygonal::solve(); - vid.alpha = 1; vid.scale = 1; - if(pmodel == mdBand && sphere) - vid.scale = .3; - if(pmodel == mdDisk && sphere) - vid.scale = .4; - } - else if(uni == '!') - pmodel = eModel(10); - else if(uni == '@') - pmodel = eModel(11); - else if(uni == '#') - pmodel = eModel(12); - else if(uni == '$') - pmodel = eModel(13); - else if(uni == '%') - pmodel = eModel(14); - else if(uni == '^') - pmodel = eModel(15); - else if(uni == '&') - pmodel = eModel(16); - else if(uni == '6') - vid.alpha = 1, vid.scale = 1; - else if(uni == 'z') + if(uni == 'z') editScale(); else if(uni == 'p') projectionDialog(); diff --git a/hyper.h b/hyper.h index 6ea5bbfd..15d64bb9 100644 --- a/hyper.h +++ b/hyper.h @@ -472,7 +472,9 @@ template struct walker { return at == x.at && spin == x.spin && mirrored == x.mirrored; } - + bool operator < (const walker& cw2) const { + return tie(at, spin, mirrored) < tie(cw2.at, cw2.spin, cw2.mirrored); + } walker& operator ++ (int) { return (*this) += 1; } walker& operator -- (int) { return (*this) -= 1; } @@ -1269,11 +1271,13 @@ extern ld ruggo; #define HASLINEVIEW enum eModel { - mdDisk, mdHalfplane, mdBand, mdPolygonal, mdPolynomial, + mdDisk, mdHalfplane, mdBand, mdPolygonal, mdFormula, mdEquidistant, mdEquiarea, mdBall, mdHyperboloid, mdHemisphere, mdBandEquidistant, mdBandEquiarea, mdSinusoidal, mdTwoPoint, mdFisheye, mdJoukowsky, mdJoukowskyInverted, - mdGUARD, mdUnchanged, mdHyperboloidFlat }; + mdRotatedHyperboles, + mdGUARD, mdUnchanged, mdHyperboloidFlat, mdPolynomial + }; namespace conformal { extern bool on; @@ -1325,6 +1329,9 @@ namespace conformal { void progress_screen(); void progress(string str); bool model_has_orientation(); + + extern string formula; + extern eModel basic_model; } namespace polygonal { diff --git a/hypgraph.cpp b/hypgraph.cpp index 827ed842..0a7e9cc3 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -516,6 +516,43 @@ void applymodel(hyperpoint H, hyperpoint& ret) { break; } + case mdRotatedHyperboles: { + // ld zlev = <- not implemented + find_zlev(H); // + geom3::depth; + conformal::apply_orientation(H[0], H[1]); + + ld y = asin_auto(H[1]); + ld x = asin_auto_clamp(H[0] / cos_auto(y)); + // ld z = zlev == 1 ? 0 : geom3::factor_to_lev(zlev); + + ld factor = geom3::lev_to_factor(y + geom3::depth); + + ret[0] = sinh(x) * factor; + ret[1] = cosh(x) * factor; + ret[2] = 0; + + ret[0] = atan(ret[0]); + ret[1] = atan(ret[1]); + + break; + } + + case mdFormula: { + dynamicval m(pmodel, conformal::basic_model); + applymodel(H, ret); + exp_parser ep; + ep.extra_params["z"] = cld(ret[0], ret[1]); + ep.extra_params["cx"] = ret[0]; + ep.extra_params["cy"] = ret[1]; + ep.extra_params["cz"] = ret[2]; + ep.s = conformal::formula; + cld res = ep.parse(); + ret[0] = real(res); + ret[1] = imag(res); + ret[2] = 0; + break; + } + case mdGUARD: break; } diff --git a/polygons.cpp b/polygons.cpp index f65c1b6e..eb094221 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -191,6 +191,7 @@ bool two_sided_model() { // if(pmodel == mdHemisphere) return true; if(pmodel == mdDisk) return sphere; if(pmodel == mdHemisphere) return true; + if(pmodel == mdRotatedHyperboles) return true; return false; } @@ -201,6 +202,8 @@ int get_side(const hyperpoint& H) { return (H[2] <= -horizon) ? -1 : 1; ; } + if(pmodel == mdRotatedHyperboles) + return H[1] > 0 ? -1 : 1; if(pmodel == mdHyperboloid && hyperbolic) return (conformal::sin_ball * H[2] > -conformal::cos_ball * H[1]) ? -1 : 1; if(pmodel == mdHyperboloid && sphere)