All files centroid.ts

100% Statements 17/17
100% Branches 2/2
100% Functions 1/1
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46  1x                                               1x 11x 11x 11x   11x 45x 45x 45x 45x   45x 45x 45x 45x   11x   11x 11x  
import { type Cartesian, type Polygon } from './@types/geometry.ts';
import { modulo } from './modulo.ts';
 
/**
 * Calculates the centroid (geometric center) of a polygon.
 *
 * The centroid is computed using the formula for the centroid of a non-self-intersecting closed polygon.
 * The vertices should be provided in order (either clockwise or counterclockwise).
 * @param vertices - An array of points representing the vertices of the polygon.
 * @returns The centroid as a Cartesian coordinate.
 * @example
 * ```typescript
 * centroid([
 *   { x: 0, y: 0 },
 *   { x: 0, y: 5 },
 *   { x: 10, y: 5 },
 *   { x: 10, y: 0 },
 * ]);
 * // { x: 5, y: 2.5 }
 * ```
 * @remarks
 * The function assumes the polygon is non-self-intersecting.
 * @group Geometry
 * @category Polygon
 */
export function centroid(vertices: Polygon): Cartesian {
  let a = 0;
  let x = 0;
  let y = 0;
 
  for (let i = 0; i < vertices.length; ++i) {
    const j = modulo(i + 1, vertices.length);
    const v0 = vertices[i];
    const v1 = vertices[j];
    const f = v0.x * v1.y - v1.x * v0.y;
 
    a += f;
    x += (v0.x + v1.x) * f;
    y += (v0.y + v1.y) * f;
  }
 
  const d = a * 3;
 
  return { x: x / d, y: y / d };
}