mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-25 07:20:09 +00:00
vertical stretch parameter is now available in all models; more details in equi-area
This commit is contained in:
parent
1e15992a22
commit
5e2a65a781
@ -828,14 +828,14 @@ ld realradius() {
|
|||||||
void drawmessage(const string& s, int& y, int col) {
|
void drawmessage(const string& s, int& y, int col) {
|
||||||
int rrad = (int) realradius();
|
int rrad = (int) realradius();
|
||||||
int space;
|
int space;
|
||||||
if(y > vid.ycenter + rrad)
|
if(y > vid.ycenter + rrad * vid.stretch)
|
||||||
space = vid.xres;
|
space = vid.xres;
|
||||||
else if(y > vid.ycenter)
|
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)
|
else if(y > vid.ycenter - vid.fsize)
|
||||||
space = vid.xcenter - rrad;
|
space = vid.xcenter - rrad;
|
||||||
else if(y > vid.ycenter - vid.fsize - rrad)
|
else if(y > vid.ycenter - vid.fsize - rrad * vid.stretch)
|
||||||
space = vid.xcenter - rhypot(rrad, vid.ycenter-vid.fsize-y);
|
space = vid.xcenter - rhypot(rrad, (vid.ycenter-vid.fsize-y) / vid.stretch);
|
||||||
else
|
else
|
||||||
space = vid.xres;
|
space = vid.xres;
|
||||||
|
|
||||||
@ -920,7 +920,7 @@ void drawCircle(int x, int y, int size, int color) {
|
|||||||
if(ISMOBILE && pts > 72) pts = 72;
|
if(ISMOBILE && pts > 72) pts = 72;
|
||||||
for(int r=0; r<pts; r++) {
|
for(int r=0; r<pts; r++) {
|
||||||
float rr = (M_PI * 2 * r) / pts;
|
float rr = (M_PI * 2 * r) / pts;
|
||||||
glcoords.push_back(make_array<GLfloat>(x + size * sin(rr), y + size * cos(rr), stereo::scrdist));
|
glcoords.push_back(make_array<GLfloat>(x + size * sin(rr), y + size * vid.stretch * cos(rr), stereo::scrdist));
|
||||||
}
|
}
|
||||||
glhr::vertices(glcoords);
|
glhr::vertices(glcoords);
|
||||||
glhr::set_depthtest(false);
|
glhr::set_depthtest(false);
|
||||||
@ -932,7 +932,10 @@ void drawCircle(int x, int y, int size, int color) {
|
|||||||
#if CAP_XGD
|
#if CAP_XGD
|
||||||
gdpush(4); gdpush(color); gdpush(x); gdpush(y); gdpush(size);
|
gdpush(4); gdpush(color); gdpush(x); gdpush(y); gdpush(size);
|
||||||
#elif CAP_SDLGFX
|
#elif CAP_SDLGFX
|
||||||
|
if(vid.stretch == 1)
|
||||||
((vid.antialias && AA_NOGL)?aacircleColor:circleColor) (s, x, y, size, color);
|
((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
|
#elif CAP_SDL
|
||||||
int pts = size * 4;
|
int pts = size * 4;
|
||||||
if(pts > 1500) pts = 1500;
|
if(pts > 1500) pts = 1500;
|
||||||
|
@ -641,9 +641,7 @@ namespace conformal {
|
|||||||
dialog::addSelItem(XLAT("parameter"), fts3(vid.twopoint_param), 'l');
|
dialog::addSelItem(XLAT("parameter"), fts3(vid.twopoint_param), 'l');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(among(pmodel, mdBandEquidistant, mdBandEquiarea)) {
|
dialog::addSelItem(XLAT("vertical stretch"), fts3(vid.stretch), 's');
|
||||||
dialog::addSelItem(XLAT("parameter"), fts3(vid.stretch), 'l');
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
dialog::addItem(XLAT("history mode"), 'a');
|
dialog::addItem(XLAT("history mode"), 'a');
|
||||||
@ -689,10 +687,31 @@ namespace conformal {
|
|||||||
#endif
|
#endif
|
||||||
else if(uni == 'l' && pmodel == mdHalfplane)
|
else if(uni == 'l' && pmodel == mdHalfplane)
|
||||||
lower_halfplane = !lower_halfplane;
|
lower_halfplane = !lower_halfplane;
|
||||||
else if(uni == 'l' && among(pmodel, mdBandEquiarea, mdBandEquidistant))
|
else if(uni == 's') {
|
||||||
dialog::editNumber(vid.stretch, 0, 10, .1, 1, XLAT("parameter"),
|
dialog::editNumber(vid.stretch, 0, 10, .1, 1, XLAT("vertical stretch"),
|
||||||
"Vertical stretch factor."
|
"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')
|
else if(uni == 'a')
|
||||||
pushScreen(history_menu);
|
pushScreen(history_menu);
|
||||||
else if(uni == 'l' && pmodel == mdHemisphere && euclid) {
|
else if(uni == 'l' && pmodel == mdHemisphere && euclid) {
|
||||||
|
@ -2260,7 +2260,7 @@ void drawaura() {
|
|||||||
for(int x=0; x<vid.xres; x++) {
|
for(int x=0; x<vid.xres; x++) {
|
||||||
|
|
||||||
ld hx = (x * 1. - vid.xcenter) / rad;
|
ld hx = (x * 1. - vid.xcenter) / rad;
|
||||||
ld hy = (y * 1. - vid.ycenter) / rad;
|
ld hy = (y * 1. - vid.ycenter) / rad / vid.stretch;
|
||||||
|
|
||||||
if(vid.camera_angle) camrotate(hx, hy);
|
if(vid.camera_angle) camrotate(hx, hy);
|
||||||
|
|
||||||
@ -2315,7 +2315,7 @@ void drawaura() {
|
|||||||
float rad0 = vid.alpha > -1 ? rad * facs[z] : rad / facs[z];
|
float rad0 = vid.alpha > -1 ? rad * facs[z] : rad / facs[z];
|
||||||
int rm = r % AURA;
|
int rm = r % AURA;
|
||||||
cx[r][z][0] = rad0 * sin(rr);
|
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++)
|
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];
|
cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z];
|
||||||
}
|
}
|
||||||
|
4
hud.cpp
4
hud.cpp
@ -418,7 +418,7 @@ void drawStats() {
|
|||||||
int spots = 0;
|
int spots = 0;
|
||||||
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
|
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
|
||||||
for(int v=vid.fsize; v<vid.yres/2-s; v += s)
|
for(int v=vid.fsize; v<vid.yres/2-s; v += s)
|
||||||
if(hypot(vid.xres/2-u-s, vid.yres/2-v-s) > rad) {
|
if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / vid.stretch) > rad) {
|
||||||
spots++;
|
spots++;
|
||||||
}
|
}
|
||||||
if(spots >= bycorner[cor] && spots >= 3) {
|
if(spots >= bycorner[cor] && spots >= 3) {
|
||||||
@ -431,7 +431,7 @@ void drawStats() {
|
|||||||
}
|
}
|
||||||
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
|
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
|
||||||
for(int v=vid.fsize; v<vid.yres/2-s; v += s)
|
for(int v=vid.fsize; v<vid.yres/2-s; v += s)
|
||||||
if(hypot(vid.xres/2-u-s, vid.yres/2-v-s) > rad) {
|
if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / vid.stretch) > rad) {
|
||||||
if(next >= isize(glyphstoshow)) break;
|
if(next >= isize(glyphstoshow)) break;
|
||||||
|
|
||||||
int cx = u;
|
int cx = u;
|
||||||
|
@ -317,7 +317,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case mdBandEquiarea: {
|
case mdBandEquiarea: {
|
||||||
y = sin_auto(y) * vid.stretch;
|
y = sin_auto(y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case mdSinusoidal: {
|
case mdSinusoidal: {
|
||||||
@ -325,7 +325,6 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case mdBandEquidistant: {
|
case mdBandEquidistant: {
|
||||||
y *= vid.stretch;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
23
polygons.cpp
23
polygons.cpp
@ -178,6 +178,7 @@ void addpoint(const hyperpoint& H) {
|
|||||||
hyperpoint Hscr;
|
hyperpoint Hscr;
|
||||||
applymodel(H, Hscr);
|
applymodel(H, Hscr);
|
||||||
for(int i=0; i<3; i++) Hscr[i] *= vid.radius;
|
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(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
|
||||||
|
|
||||||
if(spherespecial) {
|
if(spherespecial) {
|
||||||
@ -315,6 +316,8 @@ void glapplymatrix(const transmatrix& V) {
|
|||||||
mat[14] = GLfloat(vid.alpha);
|
mat[14] = GLfloat(vid.alpha);
|
||||||
mat[15] = 1;
|
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));
|
glhr::set_modelview(glhr::as_glmatrix(mat));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +454,7 @@ void fixMercator(bool tinf) {
|
|||||||
|
|
||||||
if(pmodel == mdSinusoidal)
|
if(pmodel == mdSinusoidal)
|
||||||
for(int i = 0; i<isize(glcoords); i++)
|
for(int i = 0; i<isize(glcoords); i++)
|
||||||
glcoords[i][mercator_coord] /= cos(glcoords[i][1] / vid.radius * M_PI);
|
glcoords[i][mercator_coord] /= cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||||
|
|
||||||
ld hperiod = mercator_period / 2;
|
ld hperiod = mercator_period / 2;
|
||||||
|
|
||||||
@ -460,7 +463,7 @@ void fixMercator(bool tinf) {
|
|||||||
if(mercator_coord)
|
if(mercator_coord)
|
||||||
swap(cmin, dmin), swap(cmax, dmax);
|
swap(cmin, dmin), swap(cmax, dmax);
|
||||||
if(pmodel == mdSinusoidal)
|
if(pmodel == mdSinusoidal)
|
||||||
dmin = -vid.radius / 2, dmax = vid.radius / 2;
|
dmin = -vid.stretch * vid.radius / 2, dmax = vid.stretch * vid.radius / 2;
|
||||||
if(pmodel == mdBandEquidistant)
|
if(pmodel == mdBandEquidistant)
|
||||||
dmin = -vid.stretch * vid.radius / 2, dmax = vid.stretch * vid.radius / 2;
|
dmin = -vid.stretch * vid.radius / 2, dmax = vid.stretch * vid.radius / 2;
|
||||||
if(pmodel == mdBandEquiarea)
|
if(pmodel == mdBandEquiarea)
|
||||||
@ -502,7 +505,7 @@ void fixMercator(bool tinf) {
|
|||||||
mercator_loop_max++, maxcoord += mercator_period;
|
mercator_loop_max++, maxcoord += mercator_period;
|
||||||
if(pmodel == mdSinusoidal)
|
if(pmodel == mdSinusoidal)
|
||||||
for(int i = 0; i<isize(glcoords); i++)
|
for(int i = 0; i<isize(glcoords); i++)
|
||||||
glcoords[i][mercator_coord] *= cos(glcoords[i][1] / vid.radius * M_PI);
|
glcoords[i][mercator_coord] *= cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(tinf) {
|
if(tinf) {
|
||||||
@ -529,7 +532,7 @@ void fixMercator(bool tinf) {
|
|||||||
}
|
}
|
||||||
if(pmodel == mdSinusoidal)
|
if(pmodel == mdSinusoidal)
|
||||||
for(int i = 0; i<isize(glcoords); i++)
|
for(int i = 0; i<isize(glcoords); i++)
|
||||||
glcoords[i][mercator_coord] *= cos(glcoords[i][1] / vid.radius * M_PI);
|
glcoords[i][mercator_coord] *= cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||||
glcoords.push_back(glcoords.back());
|
glcoords.push_back(glcoords.back());
|
||||||
glcoords.push_back(glcoords[0]);
|
glcoords.push_back(glcoords[0]);
|
||||||
for(int u=1; u<=2; u++) {
|
for(int u=1; u<=2; u++) {
|
||||||
@ -595,7 +598,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
twopoint_sphere_flips = j;
|
twopoint_sphere_flips = j;
|
||||||
hyperpoint h2; applymodel(h1, h2);
|
hyperpoint h2; applymodel(h1, h2);
|
||||||
using namespace hyperpoint_vec;
|
using namespace hyperpoint_vec;
|
||||||
glvertex h = glhr::pointtogl(h2 * vid.radius);
|
glvertex h = glhr::pointtogl(h2 * vid.radius); h[1] *= vid.stretch;
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
phases[j].push_back(h);
|
phases[j].push_back(h);
|
||||||
else {
|
else {
|
||||||
@ -624,7 +627,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
using namespace hyperpoint_vec;
|
using namespace hyperpoint_vec;
|
||||||
|
|
||||||
hyperpoint h1 = pp.V * glhr::gltopoint((*pp.tab)[pp.offset+i]);
|
hyperpoint h1 = pp.V * glhr::gltopoint((*pp.tab)[pp.offset+i]);
|
||||||
hyperpoint mh1; applymodel(h1, mh1);
|
hyperpoint mh1; applymodel(h1, mh1); mh1[1] *= vid.stretch;
|
||||||
phases[cpha].push_back(glhr::pointtogl(mh1 * vid.radius));
|
phases[cpha].push_back(glhr::pointtogl(mh1 * vid.radius));
|
||||||
|
|
||||||
// check if the i-th edge intersects the boundary of the ellipse
|
// check if the i-th edge intersects the boundary of the ellipse
|
||||||
@ -719,7 +722,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
hyperpoint hscr;
|
hyperpoint hscr;
|
||||||
hyperpoint h1 = pp.V * intester;
|
hyperpoint h1 = pp.V * intester;
|
||||||
if(is_behind(h1)) nofill = true;
|
if(is_behind(h1)) nofill = true;
|
||||||
applymodel(h1, hscr); hscr[0] *= vid.radius; hscr[1] *= vid.radius;
|
applymodel(h1, hscr); hscr[0] *= vid.radius; hscr[1] *= vid.radius * vid.stretch;
|
||||||
for(int i=0; i<isize(glcoords)-1; i++) {
|
for(int i=0; i<isize(glcoords)-1; i++) {
|
||||||
double x1 = glcoords[i][0] - hscr[0];
|
double x1 = glcoords[i][0] - hscr[0];
|
||||||
double y1 = glcoords[i][1] - hscr[1];
|
double y1 = glcoords[i][1] - hscr[1];
|
||||||
@ -771,7 +774,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
if(l || lastl) {
|
if(l || lastl) {
|
||||||
for(int i=0; i<isize(glcoords); i++) {
|
for(int i=0; i<isize(glcoords); i++) {
|
||||||
if(pmodel == mdSinusoidal)
|
if(pmodel == mdSinusoidal)
|
||||||
mercator_period = 2 * vid.radius * cos(glcoords[i][1] / vid.radius * M_PI);
|
mercator_period = 2 * vid.radius * cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||||
glcoords[i][mercator_coord] += mercator_period * (l - lastl);
|
glcoords[i][mercator_coord] += mercator_period * (l - lastl);
|
||||||
}
|
}
|
||||||
lastl = l;
|
lastl = l;
|
||||||
@ -783,7 +786,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
ld h = atan2(glcoords[0][0], glcoords[0][1]);
|
ld h = atan2(glcoords[0][0], glcoords[0][1]);
|
||||||
for(int i=0; i<=360; i++) {
|
for(int i=0; i<=360; i++) {
|
||||||
ld a = i * M_PI / 180 + h;
|
ld a = i * M_PI / 180 + h;
|
||||||
glcoords.push_back(make_array<GLfloat>(vid.radius * sin(a), vid.radius * cos(a), stereo::scrdist));
|
glcoords.push_back(make_array<GLfloat>(vid.radius * sin(a), vid.radius * vid.stretch * cos(a), stereo::scrdist));
|
||||||
}
|
}
|
||||||
poly_flags ^= POLY_INVERSE;
|
poly_flags ^= POLY_INVERSE;
|
||||||
}
|
}
|
||||||
@ -2513,7 +2516,7 @@ void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) {
|
|||||||
hyperpoint hscr;
|
hyperpoint hscr;
|
||||||
applymodel(h, hscr);
|
applymodel(h, hscr);
|
||||||
xc = vid.xcenter + vid.radius * hscr[0];
|
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;
|
sc = 0;
|
||||||
// EYETODO sc = vid.eye * vid.radius * hscr[2];
|
// EYETODO sc = vid.eye * vid.radius * hscr[2];
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,14 @@ namespace svg {
|
|||||||
|
|
||||||
void circle(int x, int y, int size, int col) {
|
void circle(int x, int y, int size, int col) {
|
||||||
int ba = (backcolor << 8) + 0xFF;
|
int ba = (backcolor << 8) + 0xFF;
|
||||||
if(!invisible(col))
|
if(!invisible(col)) {
|
||||||
|
if(vid.stretch == 1)
|
||||||
fprintf(f, "<circle cx='%s' cy='%s' r='%s' %s/>\n",
|
fprintf(f, "<circle cx='%s' cy='%s' r='%s' %s/>\n",
|
||||||
coord(x), coord(y), coord(size), stylestr(ba, col));
|
coord(x), coord(y), coord(size), stylestr(ba, col));
|
||||||
|
else
|
||||||
|
fprintf(f, "<circle cx='%s' cy='%s' rx='%s' ry='%s' %s/>\n",
|
||||||
|
coord(x), coord(y), coord(size), coord(size*vid.stretch), stylestr(ba, col));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string *link;
|
const string *link;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user