El teorema del eje de separación (SAT) simplifica la determinación del vector de traducción mínimo, es decir, el vector más corto que puede separar dos objetos en colisión. Sin embargo, lo que necesito es el vector que separa los objetos a lo largo del vector que mueve el objeto penetrante (es decir, el punto de contacto).
Dibujé un dibujo para ayudar a aclarar. Hay una caja que se mueve desde la posición anterior a la posterior. En su posición posterior, se cruza con el polígono gris. SAT puede devolver fácilmente el MTV, que es el vector rojo. Estoy buscando calcular el vector azul.
Mi solución actual realiza una búsqueda binaria entre las posiciones antes y después hasta que la longitud del vector azul se conoce hasta cierto umbral. Funciona pero es un cálculo muy costoso ya que la colisión entre formas necesita ser recalculada en cada ciclo.
¿Existe una forma más simple y / o más eficiente de encontrar el vector del punto de contacto?
Respuestas:
De lo que está hablando es bastante difícil si lo estructura como mover primero un objeto, luego probar la colisión y luego retroceder hasta que esté fuera del objeto. Probablemente sea mejor pensar en esto como una prueba de intersección dinámica : un objeto en movimiento contra un objeto estacionario.
Afortunadamente, las pruebas de eje de separación pueden ayudarte aquí. Aquí hay una descripción del algoritmo, cortesía de Ron Levine :
En otras palabras, recorre todos los ejes que normalmente haría en una prueba de eje de separación estática. En lugar de salir temprano si no encuentra superposición, continúe y verifique la velocidad proyectada del objeto en movimiento. Si se está alejando del objeto estático, entonces saldrás temprano. De lo contrario, puede resolver el tiempo de contacto más temprano y más reciente con bastante facilidad (es un intervalo 1D moviéndose hacia otro intervalo 1D). Si hace eso para todos los ejes y mantiene el máximo del primer tiempo de intersección y el mínimo del último tiempo de intersección, entonces sabrá si su objeto en movimiento golpeará el objeto estático, así como cuándo. Para que pueda avanzar su objeto en movimiento exactamente hasta el punto en el que golpeará el objeto estático.
Aquí hay un pseudocódigo aproximado y completamente no verificado para el algoritmo:
Aquí hay un artículo de Gamasutra que habla sobre esto implementado para algunas pruebas primitivas diferentes. Tenga en cuenta que, al igual que SAT, esto requiere objetos convexos.
Además, esto es bastante más complicado que una simple prueba de eje de separación. Asegúrese absolutamente de que lo necesita antes de probarlo. Una gran cantidad de juegos simplemente empujan los objetos entre sí a lo largo del vector de traducción mínimo, porque simplemente no penetran mucho entre sí en un cuadro determinado y es prácticamente imperceptible visualmente.
fuente
Desea usar el recorte de polígonos. Esto se explica mejor con imágenes, que no tengo, pero este tipo sí, así que le dejaré que lo explique.
http://www.codezealot.org/archives/394
El colector de contacto devolverá un punto en uno de los objetos que es "más responsable" de la colisión, no el punto directo de la colisión. Sin embargo, realmente no necesita ese punto de colisión directa. Simplemente puede separar los objetos usando la profundidad de penetración y la normal que ya tiene, y usar el colector de contacto para aplicar otros efectos físicos (por ejemplo, haga que la caja caiga / ruede por la pendiente).
Tenga en cuenta que su imagen ilustra un pequeño problema: el punto en el vector azul que está solicitando no se encontrará en ninguna simulación física, porque eso no es realmente donde golpearía la caja. La caja golpearía con su esquina inferior izquierda en algún lugar más arriba de la pendiente, ya que solo una pequeña parte de la esquina penetra.
La profundidad de penetración será relativamente pequeña, y simplemente empujando la caja fuera de la pendiente a lo largo de la penetración normal colocará la caja lo suficientemente cerca de la posición "correcta" para que sea casi imperceptible en la práctica, especialmente si la caja va a rebotar, caerse , o deslice después de todos modos.
fuente
Simplemente proyecte el vector MAT en la dirección del vector. El vector resultante se puede agregar al vector de dirección para compensar la penetración. Proyecte de la misma manera, como lo hace en el Eje cuando hace el SAT. Esto establece el objeto exactamente en la posición en que toca el otro objeto. Agregue un pequeño épsilon para combatir problemas de coma flotante.
fuente
Hay un par de advertencias en mi respuesta, que primero me saldré del camino: solo trata con cajas de límite no giratorias. Asume que está tratando de lidiar con problemas de túnel , es decir, problemas causados por objetos que se mueven a alta velocidad.
Una vez que haya identificado la MTV, sabrá el borde / superficie normal con la que debe probar. También conoce el vector de velocidad lineal del objeto interpenetrante.
Una vez que haya establecido que en algún momento durante el cuadro, se produjo una intersección, puede realizar operaciones binarias de medio paso, en base a los siguientes puntos de partida: Identifique el vértice que penetró primero durante el cuadro:
Una vez que haya identificado el vértice, el medio paso binario se vuelve mucho menos costoso:
Esto es razonablemente preciso, pero solo proporcionará un único punto de colisión, en un solo caso.
La cuestión es que, por lo general, es posible saber de antemano si un objeto se moverá lo suficientemente rápido por cuadro como para poder hacer un túnel como este, por lo que el mejor consejo es identificar los vértices principales a lo largo de la velocidad y hacer una prueba de rayos a lo largo del vector de velocidad. En el caso de objetos rotativos, tendrá que hacer algún tipo de slerp binario de medio paso para ensamblar el punto de contacto correcto.
Sin embargo, en la mayoría de los casos, se puede suponer con seguridad que la mayoría de los objetos en su escena no se moverán lo suficientemente rápido como para penetrar tan lejos en un solo cuadro, por lo que no es necesario medio paso, y la detección discreta de colisión será suficiente. Los objetos de alta velocidad como las balas, que se mueven demasiado rápido para ver, se pueden rastrear por puntos de contacto.
Curiosamente, este método de medio paso también puede darle el tiempo (casi) exacto en que ocurrió el objeto durante el marco:
Si está haciendo algún tipo de resolución de colisión física, puede corregir la posición de A:
entonces puedes hacer tu física normalmente desde allí. La desventaja es que si el objeto se mueve razonablemente rápido, lo verá teletransportarse a lo largo de su vector de velocidad.
fuente