/** * Unit formatting and parsing utilities for CAD distance values. * All internal CAD coordinates are stored in world units. * scaleFactor converts world units to millimeters (1 world unit = scaleFactor mm). */ export type UnitType = 'mm' | 'cm' | 'm'; /** * Format a raw world-unit distance into a human-readable string with the given unit. * @param raw - distance in world units * @param unit - target display unit ('mm' | 'cm' | 'm') * @param scaleFactor - millimeters per world unit (default 1) * @returns formatted string like "500 mm", "5.0 cm", "0.05 m" */ export function formatDistance( raw: number, unit: UnitType, scaleFactor: number = 1, ): string { const mm = raw * scaleFactor; switch (unit) { case 'mm': return `${mm.toFixed(0)} mm`; case 'cm': return `${(mm / 10).toFixed(1)} cm`; case 'm': return `${(mm / 1000).toFixed(2)} m`; } } /** * Parse a user-entered distance string back into world units. * @param input - numeric string (e.g. "500", "5.5", "0.05") * @param unit - the unit the user is entering values in * @param scaleFactor - millimeters per world unit (default 1) * @returns world-unit distance, or 0 if input is invalid */ export function parseDistance( input: string, unit: UnitType, scaleFactor: number = 1, ): number { const value = parseFloat(input); if (isNaN(value)) return 0; switch (unit) { case 'mm': return value / scaleFactor; case 'cm': return (value * 10) / scaleFactor; case 'm': return (value * 1000) / scaleFactor; } } /** * Format a raw world-unit coordinate value for compact display (e.g. status bar). * Uses fewer decimal places than formatDistance. */ export function formatCoordinate( raw: number, unit: UnitType, scaleFactor: number = 1, ): string { const mm = raw * scaleFactor; switch (unit) { case 'mm': return `${mm.toFixed(0)}`; case 'cm': return `${(mm / 10).toFixed(1)}`; case 'm': return `${(mm / 1000).toFixed(3)}`; } } /** * Format a raw world-unit value for an input field (without unit suffix). * This is what the user sees in text inputs so they can edit the numeric value. */ export function formatInputValue( raw: number, unit: UnitType, scaleFactor: number = 1, ): string { const mm = raw * scaleFactor; switch (unit) { case 'mm': return `${mm.toFixed(0)}`; case 'cm': return `${(mm / 10).toFixed(1)}`; case 'm': return `${(mm / 1000).toFixed(3)}`; } } /** * Format a raw world-unit squared area value (Task H5). * @param rawSquared squared world-units (e.g. polygonArea result) * @param unit target display unit * @param scaleFactor world-units → mm conversion (like formatDistance) * @returns formatted string like "5000 mm²", "50.0 cm²", "5.00 m²" */ export function formatArea( rawSquared: number, unit: UnitType, scaleFactor: number = 1, ): string { const mmSquared = rawSquared * scaleFactor * scaleFactor; switch (unit) { case 'mm': return `${mmSquared.toFixed(0)} mm²`; case 'cm': return `${(mmSquared / 100).toFixed(1)} cm²`; case 'm': return `${(mmSquared / 1000000).toFixed(2)} m²`; default: return `${mmSquared.toFixed(0)} mm²`; } }