Skip to content

Commit 604c57d

Browse files
committed
Fixes for streaming area and centroid.
1 parent 08b4357 commit 604c57d

5 files changed

Lines changed: 83 additions & 50 deletions

File tree

d3.js

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6376,45 +6376,45 @@
63766376
polygonStart: function() {
63776377
d3_geo_pathAreaScale = .5;
63786378
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
6379-
d3_geo_pathArea.lineEnd = d3_geo_pathAreaRingEnd;
63806379
},
63816380
polygonEnd: function() {
63826381
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
63836382
}
63846383
};
63856384
function d3_geo_pathAreaRingStart() {
6386-
var x0, y0;
6387-
d3_geo_areaRing = 0;
6385+
var x00, y00, x0, y0, area = 0;
63886386
d3_geo_pathArea.point = function(x, y) {
63896387
d3_geo_pathArea.point = nextPoint;
6390-
x0 = x, y0 = y;
6388+
x00 = x0 = x, y00 = y0 = y;
63916389
};
63926390
function nextPoint(x, y) {
6393-
d3_geo_areaRing += y0 * x - x0 * y;
6391+
area += y0 * x - x0 * y;
63946392
x0 = x, y0 = y;
63956393
}
6396-
}
6397-
function d3_geo_pathAreaRingEnd() {
6398-
d3_geo_areaSum += Math.abs(d3_geo_areaRing) * d3_geo_pathAreaScale;
6399-
d3_geo_pathAreaScale = -.5;
6394+
d3_geo_pathArea.lineEnd = function() {
6395+
nextPoint(x00, y00);
6396+
d3_geo_areaSum += Math.abs(area) * d3_geo_pathAreaScale;
6397+
d3_geo_pathAreaScale = -.5;
6398+
};
64006399
}
64016400
var d3_geo_pathCentroid = {
6402-
point: function(x, y) {
6403-
d3_geo_centroidX += x;
6404-
d3_geo_centroidY += y;
6405-
++d3_geo_centroidZ;
6406-
},
6401+
point: d3_geo_pathCentroidPoint,
64076402
lineStart: d3_geo_pathCentroidLineStart,
6408-
lineEnd: function() {
6409-
d3_geo_pathCentroid.point = d3_noop;
6410-
},
6403+
lineEnd: d3_geo_pathCentroidLineEnd,
64116404
polygonStart: function() {
64126405
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;
64136406
},
64146407
polygonEnd: function() {
6408+
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
64156409
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;
6410+
d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;
64166411
}
64176412
};
6413+
function d3_geo_pathCentroidPoint(x, y) {
6414+
d3_geo_centroidX += x;
6415+
d3_geo_centroidY += y;
6416+
++d3_geo_centroidZ;
6417+
}
64186418
function d3_geo_pathCentroidLineStart() {
64196419
var x0, y0;
64206420
d3_geo_pathCentroid.point = function(x, y) {
@@ -6429,6 +6429,9 @@
64296429
x0 = x, y0 = y;
64306430
}
64316431
}
6432+
function d3_geo_pathCentroidLineEnd() {
6433+
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
6434+
}
64326435
function d3_geo_pathCentroidRingStart() {
64336436
var x00, y00, x0, y0;
64346437
d3_geo_pathCentroid.point = function(x, y) {
@@ -6442,6 +6445,9 @@
64426445
d3_geo_centroidZ += z * 3;
64436446
x0 = x, y0 = y;
64446447
}
6448+
d3_geo_pathCentroid.lineEnd = function() {
6449+
nextPoint(x00, y00);
6450+
};
64456451
}
64466452
d3.geo.area = function(object) {
64476453
d3_geo_areaSum = 0;
@@ -6462,25 +6468,29 @@
64626468
},
64636469
polygonEnd: function() {
64646470
d3_geo_areaSum += d3_geo_areaRing < 0 ? 4 * π + d3_geo_areaRing : d3_geo_areaRing;
6465-
d3_geo_area.lineStart = d3_geo_area.point = d3_noop;
6471+
d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;
64666472
}
64676473
};
64686474
function d3_geo_areaRingStart() {
6469-
var λ00, φ00, λ0, φ0, cosφ0, sinφ0;
6475+
var λ00, φ00, λ1, λ0, φ0, cosφ0, sinφ0;
64706476
d3_geo_area.point = function(λ, φ) {
64716477
d3_geo_area.point = nextPoint;
6472-
λ00 = λ0 = λ * d3_radians, φ00 = φ0 = φ * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
6478+
λ1 = λ0 = (λ00 = λ) * d3_radians, φ0 = (φ00 = φ) * d3_radians, cosφ0 = Math.cos(φ0),
6479+
sinφ0 = Math.sin(φ0);
64736480
};
64746481
function nextPoint(λ, φ) {
64756482
λ *= d3_radians, φ *= d3_radians;
64766483
if (Math.abs(Math.abs(φ0) - π / 2) < ε && Math.abs(Math.abs(φ) - π / 2) < ε) return;
64776484
var cosφ = Math.cos(φ), sinφ = Math.sin(φ);
6478-
if (Math.abs(φ0 - π / 2) < ε) d3_geo_areaRing += (λ - λ00) * 2; else {
6485+
if (Math.abs(φ0 - π / 2) < ε) d3_geo_areaRing += (λ - λ1) * 2; else {
64796486
var = λ - λ0, cosdλ = Math.cos(), d = Math.atan2(Math.sqrt((d = cosφ * Math.sin()) * d + (d = cosφ0 * sinφ - sinφ0 * cosφ * cosdλ) * d), sinφ0 * sinφ + cosφ0 * cosφ * cosdλ), s = (d + π + φ0 + φ) / 4;
64806487
d3_geo_areaRing += ( < 0 && > -π || > π ? -4 : 4) * Math.atan(Math.sqrt(Math.abs(Math.tan(s) * Math.tan(s - d / 2) * Math.tan(s - π / 4 - φ0 / 2) * Math.tan(s - π / 4 - φ / 2))));
64816488
}
6482-
λ00 = λ0, φ00 = φ0, λ0 = λ, φ0 = φ, cosφ0 = cosφ, sinφ0 = sinφ;
6489+
λ1 = λ0, φ1 = φ0, λ0 = λ, φ0 = φ, cosφ0 = cosφ, sinφ0 = sinφ;
64836490
}
6491+
d3_geo_area.lineEnd = function() {
6492+
nextPoint(λ00, φ00);
6493+
};
64846494
}
64856495
d3.geo.projection = d3_geo_projection;
64866496
d3.geo.projectionMutator = d3_geo_projectionMutator;

d3.min.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/geo/area.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ var d3_geo_area = {
2020
},
2121
polygonEnd: function() {
2222
d3_geo_areaSum += d3_geo_areaRing < 0 ? 4 * π + d3_geo_areaRing : d3_geo_areaRing;
23-
d3_geo_area.lineStart = d3_geo_area.point = d3_noop;
23+
d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;
2424
}
2525
};
2626

2727
function d3_geo_areaRingStart() {
28-
var λ00, φ00, λ0, φ0, cosφ0, sinφ0; // two previous points
28+
var λ00, φ00, λ1, λ0, φ0, cosφ0, sinφ0; // start point and two previous points
2929

3030
// For the first point, …
3131
d3_geo_area.point = function(λ, φ) {
3232
d3_geo_area.point = nextPoint;
33-
λ00 = λ0 = λ * d3_radians, φ00 = φ0 = φ * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
33+
λ1 = λ0 = (λ00 = λ) * d3_radians, φ0 = (φ00 = φ) * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
3434
};
3535

3636
// For subsequent points, …
@@ -41,8 +41,8 @@ function d3_geo_areaRingStart() {
4141
if (Math.abs(Math.abs(φ0) - π / 2) < ε && Math.abs(Math.abs(φ) - π / 2) < ε) return;
4242
var cosφ = Math.cos(φ), sinφ = Math.sin(φ);
4343

44-
// If the previous point is at the south pole, something special
45-
if (Math.abs(φ0 - π / 2) < ε) d3_geo_areaRing += (λ - λ00) * 2;
44+
// If the previous point is at the south pole, something involving lunes
45+
if (Math.abs(φ0 - π / 2) < ε) d3_geo_areaRing += (λ - λ1) * 2;
4646

4747
// TODO Explain this wonderous mathematics.
4848
else {
@@ -54,6 +54,11 @@ function d3_geo_areaRingStart() {
5454
}
5555

5656
// Advance the previous points.
57-
λ00 = λ0, φ00 = φ0, λ0 = λ, φ0 = φ, cosφ0 = cosφ, sinφ0 = sinφ;
57+
λ1 = λ0, φ1 = φ0, λ0 = λ, φ0 = φ, cosφ0 = cosφ, sinφ0 = sinφ;
5858
}
59+
60+
// For the last point, return to the start.
61+
d3_geo_area.lineEnd = function() {
62+
nextPoint(λ00, φ00);
63+
};
5964
}

src/geo/path-area.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,31 @@ var d3_geo_pathAreaScale, d3_geo_pathArea = {
99
polygonStart: function() {
1010
d3_geo_pathAreaScale = .5;
1111
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
12-
d3_geo_pathArea.lineEnd = d3_geo_pathAreaRingEnd;
1312
},
1413
polygonEnd: function() {
1514
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
1615
}
1716
};
1817

1918
function d3_geo_pathAreaRingStart() {
20-
var x0, y0;
21-
22-
d3_geo_areaRing = 0;
19+
var x00, y00, x0, y0, area = 0;
2320

2421
// For the first point, …
2522
d3_geo_pathArea.point = function(x, y) {
2623
d3_geo_pathArea.point = nextPoint;
27-
x0 = x, y0 = y;
24+
x00 = x0 = x, y00 = y0 = y;
2825
};
2926

3027
// For subsequent points, …
3128
function nextPoint(x, y) {
32-
d3_geo_areaRing += y0 * x - x0 * y;
29+
area += y0 * x - x0 * y;
3330
x0 = x, y0 = y;
3431
}
35-
}
3632

37-
function d3_geo_pathAreaRingEnd() {
38-
d3_geo_areaSum += Math.abs(d3_geo_areaRing) * d3_geo_pathAreaScale;
39-
d3_geo_pathAreaScale = -.5;
33+
// For the last point, return to the start.
34+
d3_geo_pathArea.lineEnd = function() {
35+
nextPoint(x00, y00);
36+
d3_geo_areaSum += Math.abs(area) * d3_geo_pathAreaScale;
37+
d3_geo_pathAreaScale = -.5;
38+
};
4039
}

src/geo/path-centroid.js

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,29 @@
22
// TODO Enforce positive area for exterior, negative area for interior?
33

44
var d3_geo_pathCentroid = {
5-
point: function(x, y) {
6-
d3_geo_centroidX += x;
7-
d3_geo_centroidY += y;
8-
++d3_geo_centroidZ;
9-
},
5+
point: d3_geo_pathCentroidPoint,
106

117
// For lines, weight by length.
128
lineStart: d3_geo_pathCentroidLineStart,
13-
lineEnd: function() { d3_geo_pathCentroid.point = d3_noop; },
9+
lineEnd: d3_geo_pathCentroidLineEnd,
1410

1511
// For polygons, weight by area.
16-
polygonStart: function() { d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; },
17-
polygonEnd: function() { d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; }
12+
polygonStart: function() {
13+
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;
14+
},
15+
polygonEnd: function() {
16+
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
17+
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;
18+
d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;
19+
}
1820
};
1921

22+
function d3_geo_pathCentroidPoint(x, y) {
23+
d3_geo_centroidX += x;
24+
d3_geo_centroidY += y;
25+
++d3_geo_centroidZ;
26+
}
27+
2028
function d3_geo_pathCentroidLineStart() {
2129
var x0, y0;
2230

@@ -34,19 +42,30 @@ function d3_geo_pathCentroidLineStart() {
3442
}
3543
}
3644

45+
function d3_geo_pathCentroidLineEnd() {
46+
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
47+
}
48+
3749
function d3_geo_pathCentroidRingStart() {
3850
var x00, y00, x0, y0;
3951

52+
// For the first point, …
4053
d3_geo_pathCentroid.point = function(x, y) {
4154
d3_geo_pathCentroid.point = nextPoint;
4255
x00 = x0 = x, y00 = y0 = y;
4356
};
4457

58+
// For subsequent points, …
4559
function nextPoint(x, y) {
4660
var dx = x - x0, dy = y - y0, z = y0 * x - x0 * y;
4761
d3_geo_centroidX += z * (x0 + x);
4862
d3_geo_centroidY += z * (y0 + y);
4963
d3_geo_centroidZ += z * 3;
5064
x0 = x, y0 = y;
5165
}
66+
67+
// For the last point, return to the start.
68+
d3_geo_pathCentroid.lineEnd = function() {
69+
nextPoint(x00, y00);
70+
};
5271
}

0 commit comments

Comments
 (0)