forked from d3/d3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcentroid.js
More file actions
111 lines (99 loc) · 3.37 KB
/
Copy pathcentroid.js
File metadata and controls
111 lines (99 loc) · 3.37 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import "../math/trigonometry";
import "geo";
import "stream";
d3.geo.centroid = function(object) {
d3_geo_centroidDimension = d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
d3.geo.stream(object, d3_geo_centroid);
var m;
if (d3_geo_centroidW &&
Math.abs(m = Math.sqrt(d3_geo_centroidX * d3_geo_centroidX + d3_geo_centroidY * d3_geo_centroidY + d3_geo_centroidZ * d3_geo_centroidZ)) > ε) {
return [
Math.atan2(d3_geo_centroidY, d3_geo_centroidX) * d3_degrees,
Math.asin(Math.max(-1, Math.min(1, d3_geo_centroidZ / m))) * d3_degrees
];
}
};
var d3_geo_centroidDimension,
d3_geo_centroidW,
d3_geo_centroidX,
d3_geo_centroidY,
d3_geo_centroidZ;
var d3_geo_centroid = {
sphere: function() {
if (d3_geo_centroidDimension < 2) {
d3_geo_centroidDimension = 2;
d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
}
},
point: d3_geo_centroidPoint,
lineStart: d3_geo_centroidLineStart,
lineEnd: d3_geo_centroidLineEnd,
polygonStart: function() {
if (d3_geo_centroidDimension < 2) {
d3_geo_centroidDimension = 2;
d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
}
d3_geo_centroid.lineStart = d3_geo_centroidRingStart;
},
polygonEnd: function() {
d3_geo_centroid.lineStart = d3_geo_centroidLineStart;
}
};
// Arithmetic mean of Cartesian vectors.
function d3_geo_centroidPoint(λ, φ) {
if (d3_geo_centroidDimension) return;
++d3_geo_centroidW;
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians);
d3_geo_centroidX += (cosφ * Math.cos(λ) - d3_geo_centroidX) / d3_geo_centroidW;
d3_geo_centroidY += (cosφ * Math.sin(λ) - d3_geo_centroidY) / d3_geo_centroidW;
d3_geo_centroidZ += (Math.sin(φ) - d3_geo_centroidZ) / d3_geo_centroidW;
}
function d3_geo_centroidRingStart() {
var λ00, φ00; // first point
d3_geo_centroidDimension = 1;
d3_geo_centroidLineStart();
d3_geo_centroidDimension = 2;
var linePoint = d3_geo_centroid.point;
d3_geo_centroid.point = function(λ, φ) {
linePoint(λ00 = λ, φ00 = φ);
};
d3_geo_centroid.lineEnd = function() {
d3_geo_centroid.point(λ00, φ00);
d3_geo_centroidLineEnd();
d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd;
};
}
function d3_geo_centroidLineStart() {
var x0, y0, z0; // previous point
if (d3_geo_centroidDimension > 1) return;
if (d3_geo_centroidDimension < 1) {
d3_geo_centroidDimension = 1;
d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
}
d3_geo_centroid.point = function(λ, φ) {
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians);
x0 = cosφ * Math.cos(λ);
y0 = cosφ * Math.sin(λ);
z0 = Math.sin(φ);
d3_geo_centroid.point = nextPoint;
};
function nextPoint(λ, φ) {
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians),
x = cosφ * Math.cos(λ),
y = cosφ * Math.sin(λ),
z = Math.sin(φ),
w = Math.atan2(
Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w),
x0 * x + y0 * y + z0 * z);
d3_geo_centroidW += w;
d3_geo_centroidX += w * (x0 + (x0 = x));
d3_geo_centroidY += w * (y0 + (y0 = y));
d3_geo_centroidZ += w * (z0 + (z0 = z));
}
}
function d3_geo_centroidLineEnd() {
d3_geo_centroid.point = d3_geo_centroidPoint;
}