12. Proyección de un vector sobre otro

Proyectar permite medir y representar cuánto de un vector se encuentra alineado con una dirección elegida.

12.1 Medir un vector desde una dirección

Imaginemos la sombra perpendicular de un vector sobre una recta orientada. Esa sombra es su proyección. La operación conserva únicamente el aporte alineado con la dirección de referencia y descarta, por el momento, el aporte perpendicular.

Podemos expresar la proyección como un número con signo o como un vector. Distinguir ambas formas evita confusiones en fórmulas y programas.

Pregunta que responde: ¿cuánto del vector a apunta a lo largo de la dirección definida por b?

12.2 Proyección escalar

La proyección escalar de a sobre un vector no nulo b es:

compb(a) = (a · b) / |b|

También vale |a| cos θ. El resultado es un número con la unidad de a. Su signo indica si el aporte sigue el sentido de b o el opuesto.

12.3 Proyección sobre un vector unitario

Si u es unitario, |u| = 1 y la fórmula se simplifica:

compu(a) = a · u

Esta es una razón importante para trabajar con direcciones normalizadas: el producto escalar devuelve directamente la componente firmada sobre la dirección.

function componenteSobreUnitario(a, u) {
  return a.x * u.x + a.y * u.y;
}

const a = { x: 5, y: 3 };
const u = { x: 0.8, y: 0.6 };
console.log(componenteSobreUnitario(a, u));

12.4 Proyección vectorial

Para conservar dirección y sentido multiplicamos la componente escalar por el unitario de b:

proyb(a) = [(a · b) / |b|²] b

El resultado es un vector paralelo a b. Si el coeficiente es negativo, apunta en sentido contrario.

function proyectar(a, b) {
  const denominador = b.x * b.x + b.y * b.y;
  if (denominador === 0) return null;
  const factor = (a.x * b.x + a.y * b.y) / denominador;
  return { x: factor * b.x, y: factor * b.y };
}

console.log(proyectar({ x: 5, y: 3 }, { x: 4, y: 1 }));

12.5 Por qué aparece |b|²

El vector b puede tener cualquier longitud. El cociente por |b|² compensa esa longitud antes de volver a multiplicar por b. Así, escalar b por un número positivo no cambia la proyección.

Si normalizamos primero, u = b/|b|, obtenemos la forma equivalente:

proyu(a) = (a · u)u

12.6 Interpretar el signo

Signo de la componente escalar.
a · bÁnguloSentido de la proyección
PositivoMenor que 90°El mismo que b
Cero90°Proyección nula
NegativoMayor que 90°Opuesto a b

La longitud geométrica de una sombra es no negativa, pero la componente escalar conserva signo para comunicar orientación.

12.7 Ejemplo paso a paso

Proyectemos a = (6, 4) sobre b = (3, 0).

  1. a·b = 6·3 + 4·0 = 18.
  2. |b| = 3 y |b|² = 9.
  3. Componente escalar: 18/3 = 6.
  4. Factor vectorial: 18/9 = 2.
  5. Proyección vectorial: 2(3, 0) = (6, 0).

La proyección sobre el eje horizontal coincide con la componente cartesiana x de a.

12.8 Casos especiales

  • Si a y b tienen el mismo sentido, la proyección de a es a.
  • Si son perpendiculares, la proyección es el vector nulo.
  • Si tienen sentidos opuestos, la proyección apunta en sentido contrario a b.
  • Si a es nulo, su proyección es nula.
  • Si b es nulo, la proyección no está definida.
No existe una dirección de proyección definida por el vector nulo. El programa debe detectarlo antes de dividir por |b|².

12.9 Proyectar sobre los ejes

Las componentes cartesianas son casos particulares. Al proyectar a sobre i = (1, 0), obtenemos axi. Sobre j = (0, 1), obtenemos ayj.

a = proyi(a) + proyj(a)

Esta reconstrucción funciona directamente porque la base cartesiana es ortonormal.

12.10 Aplicaciones

  • Medir la velocidad de un objeto a lo largo de una vía.
  • Obtener el aporte de una fuerza en una dirección de movimiento.
  • Calcular la sombra ortogonal de un punto o vector sobre una recta.
  • Separar movimiento tangencial y normal.
  • Determinar cuánto mira un personaje hacia un objetivo.
  • Eliminar una componente no permitida en una restricción.

La proyección no debe confundirse con una perspectiva visual; aquí se trata de una proyección ortogonal sobre una dirección vectorial.

12.11 Punto más cercano sobre una recta

Una recta pasa por P y tiene dirección no nula d. Para hallar el punto Q de la recta más cercano a X, proyectamos X − P sobre d y sumamos P:

Q = P + proyd(X − P)
function puntoMasCercano(p, direccion, x) {
  const relativo = { x: x.x - p.x, y: x.y - p.y };
  const d2 = direccion.x ** 2 + direccion.y ** 2;
  if (d2 === 0) return null;
  const t = (relativo.x * direccion.x + relativo.y * direccion.y) / d2;
  return { x: p.x + t * direccion.x, y: p.y + t * direccion.y };
}

console.log(puntoMasCercano({ x: 1, y: 1 }, { x: 3, y: 1 }, { x: 4, y: 5 }));

12.12 Laboratorio de proyección

Modificá el vector a y la dirección b. La línea discontinua une la punta de a con su proyección ortogonal.

a · b
Componente escalar
Factor sobre b
Proyección vectorial
Módulo proyectado

La proyección tiene el mismo sentido general que b.

12.13 Implementación robusta

Con datos aproximados podemos tratar como nula una dirección extremadamente pequeña. El umbral debe elegirse según el dominio:

function proyectarSeguro(a, b, epsilon = 1e-12) {
  const longitudCuadrada = b.x * b.x + b.y * b.y;
  if (longitudCuadrada <= epsilon * epsilon) return null;
  const factor = (a.x * b.x + a.y * b.y) / longitudCuadrada;
  return { x: factor * b.x, y: factor * b.y };
}

console.log(proyectarSeguro({ x: 3, y: 5 }, { x: 1, y: 0 }));

12.14 Errores frecuentes

  • Confundir la proyección escalar con la vectorial.
  • Dividir por |b| en vez de |b|² en la fórmula vectorial.
  • Suponer que b es unitario sin comprobarlo.
  • Eliminar el signo de la componente escalar.
  • Proyectar sobre el vector nulo.
  • Intercambiar «proyección de a sobre b» con «proyección de b sobre a».
  • Redondear el factor antes de construir el vector.

12.15 Ejercicio integrador

Una velocidad v = (8, 6) m/s debe analizarse a lo largo de una vía cuya dirección es d = (3, 4).

  1. Comprobá que d no es unitario.
  2. Calculá la componente escalar de v sobre d.
  3. Calculá la proyección vectorial.
  4. Comprobá que la proyección es paralela a d.
  5. Explicá el signo obtenido.
Ver solución y código

|d| = 5. El producto v·d = 48. La componente escalar es 9,6 m/s. El factor es 48/25 = 1,92 y la proyección vectorial es (5,76; 7,68) m/s, de módulo 9,6 m/s. Es positiva porque forma un ángulo agudo con d.

const v = { x: 8, y: 6 };
const d = { x: 3, y: 4 };
const moduloD = Math.hypot(d.x, d.y);
const producto = v.x * d.x + v.y * d.y;
const componente = producto / moduloD;
const factor = producto / (moduloD ** 2);
const proyeccion = { x: factor * d.x, y: factor * d.y };

console.log({ moduloD, producto, componente, factor, proyeccion });
console.log("Módulo proyectado:", Math.hypot(proyeccion.x, proyeccion.y));

12.16 Ideas para recordar

  • Proyectar mide cuánto de un vector se alinea con una dirección.
  • La proyección escalar es (a·b)/|b| y conserva signo.
  • La proyección vectorial es [(a·b)/|b|²]b.
  • Si la dirección es unitaria, las fórmulas se simplifican.
  • La proyección es paralela al vector de referencia.
  • Proyectar sobre el vector nulo no está definido.
  • Las componentes cartesianas son proyecciones sobre los ejes unitarios.

En el próximo tema separaremos sistemáticamente un vector en componentes paralela y perpendicular.