26.1 Del modelo continuo al programa
En una ecuación como x(t), el tiempo puede tomar cualquier valor. Una computadora solo evalúa una cantidad finita de instantes: t0, t1, t2 y así sucesivamente.
El intervalo entre dos estados es el paso temporal, habitualmente llamado dt. Durante cada paso aproximamos cómo cambian posición, velocidad y otras variables.
Discretizar no significa que el mundo avance a saltos; significa que nuestro algoritmo toma muestras y construye una aproximación.
26.2 Qué representa delta time
dt es tiempo, no cantidad de fotogramas. Si una velocidad está en m/s, dt debe expresarse en segundos para que v·dt produzca metros.
Las API suelen informar milisegundos. Debemos dividir por 1000 antes de aplicar magnitudes expresadas por segundo.
Sin dt, sumar la misma distancia en cada cuadro hace que el movimiento dependa de la velocidad del dispositivo.
26.3 Paso variable
Con paso variable se usa el tiempo real transcurrido desde el cuadro anterior. Es sencillo y mantiene aproximadamente la velocidad cuando cambia la tasa de renderizado.
Sin embargo, un dt grande reduce precisión y puede atravesar paredes, producir resortes inestables o alterar el resultado entre ejecuciones. Conviene limitar pausas extraordinarias.
26.4 Paso fijo
Con paso fijo la física avanza siempre con el mismo intervalo, por ejemplo 1/60 s. El render puede ocurrir a otra frecuencia. Esto mejora reproducibilidad y vuelve más predecible el error numérico.
Si un cuadro tarda demasiado, pueden ejecutarse varios pasos físicos para alcanzar el tiempo real. Un acumulador conserva el tiempo pendiente.
El paso fijo no elimina el error: solo lo hace uniforme. Reducirlo mejora precisión a cambio de más cálculos.
26.5 El bucle de simulación
Un bucle típico mide tiempo, procesa entradas, ejecuta cero o más actualizaciones físicas y dibuja. La física modifica el estado; el renderizado únicamente lo representa.
- medir el tiempo transcurrido;
- agregarlo al acumulador;
- mientras alcance para un paso, actualizar la física;
- dibujar el estado más reciente;
- solicitar el próximo cuadro.
Separar estas responsabilidades permite probar la física sin lienzo ni temporizador.
26.6 requestAnimationFrame
En el navegador, requestAnimationFrame solicita una función antes del próximo repintado. Recibe una marca temporal de alta resolución. No garantiza 60 cuadros por segundo.
La pestaña puede reducir o pausar llamadas cuando queda oculta. Al regresar, debemos evitar incorporar toda la pausa como un único paso físico enorme.
La función de animación no debe asumir que el intervalo es constante; debe medirlo o alimentar un acumulador fijo.
26.7 Movimiento independiente de los cuadros
function actualizar(estado, dt) {
estado.posicion += estado.velocidad * dt;
estado.tiempo += dt;
}
const estado = { posicion: 0, velocidad: 6, tiempo: 0 };
actualizar(estado, 0.25);
console.log(estado.posicion + ' m');
console.log(estado.tiempo + ' s');En 0,25 s recorre 1,5 m. Cuatro pasos iguales producen los mismos 6 m que un segundo continuo en este modelo de velocidad constante.
26.8 Laboratorio: tamaño del paso
Compará la solución exacta de aceleración constante con Euler semiexplícito. Elegí dt y avanzá manualmente o reproducí la simulación.
Simulación preparada.
26.9 Acumulador de tiempo
const paso = 1 / 60;
let acumulador = 0;
function procesarTiempo(dtReal) {
acumulador += Math.min(dtReal, 0.25);
let pasos = 0;
while (acumulador >= paso) {
pasos++;
acumulador -= paso;
}
return pasos;
}
console.log(procesarTiempo(0.05));Para 0,05 s se ejecutan 3 pasos de 1/60 s. El pequeño resto queda acumulado para el siguiente cuadro.
26.10 Estabilidad y espiral de la muerte
Si calcular un paso tarda más que el tiempo que ese paso representa, se acumula cada vez más retraso: el programa intenta ponerse al día ejecutando más pasos y empeora el problema.
Para evitarlo se limita el tiempo acumulado, se establece un máximo de pasos por cuadro y se optimiza la simulación. Descartar tiempo puede ralentizar el mundo, pero mantiene usable la aplicación.
La interpolación visual entre el estado anterior y el actual suaviza el render sin modificar la frecuencia física.
26.11 Ejercicio integrador
Un objeto se mueve a 8 m/s. Un cuadro tarda 20 ms. Calculá dt en segundos y el desplazamiento de ese paso. ¿Qué distancia recorrerá en 50 cuadros iguales?
Ver solución y código
dt = 20/1000 = 0,02 s. Recorre 8·0,02 = 0,16 m por cuadro. En 50 cuadros transcurre 1 s y recorre 8 m.
const velocidad = 8;
const milisegundos = 20;
const dt = milisegundos / 1000;
const porPaso = velocidad * dt;
const total = porPaso * 50;
console.log(dt + ' s');
console.log(porPaso + ' m');
console.log(total + ' m');26.12 Ideas para recordar
- El programa aproxima el tiempo continuo mediante pasos.
- dt debe expresarse en unidades compatibles con las tasas.
- El paso variable sigue el reloj real, pero cambia su error.
- El paso fijo facilita reproducibilidad y estabilidad.
- Un acumulador desacopla física y renderizado.
- Los dt extremos deben limitarse.
- Pasos más pequeños suelen mejorar precisión y requieren más cálculo.
En el próximo tema estudiaremos métodos numéricos simples para integrar el movimiento.