-
Notifications
You must be signed in to change notification settings - Fork 202
/
Copy pathhufnagel.js
91 lines (80 loc) · 2.33 KB
/
hufnagel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { geoProjectionMutator as projectionMutator } from "d3-geo";
import { asin, cos, degrees, pi, radians, sign, sin, sqrt } from "./math.js";
import { solve } from "./newton.js";
export function hufnagelRaw(a, b, psiMax, ratio) {
var k = sqrt(
(4 * pi) /
(2 * psiMax +
(1 + a - b / 2) * sin(2 * psiMax) +
((a + b) / 2) * sin(4 * psiMax) +
(b / 2) * sin(6 * psiMax))
),
c = sqrt(
ratio *
sin(psiMax) *
sqrt((1 + a * cos(2 * psiMax) + b * cos(4 * psiMax)) / (1 + a + b))
),
M = psiMax * mapping(1);
function radius(psi) {
return sqrt(1 + a * cos(2 * psi) + b * cos(4 * psi));
}
function mapping(t) {
var psi = t * psiMax;
return (
(2 * psi +
(1 + a - b / 2) * sin(2 * psi) +
((a + b) / 2) * sin(4 * psi) +
(b / 2) * sin(6 * psi)) /
psiMax
);
}
function inversemapping(psi) {
return radius(psi) * sin(psi);
}
var forward = function(lambda, phi) {
var psi = psiMax * solve(mapping, (M * sin(phi)) / psiMax, phi / pi);
if (isNaN(psi)) psi = psiMax * sign(phi);
var kr = k * radius(psi);
return [((kr * c * lambda) / pi) * cos(psi), (kr / c) * sin(psi)];
};
forward.invert = function(x, y) {
var psi = solve(inversemapping, (y * c) / k);
return [
(x * pi) / (cos(psi) * k * c * radius(psi)),
asin((psiMax * mapping(psi / psiMax)) / M)
];
};
if (psiMax === 0) {
k = sqrt(ratio / pi);
forward = function(lambda, phi) {
return [lambda * k, sin(phi) / k];
};
forward.invert = function(x, y) {
return [x / k, asin(y * k)];
};
}
return forward;
}
export default function() {
var a = 1,
b = 0,
psiMax = 45 * radians,
ratio = 2,
mutate = projectionMutator(hufnagelRaw),
projection = mutate(a, b, psiMax, ratio);
projection.a = function(_) {
return arguments.length ? mutate((a = +_), b, psiMax, ratio) : a;
};
projection.b = function(_) {
return arguments.length ? mutate(a, (b = +_), psiMax, ratio) : b;
};
projection.psiMax = function(_) {
return arguments.length
? mutate(a, b, (psiMax = +_ * radians), ratio)
: psiMax * degrees;
};
projection.ratio = function(_) {
return arguments.length ? mutate(a, b, psiMax, (ratio = +_)) : ratio;
};
return projection.scale(180.739);
}