/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Polygon area and perimeter computation utilities for 2D annotations. * Uses the shoelace formula for area calculation. */ interface Point2D { x: number; y: number; } /** * Compute the signed area of a simple polygon using the shoelace formula. * Returns absolute value (always positive). */ export function computePolygonArea(points: Point2D[]): number { if (points.length < 3) return 0; let area = 0; const n = points.length; for (let i = 0; i < n; i++) { const j = (i + 1) % n; area += points[i].x * points[j].y; area -= points[j].x * points[i].y; } return Math.abs(area) / 2; } /** * Compute the perimeter of a closed polygon. */ export function computePolygonPerimeter(points: Point2D[]): number { if (points.length < 2) return 0; let perimeter = 0; const n = points.length; for (let i = 0; i < n; i++) { const j = (i + 1) % n; const dx = points[j].x - points[i].x; const dy = points[j].y - points[i].y; perimeter += Math.sqrt(dx * dx + dy * dy); } return perimeter; } /** * Compute the centroid (geometric center) of a polygon. */ export function computePolygonCentroid(points: Point2D[]): Point2D { if (points.length === 0) return { x: 0, y: 0 }; let cx = 0; let cy = 0; for (const p of points) { cx += p.x; cy += p.y; } return { x: cx / points.length, y: cy / points.length }; } /** * Format an area value for display with appropriate units. */ export function formatArea(squareMeters: number): string { if (squareMeters < 0.01) { return `${(squareMeters * 10000).toFixed(1)} cm²`; } else if (squareMeters < 10000) { return `${squareMeters.toFixed(2)} m²`; } else { return `${(squareMeters / 10000).toFixed(2)} ha`; } }