Los rectángulos permiten detectar contactos con comparaciones simples, pero también introducen ideas fundamentales: intervalos, penetración, normales, ejes separadores y respuesta de colisión.
Las cajas rectangulares se utilizan como regiones de colisión para sprites, ventanas, plataformas, vehículos y elementos de interfaz. Aunque la silueta visible sea compleja, una caja suele proporcionar una aproximación rápida y estable.
Hay dos casos principales: rectángulos alineados con los ejes, llamados AABB, y rectángulos orientados, llamados OBB.
Una AABB puede guardarse mediante esquina, ancho y alto, o mediante límites:
Una OBB requiere centro C, semiejes hx y hy, y dos vectores unitarios locales u y v. Esos ejes contienen su orientación.
Dos cajas no colisionan si existe al menos un eje con un espacio entre sus intervalos:
Si ninguna separación existe, ambas proyecciones se superponen y las cajas colisionan.
Las cuatro condiciones deben cumplirse simultáneamente. Usar < o ≤ define si un simple contacto de bordes cuenta como colisión.
Dos rectángulos pueden tocarse sin compartir área. Conviene elegir una política explícita:
En física suele interesar detectar el contacto; en selección o distribución espacial puede preferirse exigir área compartida.
La cantidad compartida en cada eje se calcula con la intersección de intervalos:
Hay colisión cuando ambos valores son positivos. El menor suele indicar el eje de mínima penetración.
El MTV es el desplazamiento más corto que separa las cajas. Su magnitud es el menor solapamiento y su dirección apunta sobre el eje correspondiente.
El signo se decide comparando los centros. Separar siempre sobre el menor eje evita movimientos diagonales innecesarios.
Para AABB, la normal pertenece a una de cuatro direcciones: (−1,0), (1,0), (0,−1) o (0,1). La normal permite eliminar o reflejar la parte de la velocidad que entra en la superficie.
Una respuesta posicional básica desplaza un objeto por el MTV. Después puede corregirse la velocidad:
Si ambos cuerpos son móviles, el desplazamiento puede repartirse según sus masas inversas.
Un objeto puede atravesar una caja entre dos fotogramas sin que exista solapamiento en ninguna posición muestreada. Este error se llama tunelización.
Las soluciones incluyen pasos más pequeños, límites barridos y detección continua del instante de impacto. Aumentar el tamaño de la caja no resuelve correctamente el problema.
Una AABB alrededor de un rectángulo girado contiene espacio vacío y puede producir falsos positivos. Para una prueba exacta entre OBB se utiliza el teorema del eje separador.
Solo es necesario probar cuatro ejes: las dos direcciones locales de cada rectángulo. Para cada eje unitario L, proyectamos todos los vértices mediante productos escalares:
Si los cuatro pares de intervalos se superponen, los rectángulos colisionan. El eje con menor solapamiento proporciona el MTV.
Mueve y rota el rectángulo B. En modo AABB se comparan límites globales; en modo OBB se prueban los cuatro ejes separadores.
function colisionAABB(a,b) {
return a.x < b.x+b.ancho &&
a.x+a.ancho > b.x &&
a.y < b.y+b.alto &&
a.y+a.alto > b.y;
}
const A={x:1,y:1,ancho:5,alto:3};
const B={x:4,y:2,ancho:4,alto:2};
console.log("¿Colisionan?",colisionAABB(A,B));La salida es true. Con estas desigualdades, un contacto exacto sin penetración no cuenta como colisión.
function contactoAABB(a,b) {
const ax=a.x+a.ancho/2, ay=a.y+a.alto/2;
const bx=b.x+b.ancho/2, by=b.y+b.alto/2;
const px=(a.ancho+b.ancho)/2-Math.abs(bx-ax);
const py=(a.alto+b.alto)/2-Math.abs(by-ay);
if (px<=0 || py<=0) return null;
if (px<py) return {profundidad:px,normal:{x:bx>ax?1:-1,y:0}};
return {profundidad:py,normal:{x:0,y:by>ay?1:-1}};
}
console.log(contactoAABB(
{x:0,y:0,ancho:4,alto:4},
{x:3,y:1,ancho:3,alto:2}
));El resultado contiene la profundidad mínima y una normal que apunta desde A hacia B.
function proyectar(vertices,eje) {
const valores=vertices.map(p=>p.x*eje.x+p.y*eje.y);
return {min:Math.min(...valores),max:Math.max(...valores)};
}
function solape(a,b) {
return Math.min(a.max,b.max)-Math.max(a.min,b.min);
}
const eje={x:1,y:0};
const A=proyectar([{x:0,y:0},{x:4,y:0},{x:4,y:2},{x:0,y:2}],eje);
const B=proyectar([{x:3,y:1},{x:6,y:1},{x:6,y:3},{x:3,y:3}],eje);
console.log("Solape sobre x:",solape(A,B));Un resultado menor o igual que cero señala separación sobre ese eje. SAT termina en cuanto encuentra uno.
Dos vehículos recorren pasillos con cajas orientadas. Cuando sus OBB se superponen, el sistema muestra el contacto, frena ambos vehículos y activa una señal preventiva.
Las colisiones rectangulares aparecen en plataformas, interfaces, cámaras, edificios, vehículos, inventarios, selección, logística y partición espacial.
Recuerda: una AABB colisiona cuando sus intervalos se superponen en ambos ejes; el menor solapamiento produce el MTV; y para OBB se buscan separaciones sobre los cuatro ejes de sus lados.
En el próximo tema estudiaremos colisiones entre círculos.