diff --git a/basegraph.cpp b/basegraph.cpp index 3bd0904a..49a9b89f 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -298,7 +298,7 @@ void display_data::set_projection(int ed) { if(vid.consider_shader_projection && pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1) && MDIM == 3) shaderside_projection = true; else if(vid.consider_shader_projection && !glhr::noshaders) { - if(pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1) && GDIM == 3 && apply_models) + if(pmodel == (nonisotropic ? mdHyperboloid : mdDisk) && !spherespecial && !(hyperbolic && vid.alpha <= -1) && GDIM == 3 && apply_models) shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::ball; if(pmodel == mdBand && hyperbolic && apply_models) shaderside_projection = true, glhr::new_shader_projection = (GDIM == 2 ? glhr::shader_projection::band : glhr::shader_projection::band3); diff --git a/drawing.cpp b/drawing.cpp index 34e2aff0..8b4571c1 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -211,7 +211,7 @@ void add1(const hyperpoint& H) { } bool is_behind(const hyperpoint& H) { - return pmodel == mdDisk && (hyperbolic ? H[2] >= 0 : true) && vid.alpha + H[2] <= BEHIND_LIMIT; + return pmodel == mdDisk && (hyperbolic ? H[2] >= 0 : true) && (nonisotropic ? false : vid.alpha + H[2] <= BEHIND_LIMIT); } hyperpoint be_just_on_view(const hyperpoint& H1, const hyperpoint &H2) { diff --git a/geom-exp.cpp b/geom-exp.cpp index 0d0bf225..5ea3ecf4 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -494,13 +494,14 @@ void ge_select_tiling() { } EX string current_proj_name() { - if(pmodel != mdDisk || nonisotropic) + bool h = hyperbolic || solnih; + if(pmodel != mdDisk) return models::get_model_name(pmodel); - else if(hyperbolic && vid.alpha == 1) + else if(h && vid.alpha == 1) return XLAT("Poincaré model"); - else if(hyperbolic && vid.alpha == 0) + else if(h && vid.alpha == 0) return XLAT("Klein-Beltrami model"); - else if(hyperbolic && vid.alpha == -1) + else if(h && vid.alpha == -1) return XLAT("inverted Poincaré model"); else if(sphere && vid.alpha == 1) return XLAT("stereographic projection"); @@ -508,7 +509,7 @@ EX string current_proj_name() { return XLAT("gnomonic projection"); else if(sphere && vid.alpha >= 999) return XLAT("orthographic projection"); - else if(hyperbolic && vid.alpha >= 999) + else if(h && vid.alpha >= 999) return XLAT("Gans model"); else return XLAT("general perspective"); diff --git a/hypgraph.cpp b/hypgraph.cpp index 9dce8659..b358e4c6 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -353,7 +353,22 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) { } case mdDisk: { - if(nisot::local_perspective_used()) H = nisot::local_perspective * H; + if(nonisotropic) { + ret = lp_apply(inverse_exp(H, iTable, true)); + ld w; + if(solnih) { + // w = 1 / sqrt(1 - sqhypot_d(3, ret)); + // w = w / (vid.alpha + w); + w = 1 / (sqrt(1 - sqhypot_d(3, ret)) * vid.alpha + 1); + } + else { + w = hypot_d(3, ret); + w = sinh(w) / ((vid.alpha + cosh(w)) * w); + } + for(int i=0; i<3; i++) ret[i] *= w; + ret[3] = 1; + break; + } ld tz = get_tz(H); if(!vid.camera_angle) { ret[0] = H[0] / tz; @@ -472,7 +487,12 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) { case mdHyperboloidFlat: case mdHyperboloid: { - + + if(nonisotropic) { + // if(nisot::local_perspective_used()) H = nisot::local_perspective * H; + ret = H; + break; + } if(pmodel == mdHyperboloid) { ld& topz = models::top_z; if(H[2] > topz) { @@ -495,8 +515,15 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) { } case mdFisheye: { - ld zlev = find_zlev(H); - H = space_to_perspective(H); + ld zlev; + if(nonisotropic) { + H = lp_apply(inverse_exp(H, iTable, false)); + zlev = 1; + } + else { + zlev = find_zlev(H); + H = space_to_perspective(H); + } H /= vid.fisheye_param; H[LDIM] = zlev; ret = H / sqrt(1 + sqhypot_d(GDIM+1, H)); diff --git a/models.cpp b/models.cpp index 48640fec..09700ee2 100644 --- a/models.cpp +++ b/models.cpp @@ -200,7 +200,7 @@ EX namespace models { EX bool model_available(eModel pm) { if(prod) return pm == mdPerspective; if(sl2) return pm == mdGeodesic; - if(nonisotropic) return among(pm, mdDisk, mdPerspective, mdGeodesic, mdEquidistant); + if(nonisotropic) return among(pm, mdDisk, mdPerspective, mdHyperboloid, mdGeodesic, mdEquidistant, mdFisheye); if(pm == mdGeodesic && !sol) return false; if(sphere && (pm == mdHalfplane || pm == mdBall)) return false; @@ -223,13 +223,13 @@ EX namespace models { int editpos = 0; EX string get_model_name(eModel m) { - if(m == mdDisk && GDIM == 3 && hyperbolic) return XLAT("ball model/Gans"); + if(m == mdDisk && GDIM == 3 && (hyperbolic || nonisotropic)) return XLAT("ball model/Gans"); if(m == mdPerspective && prod) return XLAT("native perspective"); if(nonisotropic) { - if(m == mdDisk) return XLAT("simple model: projection"); + if(m == mdHyperboloid) return XLAT("simple model: projection"); if(m == mdPerspective) return XLAT("simple model: perspective"); if(m == mdGeodesic) return XLAT("native perspective"); - if(m == mdEquidistant) return XLAT(mdinf[m].name_hyperbolic); + if(m == mdEquidistant || m == mdFisheye) return XLAT(mdinf[m].name_hyperbolic); } if(m == mdDisk && GDIM == 3) return XLAT("perspective in 4D"); if(m == mdHalfplane && GDIM == 3 && hyperbolic) return XLAT("half-space");