26. Introducción a vectores

Un vector representa magnitud y dirección. En programación se usa para describir desplazamientos, velocidades, fuerzas, movimientos, trayectorias y relaciones entre puntos.

26.1 Introducción

Hasta ahora usamos puntos para representar posiciones. Un vector, en cambio, representa un desplazamiento, una dirección o una cantidad con orientación.

En videojuegos, simulaciones y gráficos, los vectores son fundamentales para mover objetos, calcular velocidades, apuntar hacia objetivos, aplicar fuerzas y medir direcciones.

En este tema trabajaremos con vectores en dos dimensiones, representados por componentes x e y.

26.2 Qué es un vector

Un vector tiene magnitud y dirección. La magnitud indica cuánto mide o qué tan intenso es. La dirección indica hacia dónde apunta.

Vector: (3, 4)
Componente x: 3
Componente y: 4
const vector = {
  x: 3,
  y: 4
};

console.log(vector);

26.3 Vector como desplazamiento

Un vector puede indicar cómo pasar de un punto a otro. Si un objeto se mueve 5 unidades a la derecha y 2 hacia arriba, su desplazamiento es (5, 2).

const posicionInicial = { x: 10, y: 20 };
const desplazamiento = { x: 5, y: 2 };

const posicionFinal = {
  x: posicionInicial.x + desplazamiento.x,
  y: posicionInicial.y + desplazamiento.y
};

console.log(posicionFinal);

Sumar un vector a un punto produce una nueva posición.

26.4 Vector entre dos puntos

Para obtener el vector que va desde un punto A hasta un punto B, restamos coordenadas.

vectorAB = (xB - xA, yB - yA)
function vectorEntre(a, b) {
  return {
    x: b.x - a.x,
    y: b.y - a.y
  };
}

console.log(vectorEntre(
  { x: 2, y: 3 },
  { x: 8, y: 11 }
));

26.5 Magnitud de un vector

La magnitud de un vector es su longitud. Se calcula con el teorema de Pitágoras.

magnitud = √(x² + y²)
function magnitud(vector) {
  return Math.hypot(vector.x, vector.y);
}

console.log(magnitud({ x: 3, y: 4 }));
console.log(magnitud({ x: 6, y: 8 }));

Un vector (3, 4) tiene magnitud 5.

26.6 Suma de vectores

Para sumar vectores, sumamos sus componentes correspondientes.

(a.x, a.y) + (b.x, b.y) = (a.x + b.x, a.y + b.y)
function sumarVectores(a, b) {
  return {
    x: a.x + b.x,
    y: a.y + b.y
  };
}

console.log(sumarVectores(
  { x: 3, y: 2 },
  { x: 5, y: -1 }
));

La suma combina desplazamientos o efectos que actúan juntos.

26.7 Resta de vectores

Para restar vectores, restamos componente a componente. Esto suele usarse para obtener la dirección desde un objeto hacia otro.

function restarVectores(a, b) {
  return {
    x: a.x - b.x,
    y: a.y - b.y
  };
}

const objetivo = { x: 20, y: 15 };
const jugador = { x: 8, y: 5 };

console.log(restarVectores(objetivo, jugador));

El resultado apunta desde el jugador hacia el objetivo.

26.8 Multiplicar un vector por un escalar

Un escalar es un número que cambia la magnitud de un vector. Multiplicar por 2 duplica el vector; multiplicar por 0.5 lo reduce a la mitad.

function escalarVector(vector, escalar) {
  return {
    x: vector.x * escalar,
    y: vector.y * escalar
  };
}

console.log(escalarVector({ x: 3, y: 4 }, 2));
console.log(escalarVector({ x: 3, y: 4 }, 0.5));

26.9 Vector unitario

Un vector unitario tiene magnitud 1. Sirve para representar dirección sin conservar la longitud original.

vectorUnitario = vector / magnitud
function normalizar(vector) {
  const longitud = Math.hypot(vector.x, vector.y);

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

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

Normalizar es útil cuando queremos una dirección y luego aplicar una velocidad específica.

26.10 Evitar normalizar el vector cero

El vector (0, 0) tiene magnitud cero. No puede normalizarse porque implicaría dividir por cero.

function normalizar(vector) {
  const longitud = Math.hypot(vector.x, vector.y);

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

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

console.log(normalizar({ x: 0, y: 0 }));
console.log(normalizar({ x: 6, y: 8 }));

26.11 Aplicación: mover hacia un objetivo

Para mover un objeto hacia un objetivo, calculamos el vector desde la posición actual hasta el objetivo, lo normalizamos y lo multiplicamos por la velocidad.

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

  const longitud = Math.hypot(direccion.x, direccion.y);

  if (longitud === 0) {
    return posicion;
  }

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

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

26.12 Aplicación: velocidad como vector

La velocidad puede representarse como un vector. Cada actualización suma la velocidad a la posición.

let posicion = { x: 10, y: 20 };
const velocidad = { x: 3, y: -2 };

posicion = {
  x: posicion.x + velocidad.x,
  y: posicion.y + velocidad.y
};

console.log(posicion);

Este modelo simple es común en animaciones y videojuegos.

26.13 Producto punto básico

El producto punto combina dos vectores y devuelve un número. En niveles básicos, puede ayudar a saber si dos direcciones apuntan de forma parecida.

productoPunto = a.x × b.x + a.y × b.y
function productoPunto(a, b) {
  return a.x * b.x + a.y * b.y;
}

console.log(productoPunto(
  { x: 1, y: 0 },
  { x: 0, y: 1 }
));

console.log(productoPunto(
  { x: 1, y: 0 },
  { x: 1, y: 0 }
));

Más adelante, este concepto permite trabajar con ángulos, iluminación, visión y proyecciones.

26.14 Errores comunes

  • Confundir punto con vector: un punto indica posición, un vector indica desplazamiento o dirección.
  • Sumar coordenadas sin distinguir si se está moviendo un punto o combinando vectores.
  • Normalizar el vector cero y terminar dividiendo por cero.
  • Confundir magnitud con componentes individuales.
  • Olvidar que multiplicar por un escalar cambia la magnitud del vector.
  • Usar una dirección no normalizada cuando se esperaba velocidad constante.
const direccion = { x: 30, y: 40 };
const velocidad = 10;

const movimientoSinNormalizar = {
  x: direccion.x * velocidad,
  y: direccion.y * velocidad
};

console.log(movimientoSinNormalizar);

Ese movimiento no tiene longitud 10; multiplica una dirección larga por la velocidad. Por eso suele normalizarse antes.

26.15 Qué debes recordar de este tema

  • Un vector tiene magnitud y dirección.
  • En 2D puede representarse como { x, y }.
  • Un vector puede representar desplazamiento entre puntos.
  • La magnitud se calcula con Math.hypot(x, y).
  • Los vectores se suman y restan componente a componente.
  • Multiplicar por un escalar cambia la magnitud.
  • Normalizar produce un vector de magnitud 1, salvo en el caso del vector cero.

26.16 Conclusión

Los vectores permiten describir movimiento, dirección y desplazamiento de forma compacta. Son una herramienta esencial para cualquier programa que trabaje con posiciones y cambios en el espacio.

En el próximo tema estudiaremos el concepto de función matemática, que nos permitirá describir relaciones entre entradas y salidas de forma general.