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');
|
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');
|
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) {
|
if(pmodel == 4) {
|
||||||
dialog::addSelItem(XLAT("coefficient"),
|
dialog::addSelItem(XLAT("coefficient"),
|
||||||
fts4(polygonal::coefr[polygonal::coefid]), 'x');
|
fts4(polygonal::coefr[polygonal::coefid]), 'x');
|
||||||
@ -600,7 +615,11 @@ namespace conformal {
|
|||||||
void handleKeyC(int sym, int uni) {
|
void handleKeyC(int sym, int uni) {
|
||||||
dialog::handleNavigation(sym, 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();
|
if(on) clear();
|
||||||
else {
|
else {
|
||||||
if(canmove && !cheater) {
|
if(canmove && !cheater) {
|
||||||
@ -617,9 +636,13 @@ namespace conformal {
|
|||||||
|
|
||||||
switchagain: {
|
switchagain: {
|
||||||
pmodel = eModel((pmodel + (shiftmul > 0 ? 1 : -1) + MODELCOUNT) % MODELCOUNT);
|
pmodel = eModel((pmodel + (shiftmul > 0 ? 1 : -1) + MODELCOUNT) % MODELCOUNT);
|
||||||
if(sphere)
|
|
||||||
if(pmodel == mdHalfplane || pmodel == mdBand || pmodel == mdEquidistant || pmodel == mdEquiarea)
|
if(pmodel != mdEquidistant && pmodel != mdDisk && pmodel != mdEquiarea && pmodel != mdPolynomial && pmodel != mdHyperboloid) {
|
||||||
goto switchagain;
|
if(sphere && pmodel != mdBand)
|
||||||
|
goto switchagain;
|
||||||
|
if(euclid && pmodel != mdHalfplane && pmodel != mdBall)
|
||||||
|
goto switchagain;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
polygonal::solve();
|
polygonal::solve();
|
||||||
/* if(pmodel && vid.usingGL) {
|
/* if(pmodel && vid.usingGL) {
|
||||||
|
211
polygons.cpp
211
polygons.cpp
@ -388,6 +388,89 @@ double linewidthat(const hyperpoint& h, double minwidth) {
|
|||||||
}
|
}
|
||||||
return vid.linewidth;
|
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) {
|
void drawpolyline(polytodraw& p) {
|
||||||
auto pp = p.u.poly;
|
auto pp = p.u.poly;
|
||||||
@ -418,19 +501,20 @@ void drawpolyline(polytodraw& p) {
|
|||||||
|
|
||||||
addpoly(pp.V, pp.tab, pp.cnt);
|
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;
|
int poly_limit = max(vid.xres, vid.yres) * 2;
|
||||||
|
|
||||||
if(poly_flags & POLY_BEHIND) return;
|
if(poly_flags & POLY_BEHIND) return;
|
||||||
|
|
||||||
for(int i=0; i<qglcoords; i++) {
|
for(int i=0; i<qglcoords; i++) {
|
||||||
if(abs(glcoords[i][0]) > poly_limit || abs(glcoords[i][1]) > poly_limit)
|
if(abs(glcoords[i][0]) > poly_limit || abs(glcoords[i][1]) > poly_limit)
|
||||||
return; // too large!
|
return; // too large!
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sphere && vid.alphax > 1) {
|
if((spherespecial > 0 || pmodel == mdEquidistant || pmodel == mdEquiarea) && !(poly_flags & POLY_ISSIDE)) {
|
||||||
if(!hiliteclick && !(poly_flags & POLY_INFRONT)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(spherespecial > 0 && !(poly_flags & POLY_ISSIDE)) {
|
|
||||||
double rarea = 0;
|
double rarea = 0;
|
||||||
for(int i=0; i<qglcoords-1; i++)
|
for(int i=0; i<qglcoords-1; i++)
|
||||||
rarea += glcoords[i][0] * glcoords[i+1][1] - glcoords[i][1] * glcoords[i+1][0];
|
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;
|
else poly_flags &=~ POLY_INVERSE;
|
||||||
|
|
||||||
#if CAP_GL
|
if(sphere && vid.alphax > 1) {
|
||||||
if(vid.usingGL) {
|
if(!hiliteclick && !(poly_flags & POLY_INFRONT)) return;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
#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) {
|
int lastl = 0;
|
||||||
for(int t=0; t<polyi; t++) polyx[t] += x, polyy[t] += y;
|
|
||||||
aapolylineColor(s, polyx, polyy, polyi, pp.outline);
|
for(int l=mercator_loop_min; l <= mercator_loop_max; l++) {
|
||||||
for(int t=0; t<polyi; t++) polyx[t] -= x, polyy[t] -= y;
|
|
||||||
|
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;
|
vector<float> prettylinepoints;
|
||||||
|
Loading…
Reference in New Issue
Block a user