45. Aplicaciones de la trigonometría en programación

La trigonometría convierte ángulos en posiciones, direcciones, rotaciones, trayectorias y ondas que un programa puede calcular.

45.1 Introducción

La trigonometría aparece con frecuencia en gráficos, videojuegos, simulaciones, interfaces animadas, visualización de datos y geometría computacional.

Su utilidad principal es transformar un ángulo en valores concretos que luego se usan para mover, ubicar, rotar o medir objetos.

45.2 Ángulos y radianes

En JavaScript, las funciones trigonométricas trabajan con radianes. Por eso conviene tener una función de conversión reutilizable.

function aRadianes(grados) {
  return grados * Math.PI / 180;
}

function aGrados(radianes) {
  return radianes * 180 / Math.PI;
}

console.log(aRadianes(180));
console.log(aGrados(Math.PI));

45.3 Crear un vector de dirección

Una de las aplicaciones más comunes es obtener una dirección a partir de un ángulo. El coseno indica la componente horizontal y el seno la componente vertical.

function aRadianes(grados) {
  return grados * Math.PI / 180;
}

function vectorDesdeAngulo(grados) {
  const radianes = aRadianes(grados);

  return {
    x: Math.cos(radianes),
    y: Math.sin(radianes)
  };
}

console.log(vectorDesdeAngulo(0));
console.log(vectorDesdeAngulo(90));
console.log(vectorDesdeAngulo(180));

45.4 Mover un objeto según un ángulo

Si se multiplica el vector de dirección por una velocidad, se obtiene el desplazamiento del objeto.

function mover(posicion, grados, velocidad) {
  const radianes = grados * Math.PI / 180;

  return {
    x: posicion.x + Math.cos(radianes) * velocidad,
    y: posicion.y + Math.sin(radianes) * velocidad
  };
}

const personaje = { x: 50, y: 50 };

console.log(mover(personaje, 0, 10));
console.log(mover(personaje, 45, 10));
console.log(mover(personaje, 90, 10));

45.5 Movimiento en coordenadas de pantalla

En muchos sistemas gráficos el eje Y crece hacia abajo. Si se quiere que 90° apunte hacia arriba, se resta la componente vertical.

function moverEnPantalla(posicion, grados, velocidad) {
  const radianes = grados * Math.PI / 180;

  return {
    x: posicion.x + Math.cos(radianes) * velocidad,
    y: posicion.y - Math.sin(radianes) * velocidad
  };
}

const nave = { x: 200, y: 200 };

console.log(moverEnPantalla(nave, 0, 20));
console.log(moverEnPantalla(nave, 90, 20));

45.6 Ubicar puntos alrededor de un centro

Con seno y coseno se pueden distribuir objetos sobre una circunferencia, como botones radiales, partículas o puntos de una órbita.

x = centroX + cos(ángulo) · radio y = centroY + sin(ángulo) · radio
function puntoCircular(centro, radio, grados) {
  const radianes = grados * Math.PI / 180;

  return {
    x: centro.x + Math.cos(radianes) * radio,
    y: centro.y + Math.sin(radianes) * radio
  };
}

const centro = { x: 100, y: 100 };

console.log(puntoCircular(centro, 50, 0));
console.log(puntoCircular(centro, 50, 90));
console.log(puntoCircular(centro, 50, 180));

45.7 Distribuir varios elementos

Si se divide una vuelta completa entre la cantidad de elementos, se obtiene una distribución circular uniforme.

function puntoCircular(centro, radio, grados) {
  const radianes = grados * Math.PI / 180;

  return {
    x: centro.x + Math.cos(radianes) * radio,
    y: centro.y + Math.sin(radianes) * radio
  };
}

function distribuirEnCirculo(cantidad, centro, radio) {
  const puntos = [];

  for (let i = 0; i < cantidad; i++) {
    const grados = i * 360 / cantidad;
    puntos.push(puntoCircular(centro, radio, grados));
  }

  return puntos;
}

console.log(distribuirEnCirculo(4, { x: 100, y: 100 }, 40));
console.log(distribuirEnCirculo(8, { x: 100, y: 100 }, 40));

45.8 Calcular el ángulo hacia un objetivo

La función Math.atan2 permite obtener el ángulo entre dos puntos. Es muy útil para apuntar, orientar cámaras o dirigir movimientos.

function anguloHacia(origen, destino) {
  const dx = destino.x - origen.x;
  const dy = destino.y - origen.y;
  const radianes = Math.atan2(dy, dx);

  return radianes * 180 / Math.PI;
}

console.log(anguloHacia({ x: 0, y: 0 }, { x: 10, y: 0 }));
console.log(anguloHacia({ x: 0, y: 0 }, { x: 0, y: 10 }));
console.log(anguloHacia({ x: 0, y: 0 }, { x: -10, y: 0 }));

45.9 Apuntar un proyectil

Con el ángulo hacia un objetivo se puede construir la velocidad inicial de un proyectil.

function velocidadHacia(origen, destino, rapidez) {
  const dx = destino.x - origen.x;
  const dy = destino.y - origen.y;
  const angulo = Math.atan2(dy, dx);

  return {
    vx: Math.cos(angulo) * rapidez,
    vy: Math.sin(angulo) * rapidez
  };
}

console.log(velocidadHacia({ x: 0, y: 0 }, { x: 10, y: 0 }, 5));
console.log(velocidadHacia({ x: 0, y: 0 }, { x: 0, y: 10 }, 5));

45.10 Rotar un punto

La trigonometría también permite rotar coordenadas. Esta operación es básica en gráficos 2D, motores de videojuegos y transformaciones geométricas.

x' = x · cos(ángulo) - y · sin(ángulo) y' = x · sin(ángulo) + y · cos(ángulo)
function rotarPunto(punto, grados) {
  const radianes = grados * Math.PI / 180;
  const coseno = Math.cos(radianes);
  const seno = Math.sin(radianes);

  return {
    x: punto.x * coseno - punto.y * seno,
    y: punto.x * seno + punto.y * coseno
  };
}

console.log(rotarPunto({ x: 10, y: 0 }, 90));
console.log(rotarPunto({ x: 10, y: 0 }, 180));

45.11 Rotar alrededor de un centro

Para rotar alrededor de un centro que no está en el origen, primero se traslada el punto, luego se rota y finalmente se vuelve a trasladar.

function rotarPunto(punto, grados) {
  const radianes = grados * Math.PI / 180;
  const coseno = Math.cos(radianes);
  const seno = Math.sin(radianes);

  return {
    x: punto.x * coseno - punto.y * seno,
    y: punto.x * seno + punto.y * coseno
  };
}

function rotarAlrededor(punto, centro, grados) {
  const trasladado = {
    x: punto.x - centro.x,
    y: punto.y - centro.y
  };

  const rotado = rotarPunto(trasladado, grados);

  return {
    x: centro.x + rotado.x,
    y: centro.y + rotado.y
  };
}

console.log(rotarAlrededor({ x: 150, y: 100 }, { x: 100, y: 100 }, 90));

45.12 Generar ondas

El seno permite crear ondas suaves para animaciones, audio, efectos visuales o movimiento repetitivo.

function onda(tiempo, centro, amplitud, periodo) {
  const fase = tiempo / periodo * 2 * Math.PI;
  return centro + Math.sin(fase) * amplitud;
}

console.log(onda(0, 100, 20, 4));
console.log(onda(1, 100, 20, 4));
console.log(onda(2, 100, 20, 4));
console.log(onda(4, 100, 20, 4));

45.13 Simular vibración

Una vibración puede representarse con una onda de poca amplitud y frecuencia alta.

function vibracion(tiempo, intensidad) {
  const frecuencia = 30;
  return Math.sin(tiempo * frecuencia) * intensidad;
}

console.log(vibracion(0.00, 5));
console.log(vibracion(0.05, 5));
console.log(vibracion(0.10, 5));

45.14 Calcular distancia entre puntos

Aunque la distancia se apoya en el teorema de Pitágoras, se usa junto con trigonometría para resolver muchos problemas de movimiento y colisión.

function distancia(a, b) {
  const dx = b.x - a.x;
  const dy = b.y - a.y;

  return Math.sqrt(dx * dx + dy * dy);
}

console.log(distancia({ x: 0, y: 0 }, { x: 3, y: 4 }));
console.log(distancia({ x: 10, y: 10 }, { x: 13, y: 14 }));

45.15 Normalizar un vector

Normalizar un vector significa convertirlo en un vector de longitud 1. Esto permite mover objetos con velocidad constante sin importar la distancia al objetivo.

function normalizar(vector) {
  const longitud = Math.sqrt(vector.x * vector.x + vector.y * vector.y);

  if (longitud === 0) {
    return { x: 0, y: 0 };
  }

  return {
    x: vector.x / longitud,
    y: vector.y / longitud
  };
}

console.log(normalizar({ x: 3, y: 4 }));
console.log(normalizar({ x: 10, y: 0 }));

45.16 Seguir un objetivo

Combinando resta de puntos, normalización y velocidad se puede mover un objeto hacia otro.

function normalizar(vector) {
  const longitud = Math.sqrt(vector.x * vector.x + vector.y * vector.y);

  if (longitud === 0) {
    return { x: 0, y: 0 };
  }

  return {
    x: vector.x / longitud,
    y: vector.y / longitud
  };
}

function avanzarHacia(posicion, objetivo, velocidad) {
  const direccion = normalizar({
    x: objetivo.x - posicion.x,
    y: objetivo.y - posicion.y
  });

  return {
    x: posicion.x + direccion.x * velocidad,
    y: posicion.y + direccion.y * velocidad
  };
}

console.log(avanzarHacia({ x: 0, y: 0 }, { x: 30, y: 40 }, 10));

45.17 Aplicaciones frecuentes

  • Movimiento de personajes, proyectiles y partículas.
  • Rotación de objetos en gráficos 2D.
  • Distribución circular de elementos en una interfaz.
  • Cálculo de ángulos entre puntos.
  • Ondas, vibraciones, pulsos y oscilaciones.
  • Simulación de órbitas y trayectorias circulares.

45.18 Errores comunes

  • Olvidar convertir grados a radianes antes de usar Math.sin o Math.cos.
  • Confundir el sentido del eje Y en coordenadas de pantalla.
  • Usar Math.atan cuando conviene usar Math.atan2.
  • No normalizar vectores antes de aplicar una velocidad.
  • Rotar puntos alrededor del origen cuando se necesitaba rotar alrededor de otro centro.

45.19 Qué debes recordar de este tema

  • La trigonometría permite convertir ángulos en coordenadas y velocidades.
  • El coseno suele usarse para la componente X y el seno para la componente Y.
  • Math.atan2 permite obtener el ángulo hacia un punto.
  • Las rotaciones usan combinaciones de seno y coseno.
  • Las ondas con seno son útiles para animaciones y movimientos repetitivos.

45.20 Conclusión

La trigonometría es una herramienta práctica para transformar ideas geométricas en algoritmos. Permite mover objetos, calcular direcciones, rotar puntos, apuntar hacia objetivos y generar movimientos suaves con pocas líneas de código.