42. Detección de colisiones entre puntos y figuras

Detectar si un punto está dentro, fuera o sobre el borde de una figura es la forma más elemental de colisión. Estas pruebas sostienen botones, selección, mapas, zonas activas, pinceles y consultas espaciales.

42.1 Introducción

Una colisión no siempre ocurre entre objetos complejos. Muchas interacciones comienzan preguntando si una posición pertenece a una región: el puntero sobre un botón, un proyectil dentro de una zona, un personaje sobre una baldosa o una muestra dentro de una máscara.

La figura determina la prueba adecuada. Elegir una representación coherente y decidir cómo tratar el borde son tan importantes como la fórmula.

42.2 El problema de pertenencia

Dado un punto P y una región F, buscamos una clasificación:

clasificar(P,F) ∈ {dentro, borde, fuera}

Para una respuesta booleana puede considerarse el borde como interior. En editores o herramientas de precisión conviene conservar las tres posibilidades.

42.3 Sistemas de coordenadas coherentes

El punto y la figura deben expresarse en el mismo sistema. Un clic puede estar en coordenadas de pantalla mientras el objeto está definido en coordenadas locales. Antes de probar la pertenencia hay que transformar uno de ellos.

Plocal = M−1objeto · Pmundo

Esta estrategia simplifica figuras trasladadas, rotadas o escaladas: se lleva el punto hacia la figura original en lugar de reconstruir todos sus límites.

42.4 Punto dentro de un círculo

Para centro C=(cx,cy) y radio r, calculamos la distancia cuadrática:

d²=(px−cx)²+(py−cy)²
d²≤r² → dentro o borde

Comparar cuadrados evita la raíz cuadrada. Además de ser más simple, conserva exactamente la misma relación de orden para cantidades no negativas.

42.5 Punto dentro de un rectángulo AABB

Un rectángulo alineado con los ejes se describe mediante límites mínimos y máximos:

xmin≤px≤xmax
ymin≤py≤ymax

La prueba es rápida porque cada eje se evalúa por separado. Si el rectángulo usa esquina, ancho y alto, entonces xmax=x+ancho e ymax=y+alto.

42.6 Rectángulos rotados

La prueba AABB no puede aplicarse directamente a un rectángulo girado. Se resta su centro y se rota el punto por el ángulo opuesto:

Plocal=R(−θ)(P−C)

En el espacio local, el rectángulo vuelve a estar alineado. Basta comprobar |xlocal|≤ancho/2 e |ylocal|≤alto/2.

42.7 Punto dentro de un triángulo

El signo del producto cruzado indica a qué lado de cada arista está P. Si los tres signos son compatibles, el punto pertenece al triángulo:

signo(P,A,B)=(Px−Bx)(Ay−By)−(Ax−Bx)(Py−By)

Otra opción son las coordenadas baricéntricas. Ambas técnicas exigen decidir si un valor cero —punto sobre una arista— cuenta como interior.

42.8 Punto dentro de un polígono

El método de paridad lanza un rayo desde P y cuenta cruces con el contorno. Un número impar significa interior; uno par, exterior.

cruces impares → dentro
cruces pares → fuera

Funciona con polígonos cóncavos simples. El borde se comprueba primero para evitar ambigüedades cuando el rayo pasa exactamente por un vértice.

42.9 El borde y la tolerancia

Los cálculos decimales rara vez producen cero exacto. Una tolerancia ε permite considerar cercanos dos valores:

|resultado|≤ε → sobre el borde

La tolerancia debe relacionarse con la escala del problema. Un ε útil para coordenadas medidas en píxeles puede ser inadecuado para un mundo medido en kilómetros.

42.10 Prueba rápida y prueba precisa

Para figuras complejas conviene usar dos etapas:

  1. Fase amplia: descartar mediante una caja o círculo envolvente.
  2. Fase estrecha: ejecutar la prueba precisa solo sobre candidatos.

Un descarte barato reduce mucho el trabajo cuando existen cientos o miles de regiones.

42.11 Distancia con signo

Una prueba booleana solo responde dentro o fuera. Una función de distancia con signo agrega cuánto falta para llegar al borde:

círculo: d(P)=|P−C|−r
d<0
punto interior
d=0
punto sobre el borde
d>0
punto exterior

La magnitud sirve para efectos suaves, selección por proximidad, empujes y visualización de zonas de influencia.

42.12 Simulación interactiva

Mueve el punto y cambia la figura. La prueba muestra la clasificación, la fase amplia y los datos geométricos empleados.

P
Clasificacióndentro
Fase ampliacandidato
Detalled² ≤ r²

42.13 Círculo y rectángulo en JavaScript

function puntoEnCirculo(p, c, radio) {
  const dx = p.x - c.x;
  const dy = p.y - c.y;
  return dx*dx + dy*dy <= radio*radio;
}

function puntoEnRectangulo(p, r) {
  return p.x >= r.x && p.x <= r.x+r.ancho &&
         p.y >= r.y && p.y <= r.y+r.alto;
}

console.log(puntoEnCirculo({x:3,y:2},{x:0,y:0},4));
console.log(puntoEnRectangulo({x:3,y:2},{x:1,y:1,ancho:5,alto:3}));

Ambas llamadas muestran true. Los ejemplos incluyen todos los datos necesarios para ejecutarse de forma independiente.

42.14 Triángulo en JavaScript

function signo(p, a, b) {
  return (p.x-b.x)*(a.y-b.y) -
         (a.x-b.x)*(p.y-b.y);
}

function puntoEnTriangulo(p, a, b, c) {
  const s1=signo(p,a,b), s2=signo(p,b,c), s3=signo(p,c,a);
  const hayNegativo=s1<0 || s2<0 || s3<0;
  const hayPositivo=s1>0 || s2>0 || s3>0;
  return !(hayNegativo && hayPositivo);
}

const dentro=puntoEnTriangulo(
  {x:2,y:2}, {x:0,y:0}, {x:6,y:0}, {x:2,y:5}
);
console.log("¿Está dentro?", dentro);

La función considera el borde como parte del triángulo. Si los tres vértices están alineados, debe rechazarse previamente la figura degenerada.

42.15 Polígono en JavaScript

function puntoEnPoligono(p, vertices) {
  let dentro=false;
  for (let i=0,j=vertices.length-1;i<vertices.length;j=i++) {
    const a=vertices[i], b=vertices[j];
    const cruza=(a.y>p.y)!==(b.y>p.y) &&
      p.x < (b.x-a.x)*(p.y-a.y)/(b.y-a.y)+a.x;
    if (cruza) dentro=!dentro;
  }
  return dentro;
}

const figura=[{x:0,y:0},{x:6,y:0},{x:4,y:2},{x:6,y:5},{x:0,y:5}];
console.log(puntoEnPoligono({x:2,y:3},figura));

El método funciona tanto para polígonos convexos como cóncavos, siempre que el contorno sea simple y sus vértices estén ordenados.

42.16 Aplicación animada: escáner de zonas

Un dron recorre una instalación y un sensor puntual cambia de estado al atravesar regiones con formas distintas. La fase amplia descarta zonas lejanas y la prueba precisa identifica la región activa.

CÍRCULORECTÁNGULOTRIÁNGULOSensor: (0,0) · Región: ninguna

42.17 Aplicaciones y optimización

Estas pruebas aparecen en interfaces, selección de objetos, mapas interactivos, zonas de daño, disparos puntuales, partículas, herramientas de pintura, navegación y consultas geográficas.

  • Ordenar las pruebas desde las más baratas hasta las más precisas.
  • Guardar límites envolventes cuando la figura no cambia.
  • Dividir el espacio mediante cuadrículas o árboles cuando hay muchas regiones.
  • Transformar el punto al espacio local de la figura cuando sea más económico.
  • Evitar raíces cuadradas si solo se comparan distancias.

42.18 Errores frecuentes y conclusión

  • Comparar coordenadas que pertenecen a sistemas distintos.
  • Usar directamente una prueba AABB sobre una figura rotada.
  • No definir si el borde cuenta como interior.
  • Comparar resultados decimales con igualdad exacta.
  • Aplicar el algoritmo de polígono a vértices desordenados o autointersecados.
  • No detectar círculos con radio negativo o triángulos degenerados.
  • Ejecutar pruebas costosas sin un descarte amplio previo.

Recuerda: usa el mismo sistema de coordenadas, elige la prueba según la figura, trata el borde explícitamente y combina una fase amplia barata con una fase estrecha precisa.

En el próximo tema estudiaremos colisiones entre rectángulos.