v0.1-sprint0: Esqueleto completo AR-ShipDesign
- Estructura completa de carpetas (236 módulos stub + implementados) - pyproject.toml, requirements, .gitignore, LICENSE (propietario) - core/project.py: serialización .arsd (ZIP con JSON) - core/units.py: conversiones SI <-> imperial completas - ui/main_window.py: layout DELFTship-style con todos los paneles - Árbol de proyecto (dock izquierda) - Tabs de módulos (centro) - Panel de propiedades (dock derecha) - Panel hidrostáticos en vivo (inferior, fijo) - ui/i18n: español e inglés - ui/themes: tema claro y oscuro - utils/logger.py, settings.py, validation.py - data/liquids.json: 15 líquidos navales - data/stability_criteria.json: IMO IS Code 2008, A.749(18), USCG - tests/test_startup.py: 12 tests, todos PASSED - Módulo scantling/ ISO 12215 (stubs Sprint 2.5) - Módulo fabrication/molds/ para moldes FRP (stubs Sprint 13B) - Módulo fabrication/ para CNC plasma/router/laser (stubs Sprint 13)
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
"""
|
||||
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, "—")
|
||||
Reference in New Issue
Block a user