Las colisiones circulares convierten una prueba geométrica sencilla en una respuesta física completa: distancia, normal, penetración, velocidad relativa, impulso y conservación del movimiento.
Los círculos son regiones de colisión naturales para pelotas, partículas, ruedas, planetas, campos de alcance y personajes aproximadamente redondos. Su simetría hace que la orientación no afecte la prueba.
La misma información usada para detectar el contacto permite separar los cuerpos y calcular un rebote.
Cada círculo se describe con un centro y un radio:
Los radios deben ser no negativos. Para colisiones físicas también se agregan velocidad, masa, restitución y, opcionalmente, fricción.
Los círculos se tocan o solapan cuando la distancia entre centros no supera la suma de radios:
Si la distancia es mayor, existe separación. Si es igual, hay contacto tangencial; si es menor, existe penetración.
Para detectar sin calcular raíces:
Esta forma es ideal cuando solo necesitamos un booleano. Para obtener la profundidad y la normal sí necesitaremos la distancia real.
En código se usa una tolerancia para distinguir el contacto de una diferencia decimal mínima.
La normal apunta desde A hacia B:
Es un vector unitario. Si los centros coinciden, la división no está definida; debe elegirse una normal alternativa basada en la velocidad relativa o una dirección fija.
Un valor positivo indica cuánto debe aumentar la distancia entre centros para eliminar la superposición. El vector mínimo de traslación es n multiplicado por esa profundidad.
Cuando los círculos apenas se tocan, el punto de contacto sobre A es:
Si ya penetraron, las dos superficies producen puntos distintos. Puede usarse un punto intermedio o corregir primero las posiciones y calcularlo después.
Si A y B tienen la misma movilidad, cada uno se separa la mitad de la profundidad:
Con masas diferentes se reparte según las masas inversas. Un cuerpo inmóvil tiene masa inversa cero y no recibe desplazamiento.
Antes de aplicar un rebote calculamos cómo se aproxima B respecto de A:
Si vn>0 los cuerpos ya se separan; aplicar otro impulso los aceleraría incorrectamente. Solo se responde cuando vn<0.
Para masas inversas invA e invB y restitución e:
Después se aplican impulsos opuestos:
e=1 representa un choque perfectamente elástico; e=0 elimina la velocidad relativa normal.
Un círculo rápido puede atravesar otro entre fotogramas. La detección continua estudia el movimiento relativo y resuelve el instante t donde:
La ecuación es cuadrática. La menor raíz válida dentro del fotograma indica el primer impacto.
Mueve el círculo B y modifica los radios. La escena muestra la línea de centros, la normal, el punto de contacto y la profundidad.
function colisionCirculos(a,b) {
const dx=b.x-a.x, dy=b.y-a.y;
const suma=a.radio+b.radio;
return dx*dx+dy*dy <= suma*suma;
}
const A={x:0,y:0,radio:3};
const B={x:4,y:1,radio:2};
console.log("¿Colisionan?",colisionCirculos(A,B));La salida es true. No se calcula ninguna raíz porque solo se necesita comparar.
function contactoCirculos(a,b) {
const dx=b.x-a.x, dy=b.y-a.y;
const distancia=Math.hypot(dx,dy);
const suma=a.radio+b.radio;
if (distancia>suma) return null;
const normal=distancia>1e-9
? {x:dx/distancia,y:dy/distancia}
: {x:1,y:0};
return {
normal,
profundidad:suma-distancia,
punto:{x:a.x+normal.x*a.radio,y:a.y+normal.y*a.radio}
};
}
console.log(contactoCirculos(
{x:0,y:0,radio:3},{x:4,y:0,radio:2}
));El caso de centros coincidentes recibe una normal alternativa para evitar una división por cero.
function aplicarImpulso(a,b,n,restitucion=1) {
const rv={x:b.vx-a.vx,y:b.vy-a.vy};
const velocidadNormal=rv.x*n.x+rv.y*n.y;
if (velocidadNormal>=0) return;
const invA=1/a.masa, invB=1/b.masa;
const j=-(1+restitucion)*velocidadNormal/(invA+invB);
a.vx-=j*invA*n.x; a.vy-=j*invA*n.y;
b.vx+=j*invB*n.x; b.vy+=j*invB*n.y;
}
const A={vx:3,vy:0,masa:1};
const B={vx:-1,vy:0,masa:1};
aplicarImpulso(A,B,{x:1,y:0});
console.log("Velocidades:",A.vx,B.vx);Para masas iguales y restitución 1, los cuerpos intercambian sus velocidades normales.
Las partículas se mueven con velocidades y masas diferentes. Cada contacto corrige la penetración y aplica un impulso elástico; el destello señala el último choque.
Las colisiones circulares se usan en juegos de billar, partículas, ruedas, campos de fuerza, alcance de sensores, multitudes, moléculas y aproximaciones de personajes.
Recuerda: compara d² con (rA+rB)²; la normal une los centros; la penetración produce el MTV; y el impulso solo actúa si la velocidad relativa apunta hacia el contacto.
En el próximo tema estudiaremos interpolación y movimiento suave.