120 lines
3.2 KiB
TypeScript
120 lines
3.2 KiB
TypeScript
/**
|
|
* 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²`;
|
|
}
|
|
}
|