azimuthal equivolume projection

This commit is contained in:
Zeno Rogue 2019-03-30 17:45:56 +01:00
parent 99dc6b8dd7
commit 2b61413a81
6 changed files with 19 additions and 4 deletions

View File

@ -585,6 +585,7 @@ const modelinfo models[int(mdPolynomial)+1] = {
{X3("rotated hyperboles"), mf::hyper_only},
{X3("spiral"), mf::hyper_or_torus | mf::quasiband},
{X3("native perspective"), 0},
{X3("azimuthal equi-volume"), mf::azimuthal | mf::equivolume | mf::euc_boring},
{X3(""), 0},
{X3(""), 0},
{X3(""), 0},

View File

@ -258,6 +258,7 @@ enum eModel {
mdHemisphere, mdBandEquidistant, mdBandEquiarea, mdSinusoidal, mdTwoPoint,
mdFisheye, mdJoukowsky, mdJoukowskyInverted,
mdRotatedHyperboles, mdSpiral, mdPerspective,
mdEquivolume,
mdGUARD, mdUnchanged, mdHyperboloidFlat, mdPolynomial
};
@ -274,6 +275,7 @@ namespace mf {
static const flagtype hyper_only = 128;
static const flagtype hyper_or_torus = 256;
static const flagtype quasiband = 512;
static const flagtype equivolume = 1024;
};
struct modelinfo {

View File

@ -609,6 +609,7 @@ namespace conformal {
if(sphere && (pm == mdHalfplane || pm == mdBall))
return false;
if(DIM == 2 && pm == mdPerspective) return false;
if(DIM == 2 && pm == mdEquivolume) return false;
if(DIM == 3 && among(pm, mdBall, mdHyperboloid, mdFormula, mdPolygonal, mdRotatedHyperboles, mdSpiral, mdHemisphere)) return false;
return true;
}

View File

@ -2232,9 +2232,9 @@ void drawShape(pair<ld,ld>* coords, int qty, color_t color);
extern eModel pmodel;
inline bool mdAzimuthalEqui() { return pmodel == mdEquidistant || pmodel == mdEquiarea; }
inline bool mdAzimuthalEqui() { return among(pmodel, mdEquidistant, mdEquiarea, mdEquivolume); }
inline bool mdBandAny() { return pmodel == mdBand || pmodel == mdBandEquidistant || pmodel == mdBandEquiarea || pmodel == mdSinusoidal; }
inline bool mdBandAny() { return among(pmodel, mdBand, mdBandEquidistant, mdBandEquiarea, mdSinusoidal); }
color_t darkena(color_t c, int lev, int a);

View File

@ -67,6 +67,15 @@ ld asin_auto(ld x) {
}
}
ld volume_auto(ld r) {
switch(cgclass) {
case gcEuclid: return 4 * r * r * r / 3 * M_PI;
case gcHyperbolic: return M_PI * (sinh(2*r) - 2 * r);
case gcSphere: return M_PI * (2 * r - sin(2*r));
default: return 0;
}
}
ld asin_auto_clamp(ld x) {
switch(cgclass) {
case gcEuclid: return x;

View File

@ -557,7 +557,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
makeband(H, ret, [] (ld& x, ld& y) { x *= cos_auto(y); });
break;
case mdEquidistant: case mdEquiarea: {
case mdEquidistant: case mdEquiarea: case mdEquivolume: {
ld zlev = find_zlev(H);
ld rad = hypot_d(DIM, H);
@ -568,7 +568,9 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
// 4 pi / 2pi = M_PI
if(pmodel == mdEquiarea && sphere)
if(pmodel == mdEquivolume)
d = pow(volume_auto(d), 1/3.) * pow(M_PI / 2, 1/3.);
else if(pmodel == mdEquiarea && sphere)
d = sqrt(2*(1 - cos(d))) * M_PI / 2;
else if(pmodel == mdEquiarea && hyperbolic)
d = sqrt(2*(cosh(d) - 1)) / 1.5;