import “../core/subclass”; import “geom”;

d3.geom.polygon = function(coordinates) {

d3_subclass(coordinates, d3_geom_polygonPrototype);
return coordinates;

};

var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];

d3_geom_polygonPrototype.area = function() {

var i = -1,
    n = this.length,
    a,
    b = this[n - 1],
    area = 0;

while (++i < n) {
  a = b;
  b = this[i];
  area += a[1] * b[0] - a[0] * b[1];
}

return area * .5;

};

d3_geom_polygonPrototype.centroid = function(k) {

var i = -1,
    n = this.length,
    x = 0,
    y = 0,
    a,
    b = this[n - 1],
    c;

if (!arguments.length) k = -1 / (6 * this.area());

while (++i < n) {
  a = b;
  b = this[i];
  c = a[0] * b[1] - b[0] * a[1];
  x += (a[0] + b[0]) * c;
  y += (a[1] + b[1]) * c;
}

return [x * k, y * k];

};

// The Sutherland-Hodgman clipping algorithm. // Note: requires the clip polygon to be counterclockwise and convex. d3_geom_polygonPrototype.clip = function(subject) {

var input,
    closed = d3_geom_polygonClosed(subject),
    i = -1,
    n = this.length - d3_geom_polygonClosed(this),
    j,
    m,
    a = this[n - 1],
    b,
    c,
    d;

while (++i < n) {
  input = subject.slice();
  subject.length = 0;
  b = this[i];
  c = input[(m = input.length - closed) - 1];
  j = -1;
  while (++j < m) {
    d = input[j];
    if (d3_geom_polygonInside(d, a, b)) {
      if (!d3_geom_polygonInside(c, a, b)) {
        subject.push(d3_geom_polygonIntersect(c, d, a, b));
      }
      subject.push(d);
    } else if (d3_geom_polygonInside(c, a, b)) {
      subject.push(d3_geom_polygonIntersect(c, d, a, b));
    }
    c = d;
  }
  if (closed) subject.push(subject[0]);
  a = b;
}

return subject;

};

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], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3,
    y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3,
    ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
return [x1 + ua * x21, y1 + ua * y21];

}

// Returns true if the polygon is closed. function d3_geom_polygonClosed(coordinates) {

var a = coordinates[0],
    b = coordinates[coordinates.length - 1];
return !(a[0] - b[0] || a[1] - b[1]);

}