Fix polygon.centroid for open polygons.

The implementation assumed closed polygons, but it should work on either. This
is a partial fix for #443.
This commit is contained in:
Mike Bostock 2012-01-29 14:27:41 -08:00
Родитель f67e89597d
Коммит 85ad3c16b0
4 изменённых файлов: 55 добавлений и 29 удалений

Просмотреть файл

@ -192,16 +192,16 @@ d3.geom.polygon = function(coordinates) {
coordinates.centroid = function(k) { coordinates.centroid = function(k) {
var i = -1, var i = -1,
n = coordinates.length - 1, n = coordinates.length,
x = 0, x = 0,
y = 0, y = 0,
a, a,
b, b = coordinates[n - 1],
c; c;
if (!arguments.length) k = -1 / (6 * coordinates.area()); if (!arguments.length) k = -1 / (6 * coordinates.area());
while (++i < n) { while (++i < n) {
a = coordinates[i]; a = b;
b = coordinates[i + 1]; b = coordinates[i];
c = a[0] * b[1] - b[0] * a[1]; c = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * c; x += (a[0] + b[0]) * c;
y += (a[1] + b[1]) * c; y += (a[1] + b[1]) * c;

2
d3.geom.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -15,16 +15,16 @@ d3.geom.polygon = function(coordinates) {
coordinates.centroid = function(k) { coordinates.centroid = function(k) {
var i = -1, var i = -1,
n = coordinates.length - 1, n = coordinates.length,
x = 0, x = 0,
y = 0, y = 0,
a, a,
b, b = coordinates[n - 1],
c; c;
if (!arguments.length) k = -1 / (6 * coordinates.area()); if (!arguments.length) k = -1 / (6 * coordinates.area());
while (++i < n) { while (++i < n) {
a = coordinates[i]; a = b;
b = coordinates[i + 1]; b = coordinates[i];
c = a[0] * b[1] - b[0] * a[1]; c = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * c; x += (a[0] + b[0]) * c;
y += (a[1] + b[1]) * c; y += (a[1] + b[1]) * c;

Просмотреть файл

@ -8,49 +8,75 @@ var vows = require("vows"),
var suite = vows.describe("d3.geom.polygon"); var suite = vows.describe("d3.geom.polygon");
suite.addBatch({ suite.addBatch({
"counterclockwise polygon (last point equal to start point)": { "closed counterclockwise unit square": {
topic: function() { topic: function() {
return d3.geom.polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]); return d3.geom.polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]);
}, },
"area": function(polygon) { "has area 1": function(polygon) {
assert.equal(polygon.area(), 1); assert.equal(polygon.area(), 1);
}, },
"centroid": function(polygon) { "has centroid ⟨.5,.5⟩": function(polygon) {
assert.deepEqual(polygon.centroid(), [.5, .5]); assert.deepEqual(polygon.centroid(), [.5, .5]);
} }
}, },
"counterclockwise polygon (implicitly ending at start point)": { "closed clockwise unit square": {
topic: function() {
return d3.geom.polygon([[0, 0], [0, 1], [1, 1], [1, 0]]);
},
"area": function(polygon) {
assert.equal(polygon.area(), 1);
},
"centroid": function(polygon) {
assert.deepEqual(polygon.centroid(), [.5, .5]);
}
},
"clockwise polygon (last point equal to start point)": {
topic: function() { topic: function() {
return d3.geom.polygon([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]); return d3.geom.polygon([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]);
}, },
"area": function(polygon) { "has area 1": function(polygon) {
assert.equal(polygon.area(), -1); assert.equal(polygon.area(), -1);
}, },
"centroid": function(polygon) { "has centroid ⟨.5,.5⟩": function(polygon) {
assert.deepEqual(polygon.centroid(), [.5, .5]); assert.deepEqual(polygon.centroid(), [.5, .5]);
} }
}, },
"clockwise polygon (implicitly ending at start point)": { "closed clockwise triangle": {
topic: function() {
return d3.geom.polygon([[1, 1], [3, 2], [2, 3], [1, 1]]);
},
"has area 1.5": function(polygon) {
assert.equal(polygon.area(), -1.5);
},
"has centroid ⟨2,2⟩": function(polygon) {
var centroid = polygon.centroid();
assert.inDelta(centroid[0], 2, 1e-6);
assert.inDelta(centroid[1], 2, 1e-6);
}
},
"open counterclockwise unit square": {
topic: function() {
return d3.geom.polygon([[0, 0], [0, 1], [1, 1], [1, 0]]);
},
"has area 1": function(polygon) {
assert.equal(polygon.area(), 1);
},
"has centroid ⟨.5,.5⟩": function(polygon) {
assert.deepEqual(polygon.centroid(), [.5, .5]);
}
},
"open clockwise unit square": {
topic: function() { topic: function() {
return d3.geom.polygon([[0, 0], [1, 0], [1, 1], [0, 1]]); return d3.geom.polygon([[0, 0], [1, 0], [1, 1], [0, 1]]);
}, },
"area": function(polygon) { "has area 1": function(polygon) {
assert.equal(polygon.area(), -1); assert.equal(polygon.area(), -1);
}, },
"centroid": function(polygon) { "has centroid ⟨.5,.5⟩": function(polygon) {
assert.deepEqual(polygon.centroid(), [.5, .5]); assert.deepEqual(polygon.centroid(), [.5, .5]);
} }
},
"open clockwise triangle": {
topic: function() {
return d3.geom.polygon([[1, 1], [3, 2], [2, 3]]);
},
"has area 1.5": function(polygon) {
assert.equal(polygon.area(), -1.5);
},
"has centroid ⟨2,2⟩": function(polygon) {
var centroid = polygon.centroid();
assert.inDelta(centroid[0], 2, 1e-6);
assert.inDelta(centroid[1], 2, 1e-6);
}
} }
}); });