33.1 Objetivo del proyecto
Construiremos un laboratorio que permita configurar dos cuerpos, resolver un choque frontal u oblicuo y presentar evidencias de que el resultado satisface las hipótesis elegidas.
33.2 Requisitos funcionales
33.3 Arquitectura en cuatro capas
Cada capa recibe datos y devuelve resultados. El lienzo nunca decide las velocidades; solo representa la salida del motor.
33.4 Modelo de cuerpo y vector
const cuerpoA = {
id: "A",
masa: 2,
velocidad: { x: 5, y: 0 }
};
const cuerpoB = {
id: "B",
masa: 3,
velocidad: { x: 0, y: 0 }
};
function momentoLineal(cuerpo) {
return {
x: cuerpo.masa * cuerpo.velocidad.x,
y: cuerpo.masa * cuerpo.velocidad.y
};
}
console.log("Cuerpo A:", cuerpoA);
console.log("Momento de A:", momentoLineal(cuerpoA), "kg·m/s");
console.log("Cuerpo B:", cuerpoB);
console.log("Momento de B:", momentoLineal(cuerpoB), "kg·m/s");El laboratorio trabaja en unidades SI y usa vectores cartesianos internamente, aunque la interfaz reciba rapidez y ángulo.
33.5 Dos modos con un solo motor
En modo 1D fijamos todas las direcciones sobre x y n̂ = (1, 0). En modo 2D permitimos direcciones arbitrarias y proyectamos sobre la normal.
Reutilizar el mismo motor reduce duplicación y permite aplicar las mismas auditorías.
33.6 Validación de entradas
- las masas deben ser finitas y positivas;
- las componentes de velocidad deben ser finitas;
- la normal debe poder normalizarse;
- para un choque pasivo, 0 ≤ e ≤ 1;
- las unidades y la orientación de n̂ deben estar documentadas.
33.7 Detectar si corresponde resolver
Con n̂ de A hacia B, existe aproximación cuando gn,i < −εv. Si no, el resultado debe indicar sin-impacto y conservar las velocidades.
33.8 Motor impulsivo
Estas ecuaciones cubren el choque frontal y el contacto oblicuo entre superficies lisas.
33.9 Informe de salida
// Informe autocontenido del ensayo oblicuo de la sección 33.14.
const resultado = {
estado: "resuelto",
entradas: {
cuerpoA: { id: "A", masa: 2, velocidad: { x: 5, y: 0 } },
cuerpoB: { id: "B", masa: 3, velocidad: { x: 0, y: 0 } },
normal: { x: 0.866025, y: 0.5 },
restitucion: 0.8
},
impulso: {
escalar: 9.353074,
sobreA: { x: -8.1, y: -4.676537 },
sobreB: { x: 8.1, y: 4.676537 }
},
velocidadesFinales: {
A: { x: 0.95, y: -2.338269 },
B: { x: 2.7, y: 1.558846 }
},
energia: { inicial: 25, final: 20.95, cambio: -4.05 },
auditoria: {
momento: { residuo: 0, cumple: true },
restitucion: { residuo: 0, cumple: true },
tangencial: { residuo: 0, cumple: true },
energia: { cambio: -4.05, cumple: true }
}
};
console.log(JSON.stringify(resultado, null, 2));33.10 Auditorías independientes
33.11 Escalas y tolerancias
El proyecto usa una tolerancia combinada para no depender de una única escala:
El informe conserva tanto el residuo como el umbral. Una etiqueta “cumple” sin esos valores sería difícil de auditar.
33.12 Escenarios predefinidos
| Escenario | Qué permite comprobar |
|---|---|
| Elástico con masas iguales | Intercambio de velocidades normales y conservación de K. |
| Perfectamente inelástico | Velocidad normal común y máxima reducción compatible. |
| Oblicuo | Conservación de componentes tangenciales. |
| Separándose | Rechazo correcto de un impulso innecesario. |
33.13 Ensayo unidimensional
Para mA = mB, vAi = +5 m/s, vBi = 0 y e = 1:
El momento y la energía cinética permanecen constantes. Este caso debe formar parte de las pruebas mínimas.
33.14 Ensayo bidimensional
Con mA = 2 kg, mB = 3 kg, v⃗Ai = (5, 0), B en reposo, θn = 30° y e = 0,8:
El resultado conserva P⃗ = (10, 0) kg·m/s y reduce K en 4,05 J.
33.15 Flujo de uso experimental
- Elegir el modo y un escenario o configurar los controles.
- Confirmar la orientación de la normal y la aproximación.
- Leer las velocidades e impulso calculados.
- Examinar cada residuo y su tolerancia.
- Comparar las barras de energía.
- Guardar el ensayo y modificar una sola variable.
- Explicar físicamente el cambio observado.
33.16 Separar cálculo y presentación
El motor trabaja con números y objetos. La presentación convierte esos valores en texto localizado, colores, barras y flechas.
33.17 Accesibilidad y comunicación
Los colores se acompañan con etiquetas, los controles tienen label, los resultados dinámicos usan regiones accesibles y el lienzo posee una descripción. El informe textual conserva la información aunque no se interprete el gráfico.
33.18 Actividad interactiva: laboratorio integrador
Elegí un modo o escenario, modificá los parámetros y guardá ensayos para compararlos.
Laboratorio final de colisiones
Modelo impulsivo de dos cuerpos con superficies lisas.
| # | Modo | e | v⃗Af | v⃗Bf | ΔK |
|---|---|---|---|---|---|
| Todavía no se guardaron ensayos. | |||||
Choque resuelto y verificado.
33.19 Núcleo reutilizable
function resolverChoque(a, b, normal, e, tolerancia = 1e-9) {
const longitud = Math.hypot(normal.x, normal.y);
if (a.masa <= 0 || b.masa <= 0 || longitud <= tolerancia) {
throw new Error("Entrada inválida");
}
const n = { x: normal.x / longitud, y: normal.y / longitud };
const gn = (b.velocidad.x - a.velocidad.x) * n.x
+ (b.velocidad.y - a.velocidad.y) * n.y;
if (gn >= -tolerancia) return { estado: "sin-impacto", impulso: 0 };
const j = -(1 + e) * gn / (1 / a.masa + 1 / b.masa);
return {
estado: "resuelto",
impulso: j,
vAf: { x: a.velocidad.x - j * n.x / a.masa,
y: a.velocidad.y - j * n.y / a.masa },
vBf: { x: b.velocidad.x + j * n.x / b.masa,
y: b.velocidad.y + j * n.y / b.masa }
};
}
const cuerpoA = { masa: 2, velocidad: { x: 5, y: 0 } };
const cuerpoB = { masa: 3, velocidad: { x: 0, y: 0 } };
const normal = { x: Math.cos(Math.PI / 6), y: Math.sin(Math.PI / 6) };
const choqueOblicuo = resolverChoque(cuerpoA, cuerpoB, normal, 0.8);
console.log("Choque oblicuo:");
console.log(JSON.stringify(choqueOblicuo, null, 2));
const separandoseA = { masa: 2, velocidad: { x: -2, y: 0 } };
const separandoseB = { masa: 3, velocidad: { x: 2, y: 0 } };
const sinImpacto = resolverChoque(separandoseA, separandoseB, { x: 1, y: 0 }, 0.8);
console.log("Caso separándose:");
console.log(JSON.stringify(sinImpacto, null, 2));33.20 Plan de pruebas
| Nivel | Pruebas |
|---|---|
| Vectores | Suma, escala, producto escalar, módulo y normalización. |
| Motor | Casos analíticos para e = 0, e = 1 y masas iguales. |
| Auditoría | Errores introducidos deliberadamente deben ser detectados. |
| Interfaz | Modo 1D desactiva ángulos; escenarios cargan valores coherentes. |
| Casos límite | Separación, velocidad relativa cero y razones de masa grandes. |
33.21 Desafíos de ampliación
- Agregar paredes con masa inversa cero.
- Permitir ingreso directo de componentes cartesianas.
- Animar la aproximación y separación sin mezclar dibujo y motor.
- Incorporar una secuencia de tres cuerpos.
- Exportar e importar ensayos como JSON.
- Agregar incertidumbres de medición y barras de error.
- Construir pruebas automatizadas para todos los escenarios.
33.22 Cierre del curso
- El impulso conecta fuerzas breves con cambios de momento.
- El momento total se conserva cuando el impulso externo es despreciable.
- Las colisiones requieren condiciones adicionales como restitución o conservación de energía cinética.
- En dos dimensiones, elegir ejes normal–tangencial simplifica el contacto.
- Una simulación debe actualizar estados en orden temporal.
- Las estructuras de datos y las funciones puras hacen visible el modelo.
- Los residuos y tolerancias convierten una respuesta en un resultado verificable.
El laboratorio reúne estas ideas en un programa que puede crecer sin perder de vista las leyes físicas que representa.