La detección de colisiones es útil para:
- Determinar la visibilidad de los objetos, haciendo la colisión de la visual del observador con los objetos que pueda haber delante de lo visible u oculto.
- Para determinar la velocidad y las posiciones de los objetos después de las colisiones.
En geometría computacional al usarse la coma flotante, se debe usar un mínimo de distancia de colisión:
- ε = 10E-4
Conceptos previos
Distancia de un punto a un segmento
Distancia de un punto a un segmento
- Se analiza si el punto esta dentro o fuera del segmento, según el producto dot.
- Si esta fuera del segemento, se calcula el módulo de la distancia punto a extremo del segmento.
- Si esta dentro del segmento, se hace igual que distancia punto a recta.
Distancia entre líneas
Intersección rayo-triángulo
Colisión entre esferas
- La distancia mínima entre dos rectas que se cruzan es el módulo del vector w.
- El vector w pasa por los puntos P y Q de cada recta.
- La líneas están parametrizada por el punto por donde pasa y el vector dirección:
- P=P0 + ut
- Q=Q0 + vs
- D0 = Q0 - P0
- Si son paralelas, la distancia es: D = |Do-Dot(Do,u)u|
- Si no son paralelas, la distancia es: D = Dot(Do,C)/|C| siendo C=Cross(U,V)
Intersección rayo-triángulo
- Muy usado en Ray-Tracing
- Ver la orientación del triángulo, suponemos que la normal N mira hacia la fuente del rayo.
- P es el punto de intersección del rayo con el triángulo: P = Lo + L< (Po-Lo), N >
- P puede estar dentro o fuera del triángulo -> Ver si esta dentro de todos los lados del triángulo.
- Se dice que un punto "q" pertenece a un plano si: < q - Po, N > = 0, siendo Po un punto del plano.
- Sustituyendo q por P: < Lo + L·d -Po, N > = 0
- Con lo cual la distancia d = < (Po-Lo), N > / < L, N >
Código para la detección de colisiones:
//Codigo C para interseccion rayo-triangulo
//Punto a la izquierda
bool pointLeft( vec3D q, vec3D p0, vec3D p1, vec3D N)
{
vec3D n=cross((p1-p0),N);
return( dot(q-p0,n) < 0.0);
}
//Interseccion rayo-plano
Vec3D findRayIntersectPlane(Vec3D l0, Vec3D l, Vec3D n, Vec3D p0, float &d) {
// assuming n,l are normalized
float denom = dot(n, l); d = dot(p0 - l0, n);
if (denom < 1e-6) return l0;
return (l0 +(d/ denom )*l)
}
//Interseccion con triangulo
bool rayIntersectTriangle(Vec3D l0, Vec3D l, Vec3D t0, Vec3D t1, Vec3D t2){
float d=0.0;
Vec3D n=normalize(cross(t1-t0,t2-t1));
Vec3D p= findRayIntersectPlane( l0, l, n,t0,d);
return( (pointLeft(p,t0,t1,n) && pointLeft(p,t1,t2,n) pointLeft(p,t2,t0,n));
}
Colisión entre esferas
- La colisión se detecta si la distancia entre los centros es menor que la suma de los radios
- distancia entre centros: d =||c2-c1||
- Colisionan si d < r1 + r2
- Se optimiza el cálculo si se usan los cuadrados: d^2 < (r1 + r2)^2
- Es más rápido, pero menos preciso
- No confundir con d^2 < r1^2 + r2^2, faltaría el termino 2r1·r2
Colisión entre capsulas
- La colisión se detecta si la distancia entre los segmentos es menor que los Radios de las esferas de los extremos: D < ( R1 + R2 )
- Es análogo a las distancia entre esferas.
- Se usa para colisiones entre objetos redondeados que deben rodar.
Colisión entre cajas (Bouding boxes)
- Dos cajas colisionan si existe una recta (2D) o si existe un plano (3D) de separación.
- Para resolver esto se usa el teorema del eje de separación.
- Dos poliedros convexos están separados si existe un plano de separación que sea:
- paralelo a alguna de sus caras
- paralelo al plano determinado por cada par de aristas eligiendo una en cada poliedro.
- En cuanto se de una de estas condiciones se considera que no se tocan.
- En consecuencia, basta con proyectar los vértices de los poliedros en lineas perpendiculares a los planos de separación para determinar separación.
- Según esto hay sólo 15 casos posibles que comprobar:
- Los 6 Planos paralelos a caras de ambas cajas:
- X1, Y1, Z1
- X2, Y2, Z2
- Los 9 Planos paralelos a producto de aristas: (productor vectorial de todas las aristas)
- X1 x X2, X1 x Y2, X1 x Z2
- Y1 x X2, Y1 x Y2, Y1 x Z2
- Z1 x X2, Z1 x Y2, Z1 x Z2
- En cuanto uno estos casos se cumpla: NO HAY COLISIÓN.
Colisión entre Convex Hull
- Se emplea un método generalizado del plano de separación aplicado a las caras y aristas de los poliedros convexos.
- No hay semiejes como en las cajas, que facilitan el cálculo.
- Hay que hacer la comprobación de los planos paralelos y del productos vectorial de aristas.
- El número de comprobaciones es n1+ n2+ ( m1 x m2 )
- Siendo ni = número de caras y mi = número de aristas.
- No se llegan a procesar todas, en cuanto una comprobación da positivo: NO HAY COLISIÓN.















