import {sqrt} from "../math.js"; // TODO Enforce positive area for exterior, negative area for interior? var X0 = 0, Y0 = 0, Z0 = 0, X1 = 0, Y1 = 0, Z1 = 0, X2 = 0, Y2 = 0, Z2 = 0, x00, y00, x0, y0; var centroidStream = { point: centroidPoint, lineStart: centroidLineStart, lineEnd: centroidLineEnd, polygonStart: function() { centroidStream.lineStart = centroidRingStart; centroidStream.lineEnd = centroidRingEnd; }, polygonEnd: function() { centroidStream.point = centroidPoint; centroidStream.lineStart = centroidLineStart; centroidStream.lineEnd = centroidLineEnd; }, result: function() { var centroid = Z2 ? [X2 / Z2, Y2 / Z2] : Z1 ? [X1 / Z1, Y1 / Z1] : Z0 ? [X0 / Z0, Y0 / Z0] : [NaN, NaN]; X0 = Y0 = Z0 = X1 = Y1 = Z1 = X2 = Y2 = Z2 = 0; return centroid; } }; function centroidPoint(x, y) { X0 += x; Y0 += y; ++Z0; } function centroidLineStart() { centroidStream.point = centroidPointFirstLine; } function centroidPointFirstLine(x, y) { centroidStream.point = centroidPointLine; centroidPoint(x0 = x, y0 = y); } function centroidPointLine(x, y) { var dx = x - x0, dy = y - y0, z = sqrt(dx * dx + dy * dy); X1 += z * (x0 + x) / 2; Y1 += z * (y0 + y) / 2; Z1 += z; centroidPoint(x0 = x, y0 = y); } function centroidLineEnd() { centroidStream.point = centroidPoint; } function centroidRingStart() { centroidStream.point = centroidPointFirstRing; } function centroidRingEnd() { centroidPointRing(x00, y00); } function centroidPointFirstRing(x, y) { centroidStream.point = centroidPointRing; centroidPoint(x00 = x0 = x, y00 = y0 = y); } function centroidPointRing(x, y) { var dx = x - x0, dy = y - y0, z = sqrt(dx * dx + dy * dy); X1 += z * (x0 + x) / 2; Y1 += z * (y0 + y) / 2; Z1 += z; z = y0 * x - x0 * y; X2 += z * (x0 + x); Y2 += z * (y0 + y); Z2 += z * 3; centroidPoint(x0 = x, y0 = y); } export default centroidStream;