"use strict";
/**
* @namespace geometryUtils
* @description Utilities for geometric calculations, including centroid calculation and polyline conversion.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateCentroid = calculateCentroid;
exports.convertRingsToPolyline = convertRingsToPolyline;
/**
* @memberof geometryUtils
*/
/**
* Calculates the centroid of a closed polyline.
*
* @memberof geometryUtils
* @function calculateCentroid
* @param {Polyline} polyline - An array of points representing the polyline.
* @returns {Point2d|null} The centroid as a Point2d, or `null` if the polyline is invalid.
* @throws {Error} Throws an error if the polyline has fewer than 3 vertices.
* @example
* const polyline = [
* { x: 0, y: 0 },
* { x: 4, y: 0 },
* { x: 4, y: 3 },
* { x: 0, y: 3 },
* { x: 0, y: 0 }
* ];
* const centroid = calculateCentroid(polyline);
* console.log(centroid); // { x: 2, y: 1.5 }
*/
function calculateCentroid(polyline) {
let centroidX = 0;
let centroidY = 0;
let signedArea = 0;
let x0, y0, x1, y1, a;
const numVerts = polyline.length;
if (numVerts < 3) {
return null;
}
// Calculate area and centroid
for (let i = 0; i < numVerts - 1; i++) {
x0 = polyline[i].x;
y0 = polyline[i].y;
x1 = polyline[i + 1].x;
y1 = polyline[i + 1].y;
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidX += (x0 + x1) * a;
centroidY += (y0 + y1) * a;
}
// Close the polygon by connecting the last point to the first
x0 = polyline[numVerts - 1].x;
y0 = polyline[numVerts - 1].y;
x1 = polyline[0].x;
y1 = polyline[0].y;
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidX += (x0 + x1) * a;
centroidY += (y0 + y1) * a;
signedArea *= 0.5;
centroidX /= 6.0 * signedArea;
centroidY /= 6.0 * signedArea;
return {
x: centroidX || 0,
y: centroidY || 0
};
}
/**
* Converts a rings array to a Polyline format.
*
* @memberof geometryUtils
* @function convertRingsToPolyline
* @param {number[][][]} rings - An array representing rings of points in the form [[[x, y], [x, y], ...]].
* @returns {Polyline} A Polyline array with points in `{x, y}` format.
* @throws {Error} Throws an error if the input is invalid.
* @example
* const rings = [
* [
* [0, 0],
* [4, 0],
* [4, 3],
* [0, 3],
* [0, 0]
* ]
* ];
* const polyline = convertRingsToPolyline(rings);
* console.log(polyline);
* // Output: [{ x: 0, y: 0 }, { x: 4, y: 0 }, { x: 4, y: 3 }, { x: 0, y: 3 }, { x: 0, y: 0 }]
*/
function convertRingsToPolyline(rings) {
if (!rings || !Array.isArray(rings) || rings.length === 0) {
throw new Error("Invalid rings data: Expected a non-empty array.");
}
return rings[0].map(([x, y]) => {
if (typeof x !== 'number' || typeof y !== 'number') {
throw new Error("Invalid point format: Expected an array of [x, y] numbers.");
}
return { x, y };
});
}
// Example usage
/**
const geometry = {
rings: [
[
[2653639.5557742715, 760547.43011811376],
[2653692.8054461926, 760546.05479001999],
[2653741.0846456736, 760544.71030183136],
[2653762.3566273004, 760242.97769029438]
]
]
};
// Convert rings to polyline format and calculate the centroid
const polyline = convertRingsToPolyline(geometry.rings);
const centroid = calculateCentroid(polyline);
console.log("Centroid:", centroid);
*/