2010-11-08 00:49:59 +03:00
|
|
|
d3.geom = {};
|
|
|
|
// Note: requires coordinates to be clockwise and convex!
|
|
|
|
d3.geom.polygon = function(coordinates) {
|
|
|
|
var n = coordinates.length;
|
|
|
|
|
|
|
|
coordinates.area = function() {
|
|
|
|
var i = 0,
|
|
|
|
a = coordinates[n - 1][0] * coordinates[0][1],
|
|
|
|
b = coordinates[n - 1][1] * coordinates[0][0];
|
|
|
|
while (++i < n) {
|
|
|
|
a += coordinates[i - 1][0] * coordinates[i][1];
|
|
|
|
b += coordinates[i - 1][1] * coordinates[i][0];
|
|
|
|
}
|
2010-11-08 00:53:47 +03:00
|
|
|
return (b - a) * .5;
|
2010-11-08 00:49:59 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
// The Sutherland-Hodgman clipping algorithm.
|
|
|
|
coordinates.intersection = function(subject) {
|
|
|
|
var output = subject,
|
|
|
|
input,
|
|
|
|
i = -1,
|
|
|
|
j,
|
|
|
|
m,
|
|
|
|
a = coordinates[n - 1],
|
|
|
|
b,
|
|
|
|
c,
|
|
|
|
d;
|
|
|
|
while (++i < n) {
|
|
|
|
input = output.slice();
|
|
|
|
output = [];
|
|
|
|
b = coordinates[i];
|
|
|
|
c = input[(m = input.length) - 1];
|
|
|
|
j = -1;
|
|
|
|
while (++j < m) {
|
|
|
|
d = input[j];
|
|
|
|
if (d3_geom_polygonInside(d, a, b)) {
|
|
|
|
if (!d3_geom_polygonInside(c, a, b)) {
|
|
|
|
output.push(d3_geom_polygonIntersect(c, d, a, b));
|
|
|
|
}
|
|
|
|
output.push(d);
|
|
|
|
} else if (d3_geom_polygonInside(c, a, b)) {
|
|
|
|
output.push(d3_geom_polygonIntersect(c, d, a, b));
|
|
|
|
}
|
|
|
|
c = d;
|
|
|
|
}
|
|
|
|
a = b;
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
};
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
};
|
|
|
|
|
|
|
|
function d3_geom_polygonInside(p, a, b) {
|
|
|
|
return (b[0] - a[0]) * (p[1] - a[1]) >= (b[1] - a[1]) * (p[0] - a[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intersect two infinite lines cd and ab.
|
|
|
|
function d3_geom_polygonIntersect(c, d, a, b) {
|
|
|
|
var x1 = c[0], x2 = d[0], x3 = a[0], x4 = b[0],
|
|
|
|
y1 = c[1], y2 = d[1], y3 = a[1], y4 = b[1],
|
|
|
|
x13 = x1 - x3,
|
|
|
|
x21 = x2 - x1,
|
|
|
|
x43 = x4 - x3,
|
|
|
|
y13 = y1 - y3,
|
|
|
|
y21 = y2 - y1,
|
|
|
|
y43 = y4 - y3,
|
|
|
|
ua = (x43 * y13 - y43 * x13) / (y43 * x21 - x43 * y21);
|
|
|
|
return [x1 + ua * x21, y1 + ua * y21];
|
|
|
|
}
|