""" Conversiones de unidades SI ↔ Imperial para AR-ShipDesign. Internamente todo se almacena en SI (m, kg, s, N, Pa, W). Este módulo convierte para visualización en UI cuando el usuario selecciona unidades imperiales. Unidades SI base: Longitud → metro (m) Masa → kilogramo (kg) Fuerza → Newton (N) Presión → Pascal (Pa) Potencia → Watt (W) Velocidad → metro/segundo (m/s) Volumen → metro cúbico (m³) Área → metro cuadrado (m²) Temperatura → Celsius (°C) """ from __future__ import annotations from enum import Enum class UnitSystem(Enum): SI = "si" IMPERIAL = "imperial" # ────────────────────────────────────────────── # LONGITUD # ────────────────────────────────────────────── def m_to_ft(m: float) -> float: """Metros → Pies.""" return m * 3.280839895 def ft_to_m(ft: float) -> float: """Pies → Metros.""" return ft / 3.280839895 def m_to_in(m: float) -> float: """Metros → Pulgadas.""" return m * 39.3700787 def in_to_m(inches: float) -> float: """Pulgadas → Metros.""" return inches / 39.3700787 def mm_to_in(mm: float) -> float: """Milímetros → Pulgadas.""" return mm / 25.4 def in_to_mm(inches: float) -> float: """Pulgadas → Milímetros.""" return inches * 25.4 def nm_to_km(nm: float) -> float: """Millas náuticas → Kilómetros.""" return nm * 1.852 def km_to_nm(km: float) -> float: """Kilómetros → Millas náuticas.""" return km / 1.852 # ────────────────────────────────────────────── # VELOCIDAD # ────────────────────────────────────────────── def ms_to_kn(ms: float) -> float: """m/s → Nudos.""" return ms * 1.943844 def kn_to_ms(kn: float) -> float: """Nudos → m/s.""" return kn / 1.943844 def kn_to_kmh(kn: float) -> float: """Nudos → km/h.""" return kn * 1.852 def kmh_to_kn(kmh: float) -> float: """km/h → Nudos.""" return kmh / 1.852 # ────────────────────────────────────────────── # MASA Y FUERZA # ────────────────────────────────────────────── def kg_to_lb(kg: float) -> float: """Kilogramos → Libras.""" return kg * 2.204622622 def lb_to_kg(lb: float) -> float: """Libras → Kilogramos.""" return lb / 2.204622622 def kg_to_ton_metric(kg: float) -> float: """Kilogramos → Toneladas métricas.""" return kg / 1000.0 def ton_metric_to_kg(t: float) -> float: """Toneladas métricas → Kilogramos.""" return t * 1000.0 def kg_to_ton_long(kg: float) -> float: """Kilogramos → Toneladas largas (UK).""" return kg / 1016.0469088 def ton_long_to_kg(t: float) -> float: """Toneladas largas → Kilogramos.""" return t * 1016.0469088 def n_to_lbf(n: float) -> float: """Newton → Libra-fuerza.""" return n * 0.224808943 def lbf_to_n(lbf: float) -> float: """Libra-fuerza → Newton.""" return lbf / 0.224808943 # ────────────────────────────────────────────── # PRESIÓN # ────────────────────────────────────────────── def pa_to_psi(pa: float) -> float: """Pascal → PSI.""" return pa * 0.000145038 def psi_to_pa(psi: float) -> float: """PSI → Pascal.""" return psi / 0.000145038 def pa_to_bar(pa: float) -> float: """Pascal → Bar.""" return pa / 100000.0 def bar_to_pa(bar: float) -> float: """Bar → Pascal.""" return bar * 100000.0 def pa_to_kpa(pa: float) -> float: """Pascal → Kilopascal.""" return pa / 1000.0 def kpa_to_pa(kpa: float) -> float: """Kilopascal → Pascal.""" return kpa * 1000.0 # ────────────────────────────────────────────── # POTENCIA # ────────────────────────────────────────────── def w_to_hp(w: float) -> float: """Watt → Caballos de vapor (metric HP).""" return w / 735.49875 def hp_to_w(hp: float) -> float: """HP métrico → Watt.""" return hp * 735.49875 def w_to_bhp(w: float) -> float: """Watt → BHP (brake horsepower, SAE).""" return w / 745.69987 def bhp_to_w(bhp: float) -> float: """BHP → Watt.""" return bhp * 745.69987 def w_to_kw(w: float) -> float: """Watt → Kilowatt.""" return w / 1000.0 def kw_to_w(kw: float) -> float: """Kilowatt → Watt.""" return kw * 1000.0 # ────────────────────────────────────────────── # VOLUMEN # ────────────────────────────────────────────── def m3_to_ft3(m3: float) -> float: """m³ → ft³.""" return m3 * 35.3146667 def ft3_to_m3(ft3: float) -> float: """ft³ → m³.""" return ft3 / 35.3146667 def m3_to_liters(m3: float) -> float: """m³ → Litros.""" return m3 * 1000.0 def liters_to_m3(liters: float) -> float: """Litros → m³.""" return liters / 1000.0 def m3_to_usgal(m3: float) -> float: """m³ → Galones US.""" return m3 * 264.172052 def usgal_to_m3(gal: float) -> float: """Galones US → m³.""" return gal / 264.172052 # ────────────────────────────────────────────── # ÁREA # ────────────────────────────────────────────── def m2_to_ft2(m2: float) -> float: """m² → ft².""" return m2 * 10.7639104 def ft2_to_m2(ft2: float) -> float: """ft² → m².""" return ft2 / 10.7639104 # ────────────────────────────────────────────── # TEMPERATURA # ────────────────────────────────────────────── def c_to_f(celsius: float) -> float: """Celsius → Fahrenheit.""" return celsius * 9 / 5 + 32 def f_to_c(fahrenheit: float) -> float: """Fahrenheit → Celsius.""" return (fahrenheit - 32) * 5 / 9 # ────────────────────────────────────────────── # DENSIDAD # ────────────────────────────────────────────── def kg_m3_to_lb_ft3(rho: float) -> float: """kg/m³ → lb/ft³.""" return rho * 0.062427961 def lb_ft3_to_kg_m3(rho: float) -> float: """lb/ft³ → kg/m³.""" return rho / 0.062427961 # ────────────────────────────────────────────── # MOMENTO # ────────────────────────────────────────────── def nm_to_ft_lbf(nm: float) -> float: """Newton·metro → ft·lbf.""" return nm * 0.737562149 def ft_lbf_to_nm(ft_lbf: float) -> float: """ft·lbf → Newton·metro.""" return ft_lbf / 0.737562149 # ────────────────────────────────────────────── # HELPER GENÉRICO para la UI # ────────────────────────────────────────────── UNIT_LABELS: dict[str, dict[str, str]] = { "length": {"si": "m", "imperial": "ft"}, "length_small": {"si": "mm", "imperial": "in"}, "speed": {"si": "m/s", "imperial": "kn"}, "speed_nav": {"si": "kn", "imperial": "kn"}, "mass": {"si": "kg", "imperial": "lb"}, "displacement": {"si": "t", "imperial": "LT"}, "power": {"si": "kW", "imperial": "BHP"}, "pressure": {"si": "kPa", "imperial": "psi"}, "volume": {"si": "m³", "imperial": "ft³"}, "area": {"si": "m²", "imperial": "ft²"}, "temperature": {"si": "°C", "imperial": "°F"}, "density": {"si": "kg/m³", "imperial": "lb/ft³"}, } def unit_label(quantity: str, system: str = "si") -> str: """Retorna la etiqueta de unidad para una cantidad dada.""" return UNIT_LABELS.get(quantity, {}).get(system, "—")