mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 09:30:35 +00:00
Mercator projection works now; fixed equidistant/equiarea on sphere
This commit is contained in:
parent
a3d4bfdd7d
commit
96243d143f
@ -554,11 +554,26 @@ namespace conformal {
|
||||
|
||||
dialog::addBoolItem(XLAT("include history"), (includeHistory), 'i');
|
||||
|
||||
bool notconformal = (pmodel >= 5 && pmodel <= 6) || abs(vid.alpha-1) > 1e-3;
|
||||
bool notconformal0 = (pmodel >= 5 && pmodel <= 6);
|
||||
bool notconformal = notconformal0 || abs(vid.alpha-1) > 1e-3;
|
||||
|
||||
dialog::addSelItem(notconformal ? XLAT("model used (not conformal!)") : XLAT("model used"), XLAT(modelnames[pmodel]), 'm');
|
||||
dialog::addSelItem(notconformal ? XLAT("model used (not conformal!)") : XLAT("model used"),
|
||||
XLAT(
|
||||
pmodel == mdBand && sphere ? "Mercator" :
|
||||
pmodel == mdHalfplane && euclid ? "inversion" :
|
||||
modelnames[pmodel]), 'm');
|
||||
dialog::addSelItem(XLAT("rotation"), directions[pmodel][rotation&3], 'r');
|
||||
|
||||
if(pmodel == mdBand && sphere)
|
||||
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
|
||||
|
||||
if(abs(vid.alpha-1) > 1e-3 && pmodel != mdBall && pmodel != mdHyperboloid) {
|
||||
dialog::addBreak(50);
|
||||
dialog::addInfo("NOTE: this works 'correctly' only if the Poincaré model/stereographic projection is used.");
|
||||
dialog::addBreak(50);
|
||||
dialog::addBoolItem("Switch", false, '6');
|
||||
}
|
||||
|
||||
if(pmodel == 4) {
|
||||
dialog::addSelItem(XLAT("coefficient"),
|
||||
fts4(polygonal::coefr[polygonal::coefid]), 'x');
|
||||
@ -600,7 +615,11 @@ namespace conformal {
|
||||
void handleKeyC(int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
|
||||
if(uni == 'e') {
|
||||
if(uni == '6')
|
||||
vid.alpha = 1, vid.scale = 1;
|
||||
else if(uni == 'z')
|
||||
editScale();
|
||||
else if(uni == 'e') {
|
||||
if(on) clear();
|
||||
else {
|
||||
if(canmove && !cheater) {
|
||||
@ -617,9 +636,13 @@ namespace conformal {
|
||||
|
||||
switchagain: {
|
||||
pmodel = eModel((pmodel + (shiftmul > 0 ? 1 : -1) + MODELCOUNT) % MODELCOUNT);
|
||||
if(sphere)
|
||||
if(pmodel == mdHalfplane || pmodel == mdBand || pmodel == mdEquidistant || pmodel == mdEquiarea)
|
||||
goto switchagain;
|
||||
|
||||
if(pmodel != mdEquidistant && pmodel != mdDisk && pmodel != mdEquiarea && pmodel != mdPolynomial && pmodel != mdHyperboloid) {
|
||||
if(sphere && pmodel != mdBand)
|
||||
goto switchagain;
|
||||
if(euclid && pmodel != mdHalfplane && pmodel != mdBall)
|
||||
goto switchagain;
|
||||
}
|
||||
}
|
||||
polygonal::solve();
|
||||
/* if(pmodel && vid.usingGL) {
|
||||
|
211
polygons.cpp
211
polygons.cpp
@ -388,6 +388,89 @@ double linewidthat(const hyperpoint& h, double minwidth) {
|
||||
}
|
||||
return vid.linewidth;
|
||||
}
|
||||
|
||||
|
||||
// -radius to +3radius
|
||||
|
||||
int mercator_coord;
|
||||
int mercator_loop_min = 0, mercator_loop_max = 0;
|
||||
|
||||
void fixMercator() {
|
||||
|
||||
ld period = 4 * vid.radius;
|
||||
ld hperiod = period / 2;
|
||||
|
||||
mercator_coord = 1;
|
||||
ld cmin = -vid.xcenter, cmax = vid.xres - vid.xcenter, dmin = -vid.ycenter, dmax = vid.yres - vid.ycenter;
|
||||
if(mercator_coord)
|
||||
swap(cmin, dmin), swap(cmax, dmax);
|
||||
|
||||
for(int i = 0; i<qglcoords; i++) {
|
||||
while(glcoords[0][mercator_coord] < hperiod) glcoords[0][mercator_coord] += period;
|
||||
while(glcoords[0][mercator_coord] > hperiod) glcoords[0][mercator_coord] -= period;
|
||||
}
|
||||
|
||||
ld first = glcoords[0][mercator_coord];
|
||||
ld next = first;
|
||||
|
||||
ld mincoord = first, maxcoord = first;
|
||||
|
||||
for(int i = 0; i<qglcoords; i++) {
|
||||
while(glcoords[i][mercator_coord] < next - hperiod)
|
||||
glcoords[i][mercator_coord] += period;
|
||||
while(glcoords[i][mercator_coord] > next + hperiod)
|
||||
glcoords[i][mercator_coord] -= period;
|
||||
next = glcoords[i][mercator_coord];
|
||||
mincoord = min<ld>(mincoord, glcoords[i][mercator_coord]);
|
||||
maxcoord = max<ld>(maxcoord, glcoords[i][mercator_coord]);
|
||||
}
|
||||
|
||||
ld last = first;
|
||||
while(last < next - hperiod) last += period;
|
||||
while(last > next + hperiod) last -= period;
|
||||
|
||||
if(first == last) {
|
||||
while(mincoord > cmin)
|
||||
mercator_loop_min--, mincoord -= period;
|
||||
while(maxcoord < cmax)
|
||||
mercator_loop_max++, maxcoord += period;
|
||||
}
|
||||
else {
|
||||
if(last < first) {
|
||||
reverse(glcoords, glcoords+qglcoords);
|
||||
swap(first, last);
|
||||
}
|
||||
while(maxcoord > cmin) {
|
||||
for(int i=0; i<qglcoords; i++) glcoords[i][mercator_coord] -= period;
|
||||
first -= period; last -= period;
|
||||
mincoord -= period; maxcoord -= period;
|
||||
}
|
||||
int base = qglcoords;
|
||||
int minto = mincoord;
|
||||
while(minto < cmax) {
|
||||
for(int i=0; i<base; i++) {
|
||||
for(int c=0; c<3; c++)
|
||||
glcoords[qglcoords][c] = glcoords[qglcoords-base][c];
|
||||
glcoords[qglcoords][mercator_coord] += period;
|
||||
qglcoords++;
|
||||
}
|
||||
minto += period;
|
||||
}
|
||||
for(int r=0; r<3; r++)
|
||||
glcoords[qglcoords][r] = glcoords[qglcoords-1][r];
|
||||
qglcoords++;
|
||||
for(int r=0; r<3; r++)
|
||||
glcoords[qglcoords][r] = glcoords[0][r];
|
||||
qglcoords++;
|
||||
for(int u=1; u<=2; u++) {
|
||||
auto& v = glcoords[qglcoords-u][1-mercator_coord];
|
||||
v = v < 0 ? dmin : dmax;
|
||||
}
|
||||
/* printf("cycling %d -> %d\n", base, qglcoords);
|
||||
for(int a=0; a<qglcoords; a++)
|
||||
printf("[%3d] %10.5lf %10.5lf\n", a, glcoords[a][0], glcoords[a][1]); */
|
||||
}
|
||||
}
|
||||
|
||||
void drawpolyline(polytodraw& p) {
|
||||
auto pp = p.u.poly;
|
||||
@ -418,19 +501,20 @@ void drawpolyline(polytodraw& p) {
|
||||
|
||||
addpoly(pp.V, pp.tab, pp.cnt);
|
||||
|
||||
mercator_loop_min = mercator_loop_max = 0;
|
||||
if(sphere && pmodel == mdBand)
|
||||
fixMercator();
|
||||
|
||||
int poly_limit = max(vid.xres, vid.yres) * 2;
|
||||
|
||||
|
||||
if(poly_flags & POLY_BEHIND) return;
|
||||
|
||||
for(int i=0; i<qglcoords; i++) {
|
||||
if(abs(glcoords[i][0]) > poly_limit || abs(glcoords[i][1]) > poly_limit)
|
||||
return; // too large!
|
||||
}
|
||||
|
||||
if(sphere && vid.alphax > 1) {
|
||||
if(!hiliteclick && !(poly_flags & POLY_INFRONT)) return;
|
||||
}
|
||||
|
||||
if(spherespecial > 0 && !(poly_flags & POLY_ISSIDE)) {
|
||||
if((spherespecial > 0 || pmodel == mdEquidistant || pmodel == mdEquiarea) && !(poly_flags & POLY_ISSIDE)) {
|
||||
double rarea = 0;
|
||||
for(int i=0; i<qglcoords-1; i++)
|
||||
rarea += glcoords[i][0] * glcoords[i+1][1] - glcoords[i][1] * glcoords[i+1][0];
|
||||
@ -446,60 +530,75 @@ void drawpolyline(polytodraw& p) {
|
||||
}
|
||||
else poly_flags &=~ POLY_INVERSE;
|
||||
|
||||
#if CAP_GL
|
||||
if(vid.usingGL) {
|
||||
// if(pmodel == 0) for(int i=0; i<qglcoords; i++) glcoords[i][2] = vid.scrdist;
|
||||
activateGlcoords();
|
||||
gldraw(3, Id, 0, qglcoords, p.col, pp.outline, poly_flags);
|
||||
return;
|
||||
if(sphere && vid.alphax > 1) {
|
||||
if(!hiliteclick && !(poly_flags & POLY_INFRONT)) return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CAP_SVG==1
|
||||
if(svg::in) {
|
||||
coords_to_poly();
|
||||
int col = p.col;
|
||||
if(poly_flags & POLY_INVERSE) col = 0;
|
||||
svg::polygon(polyx, polyy, polyi, col, pp.outline, pp.minwidth);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
coords_to_poly();
|
||||
|
||||
#if CAP_XGD==1
|
||||
gdpush(1); gdpush(p.col); gdpush(pp.outline); gdpush(polyi);
|
||||
for(int i=0; i<polyi; i++) gdpush(polyx[i]), gdpush(polyy[i]);
|
||||
#elif CAP_SDLGFX==1
|
||||
|
||||
if(poly_flags & POLY_INVERSE) {
|
||||
int i = polyi;
|
||||
polyx[i] = 0; polyy[i] = 0; i++;
|
||||
polyx[i] = vid.xres; polyy[i] = 0; i++;
|
||||
polyx[i] = vid.xres; polyy[i] = vid.yres; i++;
|
||||
polyx[i] = 0; polyy[i] = vid.yres; i++;
|
||||
polyx[i] = 0; polyy[i] = 0; i++;
|
||||
filledPolygonColorI(s, polyx, polyy, polyi+5, p.col);
|
||||
}
|
||||
else
|
||||
filledPolygonColorI(s, polyx, polyy, polyi, p.col);
|
||||
|
||||
if(vid.goteyes) filledPolygonColorI(aux, polyxr, polyy, polyi, p.col);
|
||||
|
||||
((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, pp.outline);
|
||||
if(vid.goteyes) aapolylineColor(aux, polyxr, polyy, polyi, pp.outline);
|
||||
|
||||
if(vid.xres >= 2000 || fatborder) {
|
||||
int xmi = 3000, xma = -3000;
|
||||
for(int t=0; t<polyi; t++) xmi = min(xmi, polyx[t]), xma = max(xma, polyx[t]);
|
||||
|
||||
if(xma > xmi + 20) for(int x=-1; x<2; x++) for(int y=-1; y<=2; y++) if(x*x+y*y == 1) {
|
||||
for(int t=0; t<polyi; t++) polyx[t] += x, polyy[t] += y;
|
||||
aapolylineColor(s, polyx, polyy, polyi, pp.outline);
|
||||
for(int t=0; t<polyi; t++) polyx[t] -= x, polyy[t] -= y;
|
||||
int lastl = 0;
|
||||
|
||||
for(int l=mercator_loop_min; l <= mercator_loop_max; l++) {
|
||||
|
||||
if(l || lastl) {
|
||||
for(int i=0; i<qglcoords; i++)
|
||||
glcoords[i][mercator_coord] += vid.radius * 4 * (l - lastl);
|
||||
lastl = l;
|
||||
}
|
||||
|
||||
#if CAP_GL
|
||||
if(vid.usingGL) {
|
||||
// if(pmodel == 0) for(int i=0; i<qglcoords; i++) glcoords[i][2] = vid.scrdist;
|
||||
activateGlcoords();
|
||||
gldraw(3, Id, 0, qglcoords, p.col, pp.outline, poly_flags);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CAP_SVG==1
|
||||
if(svg::in) {
|
||||
coords_to_poly();
|
||||
int col = p.col;
|
||||
if(poly_flags & POLY_INVERSE) col = 0;
|
||||
svg::polygon(polyx, polyy, polyi, col, pp.outline, pp.minwidth);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
coords_to_poly();
|
||||
|
||||
#if CAP_XGD==1
|
||||
gdpush(1); gdpush(p.col); gdpush(pp.outline); gdpush(polyi);
|
||||
for(int i=0; i<polyi; i++) gdpush(polyx[i]), gdpush(polyy[i]);
|
||||
#elif CAP_SDLGFX==1
|
||||
|
||||
if(poly_flags & POLY_INVERSE) {
|
||||
int i = polyi;
|
||||
polyx[i] = 0; polyy[i] = 0; i++;
|
||||
polyx[i] = vid.xres; polyy[i] = 0; i++;
|
||||
polyx[i] = vid.xres; polyy[i] = vid.yres; i++;
|
||||
polyx[i] = 0; polyy[i] = vid.yres; i++;
|
||||
polyx[i] = 0; polyy[i] = 0; i++;
|
||||
filledPolygonColorI(s, polyx, polyy, polyi+5, p.col);
|
||||
}
|
||||
else
|
||||
filledPolygonColorI(s, polyx, polyy, polyi, p.col);
|
||||
|
||||
if(vid.goteyes) filledPolygonColorI(aux, polyxr, polyy, polyi, p.col);
|
||||
|
||||
((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, pp.outline);
|
||||
if(vid.goteyes) aapolylineColor(aux, polyxr, polyy, polyi, pp.outline);
|
||||
|
||||
if(vid.xres >= 2000 || fatborder) {
|
||||
int xmi = 3000, xma = -3000;
|
||||
for(int t=0; t<polyi; t++) xmi = min(xmi, polyx[t]), xma = max(xma, polyx[t]);
|
||||
|
||||
if(xma > xmi + 20) for(int x=-1; x<2; x++) for(int y=-1; y<=2; y++) if(x*x+y*y == 1) {
|
||||
for(int t=0; t<polyi; t++) polyx[t] += x, polyy[t] += y;
|
||||
aapolylineColor(s, polyx, polyy, polyi, pp.outline);
|
||||
for(int t=0; t<polyi; t++) polyx[t] -= x, polyy[t] -= y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
vector<float> prettylinepoints;
|
||||
|
Loading…
Reference in New Issue
Block a user