From 5e2a65a7819d6ec93fa4824b1bfd6824b10817ad Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 1 Aug 2018 04:01:16 +0200 Subject: [PATCH] vertical stretch parameter is now available in all models; more details in equi-area --- basegraph.cpp | 15 +++++++++------ conformal.cpp | 29 ++++++++++++++++++++++++----- graph.cpp | 4 ++-- hud.cpp | 4 ++-- hypgraph.cpp | 3 +-- polygons.cpp | 23 +++++++++++++---------- screenshot.cpp | 11 ++++++++--- 7 files changed, 59 insertions(+), 30 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index 818c0c8c..aad64406 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -828,14 +828,14 @@ ld realradius() { void drawmessage(const string& s, int& y, int col) { int rrad = (int) realradius(); int space; - if(y > vid.ycenter + rrad) + if(y > vid.ycenter + rrad * vid.stretch) space = vid.xres; else if(y > vid.ycenter) - space = vid.xcenter - rhypot(rrad, y-vid.ycenter); + space = vid.xcenter - rhypot(rrad, (y-vid.ycenter) / vid.stretch); else if(y > vid.ycenter - vid.fsize) space = vid.xcenter - rrad; - else if(y > vid.ycenter - vid.fsize - rrad) - space = vid.xcenter - rhypot(rrad, vid.ycenter-vid.fsize-y); + else if(y > vid.ycenter - vid.fsize - rrad * vid.stretch) + space = vid.xcenter - rhypot(rrad, (vid.ycenter-vid.fsize-y) / vid.stretch); else space = vid.xres; @@ -920,7 +920,7 @@ void drawCircle(int x, int y, int size, int color) { if(ISMOBILE && pts > 72) pts = 72; for(int r=0; r(x + size * sin(rr), y + size * cos(rr), stereo::scrdist)); + glcoords.push_back(make_array(x + size * sin(rr), y + size * vid.stretch * cos(rr), stereo::scrdist)); } glhr::vertices(glcoords); glhr::set_depthtest(false); @@ -932,7 +932,10 @@ void drawCircle(int x, int y, int size, int color) { #if CAP_XGD gdpush(4); gdpush(color); gdpush(x); gdpush(y); gdpush(size); #elif CAP_SDLGFX - ((vid.antialias && AA_NOGL)?aacircleColor:circleColor) (s, x, y, size, color); + if(vid.stretch == 1) + ((vid.antialias && AA_NOGL)?aacircleColor:circleColor) (s, x, y, size, color); + else + ((vid.antialias && AA_NOGL)?aaellipseColor:ellipseColor) (s, x, y, size, size * vid.stretch, color); #elif CAP_SDL int pts = size * 4; if(pts > 1500) pts = 1500; diff --git a/conformal.cpp b/conformal.cpp index 64278b15..24f75f4b 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -641,9 +641,7 @@ namespace conformal { dialog::addSelItem(XLAT("parameter"), fts3(vid.twopoint_param), 'l'); } - if(among(pmodel, mdBandEquidistant, mdBandEquiarea)) { - dialog::addSelItem(XLAT("parameter"), fts3(vid.stretch), 'l'); - } + dialog::addSelItem(XLAT("vertical stretch"), fts3(vid.stretch), 's'); dialog::addBreak(100); dialog::addItem(XLAT("history mode"), 'a'); @@ -689,10 +687,31 @@ namespace conformal { #endif else if(uni == 'l' && pmodel == mdHalfplane) lower_halfplane = !lower_halfplane; - else if(uni == 'l' && among(pmodel, mdBandEquiarea, mdBandEquidistant)) - dialog::editNumber(vid.stretch, 0, 10, .1, 1, XLAT("parameter"), + else if(uni == 's') { + dialog::editNumber(vid.stretch, 0, 10, .1, 1, XLAT("vertical stretch"), "Vertical stretch factor." ); + dialog::extra_options = [] () { + dialog::addBreak(100); + if(sphere && pmodel == mdBandEquiarea) { + dialog::addBoolItem("Gall-Peters", vid.stretch == 2, 'o'); + dialog::add_action([] { vid.stretch = 2; dialog::ne.s = "2"; }); + } + if(pmodel == mdBandEquiarea) { + // y = K * sin(phi) + // cos(phi) * cos(phi) = 1/K + if(sphere && vid.stretch >= 1) { + ld phi = acos(sqrt(1/vid.stretch)); + dialog::addInfo(XLAT("The current value makes the map conformal at the latitude of %1 (%2°).", fts(phi), fts(phi * 180 / M_PI))); + } + else if(hyperbolic && abs(vid.stretch) <= 1 && abs(vid.stretch) >= 1e-9) { + ld phi = acosh(abs(sqrt(1/vid.stretch))); + dialog::addInfo(XLAT("The current value makes the map conformal %1 units from the main line.", fts(phi))); + } + else dialog::addInfo(""); + } + }; + } else if(uni == 'a') pushScreen(history_menu); else if(uni == 'l' && pmodel == mdHemisphere && euclid) { diff --git a/graph.cpp b/graph.cpp index 8328d153..0f283427 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2260,7 +2260,7 @@ void drawaura() { for(int x=0; x -1 ? rad * facs[z] : rad / facs[z]; int rm = r % AURA; cx[r][z][0] = rad0 * sin(rr); - cx[r][z][1] = rad0 * cos(rr); + cx[r][z][1] = rad0 * cos(rr) * vid.stretch; for(int u=0; u<3; u++) cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z]; } diff --git a/hud.cpp b/hud.cpp index 039b34b3..8afde15d 100644 --- a/hud.cpp +++ b/hud.cpp @@ -418,7 +418,7 @@ void drawStats() { int spots = 0; for(int u=vid.fsize; u rad) { + if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / vid.stretch) > rad) { spots++; } if(spots >= bycorner[cor] && spots >= 3) { @@ -431,7 +431,7 @@ void drawStats() { } for(int u=vid.fsize; u rad) { + if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / vid.stretch) > rad) { if(next >= isize(glyphstoshow)) break; int cx = u; diff --git a/hypgraph.cpp b/hypgraph.cpp index 7bac3aa1..8ab5f863 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -317,7 +317,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) { break; } case mdBandEquiarea: { - y = sin_auto(y) * vid.stretch; + y = sin_auto(y); break; } case mdSinusoidal: { @@ -325,7 +325,6 @@ void applymodel(hyperpoint H, hyperpoint& ret) { break; } case mdBandEquidistant: { - y *= vid.stretch; break; } default: { diff --git a/polygons.cpp b/polygons.cpp index 2c8523b4..dc59e379 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -178,6 +178,7 @@ void addpoint(const hyperpoint& H) { hyperpoint Hscr; applymodel(H, Hscr); for(int i=0; i<3; i++) Hscr[i] *= vid.radius; + Hscr[1] *= vid.stretch; // if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND; if(spherespecial) { @@ -314,6 +315,8 @@ void glapplymatrix(const transmatrix& V) { mat[13] = 0; mat[14] = GLfloat(vid.alpha); mat[15] = 1; + + if(vid.stretch != 1) mat[1] *= vid.stretch, mat[5] *= vid.stretch, mat[9] *= vid.stretch, mat[13] *= vid.stretch; glhr::set_modelview(glhr::as_glmatrix(mat)); } @@ -451,7 +454,7 @@ void fixMercator(bool tinf) { if(pmodel == mdSinusoidal) for(int i = 0; i(vid.radius * sin(a), vid.radius * cos(a), stereo::scrdist)); + glcoords.push_back(make_array(vid.radius * sin(a), vid.radius * vid.stretch * cos(a), stereo::scrdist)); } poly_flags ^= POLY_INVERSE; } @@ -2513,7 +2516,7 @@ void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) { hyperpoint hscr; applymodel(h, hscr); xc = vid.xcenter + vid.radius * hscr[0]; - yc = vid.ycenter + vid.radius * hscr[1]; + yc = vid.ycenter + vid.radius * vid.stretch * hscr[1]; sc = 0; // EYETODO sc = vid.eye * vid.radius * hscr[2]; } diff --git a/screenshot.cpp b/screenshot.cpp index 22b6a1d9..7ac5fe6a 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -73,9 +73,14 @@ namespace svg { void circle(int x, int y, int size, int col) { int ba = (backcolor << 8) + 0xFF; - if(!invisible(col)) - fprintf(f, "\n", - coord(x), coord(y), coord(size), stylestr(ba, col)); + if(!invisible(col)) { + if(vid.stretch == 1) + fprintf(f, "\n", + coord(x), coord(y), coord(size), stylestr(ba, col)); + else + fprintf(f, "\n", + coord(x), coord(y), coord(size), coord(size*vid.stretch), stylestr(ba, col)); + } } const string *link;