Resolución de colisión

23

Sé muy bien cómo verificar las colisiones, pero no sé cómo manejar la colisión de una buena manera.

Simplificado, si dos objetos chocan, uso algunos cálculos para cambiar la dirección de la velocidad. Si no muevo los dos objetos, todavía se superpondrán y si la velocidad no es lo suficientemente grande, aún colisionarán después de la próxima actualización. Esto puede hacer que los objetos se atasquen entre sí.

Pero, ¿qué pasa si trato de mover los dos objetos para que no se superpongan? Esto suena como una buena idea, pero me di cuenta de que si hay más de dos objetos, esto se vuelve muy complicado. ¿Qué pasa si muevo los dos objetos y uno de ellos choca con otros objetos, así que también tengo que moverlos y pueden chocar con las paredes, etc.

Tengo en mente un juego 2D de arriba hacia abajo, pero no creo que tenga mucho que ver con eso. ¿Cómo se manejan generalmente las colisiones?

Esta pregunta se hace en nombre de Wooh

CiscoIPPhone
fuente
1
¿Puedes aclarar el tipo de juego? "De arriba hacia abajo en 2D" podría significar muchas cosas: un juego de acción y aventura al estilo Zelda, un juego de disparos de desplazamiento vertical o un juego de billar de bolsillo. ¡Todo esto tendría estilos estándar muy diferentes de manejo de colisiones!
Ian Schreiber
2
No puedo aclarar eso. La pregunta no se trata de lo que sucederá como resultado de una colisión, se trata de manejar el problema de superposición múltiple. Creo que es suficiente saber que estoy rebotando objetos entre sí y quiero que se comporten de manera realista para responder esta pregunta.
CiscoIPPhone

Respuestas:

16

Daniel Kodicek cubre este tema con gran detalle en su libro, Matemáticas y física para programadores .

Kodicek hace dos cosas para lograr una resolución de colisión de aspecto natural:

  • Su función de detección de colisión calcula el tiempo exacto en que chocarán dos objetos.
  • Él recalcula nuevas velocidades en el momento de la colisión, por lo que los objetos nunca se superponen.

Subí una demostración basada en la detección y resolución de colisiones de Kodicek .

actualización: Aquí hay un algoritmo de detección y resolución de colisión que es muy similar al método de Kodicek. Con código fuente . Todavía recomiendo el libro de Kodicek, ya que su algoritmo se implementa de manera ligeramente diferente y se explica mucho más a fondo.

Leftium
fuente
1
Su enlace de demostración parece estar roto.
cenizas999
@ ashes999: enlace arreglado ahora!
Leftium
Es un algoritmo para círculos. ¿Qué hay de las cajas?
Anton Chikin
@AntonChikin: el algoritmo de resolución de colisión de Kodicek solo toma tres entradas: masa, velocidad y normal en el punto de colisión. Kodicek siempre calcula lo normal en el punto de colisión al detectar colisiones. Explica muchos tipos diferentes de detección de colisión, incluida una caja que golpea otra caja. Simplemente conecte ese algoritmo de detección de colisión en el algoritmo de resolución de colisión. Vea los capítulos 8-10 del libro de Kodicek para una explicación completa. (Tenga en cuenta que la física rotacional requiere más matemática, que también se trata más adelante en el libro ...)
Leftium
1
@ThomasHilbert: el código fuente de demostración y los ejecutables de Windows ahora están disponibles en leftium.com/asteroid
Leftium
6

¿Qué pasa si comprueba la colisión antes de que los objetos se muevan, en lugar de después? O, en otras palabras, ¿rechaza la nueva posición si los objetos chocan, reutilizando la anterior en ese caso?

Pseudocódigo:

  tmpPosition1 = Obj1.position
  tmpPosition2 = Obj2.position
  updatePosition(Obj1)
  updatePosition(Obj2)
  if collided(Obj1,Obj2) then
      updateVelocities( Obj1, Obj2 )
      Obj1.position = tmpPosition1
      Obj2.position = tmpPosition2
  endif

De esta manera, los objetos chocarán entre sí cuando estén a punto de colisionar , si su paso de actualización es lo suficientemente pequeño, el jugador no debería notar nada extraño en la representación.

CeeJay
fuente
1
Esto es bastante molesto, porque no puedes moverte fácilmente en paralelo a los objetos porque no puedes moverte en absoluto si tocas otros objetos.
Ikke
A menos que resuelva x e y por separado
instantaphex
6

Siempre que dos objetos se superpongan, verifique si se están acercando o alejando uno del otro. Haz la colisión solo si se mueven uno hacia el otro.

Es bastante fácil con las matemáticas vectoriales, simplemente calcula:

dot_product (B.posición - A.posición, A.velocidad - B.velocidad)

Si el resultado es positivo, los objetos se mueven uno hacia el otro.

aaaaaaaaaaaa
fuente
4

Podría estar malinterpretando, pero parece que estás haciendo dos preguntas: 1. ¿Cuáles son algunas formas generales de lidiar con la resolución de colisiones? El término que estás buscando es 'simulación basada en impulsos', y hay un montón de documentos que puedo hacerlo mejor justicia que yo.

En resumen, desea acelerar su simulación física en el espacio de impulso, que es la masa por la velocidad (no haga las cosas basadas en la fuerza, su integrador no lo está haciendo bien de todos modos).

Para una respuesta angular, afortunadamente, los momentos de inercia mayores y menores siempre se pueden reducir a dos ejes ortogonales (en 2D), lo que significa que una matriz múltiple funcionará en general, y si los alinea con los ejes X e Y, se convierte en un vector 2D

Cuando tiene una colisión, calcula una respuesta basada en los momentos lineales y angulares en el punto de colisión, y un buen factor de fraude es, si tiene interpenetración, aplicar alguna fuerza de penalización (como se mencionó anteriormente) para separar los dos cuerpos.

Desde el punto en que terminará agregando más y más reglas para controlar el comportamiento aberrante, como limitar el momento angular máximo para que las cosas no giren como tops, etc., pero este es un buen comienzo.

Mantenlo simple si puedes.

  1. ¿Cómo se resuelven los problemas de colisión de varios cuerpos?

La única forma real de hacerlo es con un sistema de ecuaciones lineales y mucha resolución. La forma práctica de hacerlo es tener un sistema como el anterior y hacer que la física se resuelva naturalmente con el tiempo.

La mayoría de los juegos que hacen cosas como rodar, o pararse sobre superficies en movimiento, tienen un modelo híbrido donde sus pies están unidos a una superficie (o ruedas a la carretera) para acomodar el paso del tiempo físico (lo que resultaría en ciclos de respuesta de interpenetración y no funcionaría)

Espero que esto ayude. Si necesita ejemplos matemáticos, hágamelo saber.

Aaron Brady
fuente
3

La forma en que esto generalmente se resuelve en los motores de física es aplicando una fuerza de penalización. Mover el cuerpo rígido después de la interpenetración no se verá bien si sus cuerpos rígidos se mueven a velocidades más altas (verá movimientos de sacudida momentáneos), aunque como primer paso, debe intentarlo y ver si se ajusta a sus necesidades.

A penalty forcese aplica como un amortiguador de resorte, donde la fuerza de penalización aumenta cuanto más se ha penetrado el cuerpo rígido y se reduce en los cuadros posteriores. Piense en ello como resortes. Cuando dos cuerpos rígidos se entrecruzan, cada uno se encuentra con un resorte invisible que amortigua su progresión (es decir, evita una mayor penetración) y aplica lo mencionado anteriormente penalty forcehasta que los cuerpos ya no penetran.

Es un tema amplio, pero espero que la información anterior lo ayude a comenzar.

Samaursa
fuente
Entonces, en lugar de evitar la interpenetración, este método lo permite pero proporciona resistencia, ¿casi como si los objetos estuvieran comprimidos?
CiscoIPPhone
Proporciona resistencia, sí, la resistencia aumenta cuanto más intenta el cuerpo penetrar. En la práctica, si tiene un tiempo delta lo suficientemente bajo (por ejemplo, 10 ms), no producirá ninguna penetración. Sin embargo, la verdadera ventaja de este método es cuando tiene cuerpos que se han interpenetrado por varias razones (se cambió la posición, son cuerpos rígidos en red y se corrigieron sus posiciones) y ahora necesitan separarse, porque sin esta técnica los cuerpos explotará en lugar de separarse gradualmente.
Samaursa el