23. Movimiento utilizando ángulos

Un ángulo puede convertirse en una dirección y luego en velocidad. Al combinar esa velocidad con el tiempo obtenemos un movimiento continuo, controlable e independiente de la cantidad de cuadros por segundo.

23.1 Introducción

En muchos objetos móviles resulta más natural guardar una orientación que dos componentes de velocidad. Un automóvil posee un rumbo, una nave apunta con su nariz y un proyectil parte con un ángulo de lanzamiento.

La trigonometría transforma esa orientación en componentes x e y. Así podemos actualizar una posición sin escribir reglas diferentes para cada cuadrante.

23.2 Del ángulo a la dirección

Un ángulo θ medido desde el eje x positivo produce el vector unitario:

dirección = (cos θ, sen θ)

Como cos²θ+sen²θ=1, este vector mide exactamente una unidad. El ángulo decide hacia dónde apunta, pero todavía no establece qué tan rápido se mueve el objeto.

23.3 De dirección a velocidad

Multiplicamos la dirección por una rapidez escalar:

velocidad = rapidez · dirección
vx = rapidez·cos θ
vy = rapidez·sen θ

La magnitud de la velocidad será igual a la rapidez elegida. Esto garantiza que el objeto no se acelere accidentalmente al cambiar de orientación.

23.4 Velocidad, tiempo y desplazamiento

La velocidad expresa unidades por segundo. Para saber cuánto avanzar durante un cuadro la multiplicamos por el tiempo transcurrido Δt:

desplazamiento = velocidad·Δt
posiciónNueva = posición + desplazamiento

Si rapidez=120 píxeles/s y Δt=0.25 s, el objeto recorre 30 píxeles en la dirección indicada.

23.5 Interpretación visual

Objeto que convierte un ángulo en dirección velocidad y desplazamiento
El ángulo produce una dirección; la rapidez y el tiempo determinan el desplazamiento final.

Separar estas magnitudes facilita modificar una sin alterar las demás: podemos girar manteniendo rapidez, frenar sin cambiar dirección o pausar el tiempo sin perder orientación.

23.6 Coordenadas matemáticas y de pantalla

En el plano matemático y aumenta hacia arriba. En Canvas aumenta hacia abajo. Si queremos que un ángulo positivo sea antihorario visualmente:

vx = rapidez·cos θ
vyPantalla = −rapidez·sen θ

Si omitimos el signo negativo, los ángulos positivos girarán en sentido horario. Ambas convenciones funcionan si se utilizan consistentemente.

23.7 Control tipo automóvil

En un control de automóvil o nave, izquierda y derecha modifican el ángulo, mientras que avanzar aplica velocidad en la orientación actual.

ángulo += giro·Δt
posición += dirección(ángulo)·rapidez·Δt

Este modelo difiere del control directo por ejes: el objeto debe girar antes de cambiar su rumbo de desplazamiento.

23.8 Simulación interactiva: conduce con un ángulo

Ajusta ángulo, rapidez y giro. Pulsa avanzar o activa la animación automática. La trayectoria permite observar cómo cambian las componentes sin alterar la rapidez total.

Dirección(0.866, 0.500)
Velocidad(86.60, 50.00)
Posición(0.00, 0.00)
Estadodetenido

23.9 Implementación básica en JavaScript

function mover(posicion, anguloGrados, rapidez, dt) {
  const angulo = anguloGrados * Math.PI / 180;
  posicion.x += Math.cos(angulo) * rapidez * dt;
  posicion.y += Math.sin(angulo) * rapidez * dt;
}

const posicion = { x: 100, y: 100 };
mover(posicion, 30, 80, 0.5);

console.log(`Posición x: ${posicion.x.toFixed(2)}`);
console.log(`Posición y: ${posicion.y.toFixed(2)}`);

Al presionar Ejecutar, se muestra la posición alcanzada después de avanzar durante 0.5 segundos con una orientación de 30°. Esta versión usa la orientación de pantalla habitual, donde y positivo apunta hacia abajo. Para orientación matemática se cambia el signo de la actualización vertical.

23.10 Bucle de animación y delta time

function mover(posicion, anguloGrados, rapidez, dt) {
  const angulo = anguloGrados * Math.PI / 180;
  posicion.x += Math.cos(angulo) * rapidez * dt;
  posicion.y += Math.sin(angulo) * rapidez * dt;
}

const posicion = { x: 0, y: 0 };
const angulo = 45;
const rapidez = 100;
let cuadros = 0;
let anterior = 0;

function actualizar(ahora) {
  const dt = Math.min((ahora - anterior) / 1000, 0.05);
  anterior = ahora;
  mover(posicion, angulo, rapidez, dt);
  cuadros++;
  console.log(`Cuadro ${cuadros}: dt=${dt.toFixed(3)} s, posición=(${posicion.x.toFixed(2)}, ${posicion.y.toFixed(2)})`);

}

// Simulamos cinco cuadros, separados por 16 ms.
for (let ahora = 16; ahora <= 80; ahora += 16) {
  actualizar(ahora);
}

Al presionar Ejecutar, el bucle simula cinco cuadros de aproximadamente 16 ms y muestra inmediatamente su dt y la posición actualizada. En una animación real, las llamadas del for se reemplazan por requestAnimationFrame(actualizar). Limitar Δt evita saltos enormes si la pestaña se pausa.

23.11 Movimiento hacia un objetivo

Si conocemos posición y objetivo, obtenemos el ángulo mediante Math.atan2:

θ = atan2(objetivo.y−posición.y, objetivo.x−posición.x)

Luego usamos cos θ y sen θ para avanzar. Antes del último paso conviene comparar la distancia restante para no sobrepasar el objetivo y oscilar alrededor de él.

23.12 Aceleración y giro suave

Un movimiento más natural no cambia rapidez y orientación instantáneamente. Podemos mantener velocidad lineal y velocidad angular, y aplicar aceleraciones durante el tiempo:

rapidez += aceleración·Δt
ángulo += velocidadAngular·Δt

La fricción puede representarse reduciendo la rapidez gradualmente. Para girar hacia un objetivo se calcula la diferencia angular más corta, normalizada entre −π y π.

23.13 Aplicaciones y errores comunes

Este patrón sirve para vehículos, naves, proyectiles, enemigos, cámaras, pinceles direccionales y partículas.

Ejemplo animado: nave perseguidora

La nave calcula el ángulo hacia un objetivo móvil, gira por el camino angular más corto y avanza con una rapidez multiplicada por Δt. Al acercarse reduce la velocidad para no sobrepasarlo.

Persiguiendo objetivo…

Errores comunes

  • Pasar grados a seno y coseno sin convertirlos.
  • Olvidar multiplicar por Δt.
  • Usar rapidez distinta por eje y deformar la dirección.
  • Confundir orientación visual del sprite con su eje frontal real.
  • No tratar la inversión de y en pantalla.
  • Acumular un Δt enorme después de una pausa.
  • No limitar el último paso hacia un objetivo.

23.14 Qué debes recordar y conclusión

  • (cos θ, sen θ) convierte ángulo en dirección.
  • Dirección por rapidez produce velocidad.
  • Velocidad por tiempo produce desplazamiento.
  • La posición se actualiza sumando el desplazamiento.
  • Δt hace el movimiento independiente de cuadros.
  • Math.atan2 permite apuntar hacia un objetivo.
  • La convención del eje y debe aplicarse coherentemente.

El movimiento angular separa orientación, rapidez y tiempo. Esta estructura hace que el comportamiento sea fácil de controlar, animar y extender con aceleración o giro suave.

En el próximo tema utilizaremos estas mismas herramientas para rotar puntos alrededor del origen.