Técnicas de detección de colisión del motor de física continua

10

Estoy trabajando en un motor de física puramente continuo , y necesito elegir algoritmos para la detección de colisión de fase amplia y estrecha. "Puramente continuo" significa que nunca hago pruebas de intersección, sino que quiero encontrar formas de detectar cada colisión antes de que suceda, y poner cada una en la pila de "colisiones planificadas" que ordena TOI.

Fase amplia El único método continuo de fase amplia que se me ocurre es encerrar cada cuerpo en un círculo y probar si cada círculo se superpondrá con otro. Sin embargo, esto parece terriblemente ineficiente y carece de sacrificio.

Tampoco tengo idea de qué análogos continuos podrían existir para los métodos de eliminación selectiva de colisión discretos, como los árboles cuádruples. ¿Cómo puedo evitar las pruebas amplias inapropiadas e inútiles, como lo hace un motor discreto? También me gustaría poder ver colisiones con más de 1 fotograma por delante.

Fase estrecha
He logrado adaptar el SAT estrecho a una verificación continua en lugar de una discreta, pero estoy seguro de que existen otros algoritmos mejores en los documentos o sitios que podrían haber encontrado.
¿Qué algoritmos rápidos o precisos sugiere que use y cuáles son las ventajas / desventajas de cada uno?

Nota final:
Digo técnicas y no algoritmos porque aún no he decidido cómo almacenaré diferentes polígonos que podrían ser cóncavos, convexos, redondos o incluso tener agujeros. Planeo tomar una decisión sobre esto en función de lo que requiere el algoritmo (por ejemplo, si elijo un algoritmo que descompone un polígono en triángulos o formas convexas, simplemente almacenaré los datos del polígono en esta forma).

Grifo
fuente
Lamento agregar, pero ¿por qué no usar Box2D? Se ha portado a casi todos los idiomas. Si no planea usarlo, ¿por qué no navega por su fuente para que pueda ver cómo maneja su colisión?
Derek

Respuestas:

2

Realmente solo estoy lanzando ideas por aquí. Asumiendo que tiene (como mínimo) la currentposición y la nextposición; para cada cuadro

Necesitaría dos fases amplias separadas, seguidas de su fase estrecha:

  • Uno que descubra que ocurrirá una colisión.
  • Uno que descubra aproximadamente dónde ocurre realmente la colisión (por ejemplo, una fase amplia / SAT inexacto)
  • Finalmente, su fase estrecha mejoraría el resultado de la segunda fase amplia.

Fase amplia inicial

Puede examinar el hashing espacial (usando la nextposición, no current) para la fase amplia inicial. Esto dividiría bien su espacio problemático en grupos de candidatos para colisión.

Segunda fase amplia

Haga una muestra múltiple binaria utilizando el método de intersección circular que describió. En otras palabras:

left = current
right = next
midpoint = (left + right) / 2
loop a desired amount of times tweaked to the accuracy you want:
  is a collision occuring at midpoint?
    right = midpoint
  else?
    left = midpoint
  midpoint = (left + right) / 2
pointOfCollision = midpoint

Ese ajuste de precisión también podría tener en cuenta la distancia: creo que usar la 'longitud al cuadrado' next - currentobtendría un resultado perfecto de píxeles.

Fase estrecha

Haga una muestra múltiple binaria usando algo como PMask : la lógica será exactamente la misma que la anterior; solo usando una rutina de colisión diferente.

Finalmente

Usted será capaz de elaborar el tiempo de intersección desde pointOfCollision, currenty su actual speedy acceleration(suponiendo que tiene un integrador razonable).

Jonathan Dickinson
fuente
Entonces, para la detección secundaria de fase amplia, ¿está sugiriendo que obtenga el punto medio de la ruta de viaje del círculo y pruebe si está dentro del círculo que se está probando? Estaba pensando que podría simplemente crear una ecuación que da la distancia de dos círculos entre sí sobre el tiempo, y ver si en algún momento la distancia es igual a 0.
Griffin
Además, ¿qué hace Pmask exactamente? el sitio realmente no explica = /.
Griffin
@Griffin su primer comentario podría funcionar, vea si puede resolverlo. Básicamente estoy haciendo una búsqueda binaria en un espacio de colisión ... PMask es bastante inteligente. Vea un 64-int sin signo como una cuadrícula de píxeles de 8x8 (activar / desactivar): un AND simple (binario) determina si se está produciendo una colisión (no cero); primero debes hacer algunos cambios de bits inteligentes, pero esa es la idea. Lea la fuente para más información; es difícil de explicar aquí (o más bien, mi explicación sería una mierda), realmente necesitas referirte a la fuente.
Jonathan Dickinson
1

Bien, he visto que has actualizado tu pregunta para ser más específico. Trataré de ayudarte un poco más.

Para su primera comprobación de fase amplia, recomendaría encarecidamente el hashing espacial .

Básicamente, divide su pantalla en cuadrículas del mismo tamaño. Luego, si un objeto se encuentra dentro de una cuadrícula, lo agrega a un "cubo" en una tabla hash 1D.

Ese es tu primer cheque hecho. Si los objetos no están en el mismo cubo, sería imposible que se crucen.

Continuando con eso, ahora tiene una lista de cubos con objetos (potencialmente) en ellos. Puede hacer otra verificación de fase amplia aquí:

A.) Dividiendo este cubo en otros 4 cubos, y verificando la tabla hash 1D resultante. Si no están en el mismo balde, no hay colisión.

O:

B.) Hacer una simple verificación de distancia y tener en cuenta el ancho y / o la altura del objeto para garantizar la precisión.

¿Pero qué pasa cuando potencialmente tienes una colisión?

Entonces recomendaría algo similar a esto . Es esencialmente un tipo de mezcla entre colisión poligonal (para formas complejas) o rectángulo / círculo para formas menos complejas.

Además, si realmente desea "detectar colisiones antes de que sucedan y almacenarlas", siempre puede hacer algo como esto:

Si dos objetos están en el mismo cubo, entonces podrían colisionar.

Además, ¿están los objetos lo suficientemente cerca como para que puedan colisionar pronto? (Teniendo en cuenta la velocidad, el tamaño del objeto y la distancia)

Si la respuesta a ambas es afirmativa, continúe y guárdela para hacer una prueba de intersección más tarde.


" Antigua respuesta

Bueno, desafortunadamente he perdido la noción de mi manual "Todos los tipos de colisión y para qué se usan". :)

Sin embargo, a pesar de que esta es una pregunta extremadamente amplia, te ayudaré a comenzar.

Hay una buena (respuesta) pregunta relacionada con algo como esto aquí .

Además de un artículo de las personas que hicieron N y N + aquí .

Sin mencionar que tienes la buena colisión por píxel de reserva .

Dudo sinceramente que alguien tenga a mano una lista de cada tipo de colisión, pero esto debería ayudarlo a comenzar.

Sin embargo, debo mencionar que el tipo de colisión que necesitas (y terminarás usando) depende en gran medida del tipo de juego que estés creando. Es por eso que encuentra tutoriales: la mayoría de las personas asumen que tiene una idea de lo que quiere, por lo que lo ayudan en esa área específica. Me doy cuenta de que la mayoría de mis enlaces son tutoriales sobre un tema específico, pero creo que honestamente te ayudarán más. Una lista es una cosa, pero si usted lee sobre cada punto de viñeta usted mismo, puede llegar a una decisión más informada que probablemente se adapte a sus necesidades más específicamente.

electroflame
fuente
Olvidé agregar el método en el que basé mi colisión (por píxel usando un diseño de casco). Perdone el archivo, el sitio original se ha ido al cielo del sitio web. web.archive.org/web/20090126230334/http://www.ziggyware.com/…
electroflame