37.1 Objetivo del proyecto
El laboratorio debe simular varios cuerpos puntuales, permitir cambiar condiciones iniciales y representar sus trayectorias. No buscamos solamente una animación atractiva: el programa debe informar sus unidades, método y errores.
Una versión mínima completa incluye escenarios ligados, elípticos, de escape y un sistema binario perturbado.
37.2 Requisitos funcionales
- cargar configuraciones reproducibles;
- calcular aceleraciones gravitatorias por pares;
- integrar todos los cuerpos con un paso fijo explícito;
- pausar, continuar y reiniciar;
- modificar paso, velocidad inicial y rapidez visual;
- mostrar trayectorias, vectores e invariantes.
37.3 Requisitos de calidad
El mismo estado inicial y los mismos parámetros deben producir el mismo resultado. La simulación debe mantenerse independiente de la frecuencia de refresco de la pantalla.
Los errores no finitos deben detener o reiniciar el cálculo de forma controlada, nunca propagarse silenciosamente.
37.4 Arquitectura en capas
Cada capa recibe datos y devuelve resultados sin depender de los detalles internos de la siguiente. Así podemos probar la física sin Canvas y cambiar la interfaz sin reescribir el integrador.
37.5 Modelo de un cuerpo
En dos dimensiones cada cuerpo almacena masa, posición y velocidad. Nombre, color, radio visual y trayectoria ayudan a la interfaz:
Las unidades normalizadas mantienen G = 1 y valores cercanos a la unidad; la interfaz debe indicarlo claramente.
37.6 Estado inicial y escenarios
Un escenario es una función que construye datos nuevos. No conviene reutilizar objetos mutados por una ejecución anterior.
Al reiniciar se vuelven a crear cuerpos, tiempo, trazas, energía de referencia y momento angular de referencia.
37.7 Gravedad por pares
Para cada par i, j calculamos una sola separación:
Las contribuciones opuestas respetan la tercera ley de Newton y ayudan a conservar el momento lineal total.
37.8 Integración leapfrog
El proyecto usa la secuencia impulso–deriva–impulso:
- actualizar todas las velocidades medio paso;
- actualizar todas las posiciones un paso completo;
- recalcular aceleraciones;
- completar el segundo medio paso de velocidad.
Es de segundo orden, reversible y simpléctica para este Hamiltoniano.
37.9 Paso físico y velocidad visual
Δt controla la precisión física. Los pasos por cuadro controlan cuánto tiempo simulado avanza la animación. Son parámetros distintos.
Aumentar pasos por cuadro conserva la trayectoria calculada; aumentar Δt modifica el error de cada actualización.
37.10 Marco baricéntrico
Antes de iniciar, restamos posición y velocidad del centro de masa:
El dibujo también puede seguir al baricentro para que la dinámica interna permanezca centrada.
37.11 Diagnósticos globales
Para un sistema aislado controlamos:
Lz = Σmi(xivyi − yivxi)
La interfaz muestra errores relativos respecto de sus valores al reiniciar.
37.12 Diagnósticos orbitales
En escenarios con un cuerpo dominante podemos calcular la energía específica relativa, excentricidad y semieje de la sonda.
En un sistema binario, una cónica respecto de un foco único es solo una aproximación instantánea. El laboratorio lo indica para no presentar elementos osculatrices como constantes.
37.13 Clasificar la trayectoria
Respecto de una masa dominante:
- ε < 0 y e < 1: ligada;
- ε ≈ 0 y e ≈ 1: escape parabólico límite;
- ε > 0 y e > 1: escape hiperbólico.
Debe usarse una tolerancia, porque una comparación exacta con cero es frágil numéricamente.
37.14 Transformación a píxeles
La cámara convierte coordenadas físicas sin alterar el estado:
ypx = ycentro − escala(y − ycámara)
El signo negativo restaura un eje y físico ascendente sobre Canvas.
37.15 Trazas y vectores
Guardar todas las posiciones indefinidamente consume memoria. Una cola limitada conserva solamente los últimos puntos de cada trayectoria.
Los vectores de velocidad y aceleración necesitan escalas visuales independientes; su longitud en píxeles no debe reutilizarse como magnitud física.
37.16 Ciclo de animación
requestAnimationFrame sincroniza el dibujo con el navegador. En cada cuadro se ejecutan cero o más pasos físicos, se actualizan diagnósticos y se renderiza una vez.
Al pausar, el dibujo y los controles continúan disponibles, pero el estado físico no avanza.
37.17 Motor gravitatorio con JavaScript
function aceleraciones(cuerpos, G = 1, epsilon = 0) {
const resultado = cuerpos.map(() => ({ x: 0, y: 0 }));
for (let i = 0; i < cuerpos.length; i++) {
for (let j = i + 1; j < cuerpos.length; j++) {
const dx = cuerpos[j].x - cuerpos[i].x;
const dy = cuerpos[j].y - cuerpos[i].y;
const inversoR3 = (dx * dx + dy * dy + epsilon ** 2) ** -1.5;
resultado[i].x += G * cuerpos[j].masa * dx * inversoR3;
resultado[i].y += G * cuerpos[j].masa * dy * inversoR3;
resultado[j].x -= G * cuerpos[i].masa * dx * inversoR3;
resultado[j].y -= G * cuerpos[i].masa * dy * inversoR3;
}
}
return resultado;
}
const cuerpos = [
{ masa: 1, x: 0, y: 0 },
{ masa: 0.001, x: 1, y: 0 }
];
console.log(aceleraciones(cuerpos));
37.18 Un paso leapfrog con JavaScript
function pasoLeapfrog(cuerpos, dt, calcularAceleraciones) {
let a = calcularAceleraciones(cuerpos);
cuerpos.forEach((cuerpo, i) => {
cuerpo.vx += 0.5 * a[i].x * dt;
cuerpo.vy += 0.5 * a[i].y * dt;
});
cuerpos.forEach(cuerpo => {
cuerpo.x += cuerpo.vx * dt;
cuerpo.y += cuerpo.vy * dt;
});
a = calcularAceleraciones(cuerpos);
cuerpos.forEach((cuerpo, i) => {
cuerpo.vx += 0.5 * a[i].x * dt;
cuerpo.vy += 0.5 * a[i].y * dt;
});
}
console.log("La función actualiza todos los cuerpos sobre la misma instantánea.");
37.19 Laboratorio orbital integrado
Elegí un escenario, modificá la rapidez inicial de la sonda y compará el efecto de Δt. Las flechas sobre la sonda muestran velocidad y aceleración; el panel derecho registra los errores globales.
Órbita circular alrededor de un cuerpo dominante en unidades G = 1.
37.20 Experimentos propuestos
- en el escenario circular, reducí y aumentá la rapidez para crear elipses;
- superá aproximadamente √2 veces la rapidez circular para escapar;
- aumentá Δt y observá cuándo los invariantes dejan de ser confiables;
- en el sistema binario, compará la trayectoria irregular de la sonda;
- ocultá las trazas para distinguir estado instantáneo de historia.
37.21 Pruebas de aceptación
- un sistema aislado conserva baricentro, energía y momento dentro de tolerancias;
- una órbita circular mantiene radio al reducir Δt;
- duplicar todas las masas fuente duplica las aceleraciones instantáneas;
- reiniciar reproduce exactamente el mismo estado;
- pausar no cambia el tiempo simulado;
- la interfaz continúa siendo usable con teclado y en pantallas angostas.
37.22 Ampliaciones posibles
- editor de cuerpos con masa, posición y velocidad;
- colisiones, fusión y radios físicos;
- integradores RK4 y adaptativos para comparar;
- vista tridimensional y elementos orbitales;
- maniobras impulsivas programables;
- exportación e importación de escenarios JSON;
- efemérides reales y modelos de perturbaciones.
37.23 Desafío final
Agregá al proyecto un escenario de dos masas iguales en órbita circular mutua. En unidades G = 1 y separación total d = 1:
- ubicá las masas en x = −0,5 y x = +0,5;
- calculá la velocidad tangencial de cada una;
- verificá que el período sea 2π;
- medí la conservación durante diez períodos.
Ver solución
Para masas m₁ = m₂ = 0,5, la velocidad angular es ω = √[G(m₁ + m₂)/d³] = 1. Cada cuerpo está a 0,5 del baricentro, por lo que su rapidez es 0,5.
Podemos usar velocidades (0; −0,5) para el cuerpo izquierdo y (0; +0,5) para el derecho. El período es 2π/ω = 2π.
const G = 1, masaTotal = 1, separacion = 1;
const omega = Math.sqrt(G * masaTotal / separacion ** 3);
const radio = separacion / 2;
const rapidez = omega * radio;
const binario = [
{ masa: 0.5, x: -radio, y: 0, vx: 0, vy: -rapidez },
{ masa: 0.5, x: radio, y: 0, vx: 0, vy: rapidez }
];
console.log("ω:", omega.toFixed(4));
console.log("rapidez:", rapidez.toFixed(4));
console.log("período:", (2 * Math.PI / omega).toFixed(4));
console.log(binario);
37.24 Cierre del recorrido
- La gravedad conecta geometría, energía y evolución temporal.
- Una órbita es el resultado de posición, velocidad y campo gravitatorio.
- Los modelos analíticos orientan el diseño y los numéricos amplían lo que podemos estudiar.
- Un simulador serio declara unidades, marcos, aproximaciones y tolerancias.
- Los invariantes y la convergencia son parte del programa, no una tarea posterior.
- Separar datos, física e interfaz permite extender el proyecto con seguridad.
Con este laboratorio queda completo el recorrido desde la ley de gravitación hasta una simulación interactiva de sistemas orbitales.