Risoluzione delle collisioni in caso di collisione con più oggetti


15

Ho oggetti statici e oggetti mobili. Le collisioni vengono rilevate usando il teorema dell'asse di separazione.

Ad esempio, in questa situazione ho due oggetti statici (in rosso):

inserisci qui la descrizione dell'immagine

e un oggetto mobile tra i due:

inserisci qui la descrizione dell'immagine

Il mio algoritmo è in grado di calcolare la collisione tra due di questi oggetti e sputa anche un vettore di risoluzione perfetta (che significa un vettore a spostamento minimo) alla collisione.

Quindi, ad esempio, quando controllo la collisione tra il rettangolo verde e il rettangolo rosso destro, l'algoritmo sputa un vettore che mi dice come devo spostare il rettangolo verde per risolvere la collisione:

inserisci qui la descrizione dell'immagine

Notate che ho appena disegnato questo in MSPaint, quindi in quella foto potrebbe essere che il vettore di traduzione minima spinga il rettangolo verde in alto, ma suppongo che spingendolo fuori a sinistra / il diritto è in realtà più breve.

Il modo generale di affrontare questo problema sarebbe risolvere solo la collisione di una collisione per fotogramma, anziché contemporaneamente. Ma nel mio caso, ciò comporterebbe il Flip-flop:

Innanzitutto, il solutore rileva due collisioni ma risolve solo la collisione tra il rettangolo destro e il rettangolo verde:

inserisci qui la descrizione dell'immagine

Quindi, nel fotogramma successivo, rileva solo una collisione tra il rettangolo rosso sinistro e il rettangolo verde e lo risolve:

inserisci qui la descrizione dell'immagine

Come puoi vedere, questo in realtà non risolve la collisione (ad esempio spingendo il rettangolo verde verso l'alto), e invece semplicemente infradito tra i due stati all'infinito.

Come posso risolvere questo?


Stai usando i rettangoli nel tuo esempio. Il tuo algoritmo di collisione risolve la collisione solo su un asse? In tal caso, ha senso che si stia verificando il comportamento descritto.
caos Tecnico

No, può risolverli con qualsiasi tipo di forma su tutti gli assi possibili (non solo rettangoli, sono solo i più facili da disegnare con MS Paint: P) e troverà sempre il vettore più corto esistente che allontana i due oggetti .
TravisG,

+1 Buona domanda. Ho rimosso il "tag" (2D) dal titolo, è qualcosa che dovresti evitare (vedi meta ).
Bummzack,

Risposte:


7

A seconda di cosa esattamente stai cercando di ottenere (elevata precisione fisica o solo una simulazione in tempo reale abbastanza vicina), potresti provare a utilizzare i contatti speculativi.

Ecco i dettagli: http://www.wildbunny.co.uk/blog/2011/03/25/speculative-contacts-an-continuous-collision-engine-approach-part-1/

Descrive in quell'articolo ciò che devi sapere per implementarlo, ed è molto semplice rispetto ad altri approcci (come il lancio di sfere e l'ordinamento delle risoluzioni delle collisioni in base al momento dell'impatto).

Se hai bisogno / vuoi di più, puoi acquistare il suo codice sorgente per (IIRC) $ 7.

Ecco un video della mia implementazione in 3D: http://www.youtube.com/watch?v=JvT2H1RmOas

Nota quanto è stabile la simulazione con una sola iterazione. È possibile utilizzare facilmente più iterazioni per frame per risolvere più collisioni in uno stato stabile, che sarebbe più preciso.


2

Puoi prima calcolare tutti i vettori necessari per risolvere ogni collisione, quindi calcolare un risultante da essi.

L'unico caso in cui questo può aggirarti è se questi vettori si annullano a vicenda, proprio come nel tuo esempio. In tal caso, la collisione non può essere risolta.


Aggiungere un piccolo vettore casuale con una magnitudo di circa epsilon * 10 alle collisioni? L'aritmetica in virgola mobile dovrebbe fare il resto.
Martin Sojka,

2
Sì, questo può funzionare, immagino. Ma può anche creare movimenti di jitter.
Mihai Maruseac,

1
Spero di poter ancora ottenere una risposta su questo: il calcolo di una risultante risolve il problema del "loop infinito", ma reintroduce il problema "crack", in cui muoversi mentre si scorre su un muro fatto di piastrelle della stessa dimensione fa sì che il corpo ottenga bloccato tra le "crepe" delle piastrelle. C'è un modo per risolvere entrambi questi problemi?
Vittorio Romeo,

D'accordo ... non esiste una "risposta giusta" migliore per risolvere una collisione del corpo rigido impossibile come quella. O si agita, o si consente un po 'di "fungosità" in uno o più degli oggetti.
David Van Brink,

0

Se lo guardi da vicino, quello stato di oggetti è (o dovrebbe essere) irraggiungibile.

Lascia che la forma rossa più a sinistra sia la forma R1 e la forma rossa più a destra sia la forma R2. Lascia che la forma verde sia G.

vale a dire data la dimensione e la geometria di tutti e tre gli oggetti e dato che tutti gli oggetti non sono penetrabili:

 (1) G could not have been just directly to the left of R2, since R1 has been there 
     already. Consequently, the translation of G from left to right, penetrating R2
     could not have occurred.
 (2) G could not have been just directly to the right of R1 since R2 has been there 
     already. Consquence of which is the same as that from (1).
 (3) Had G come from the top, the movement will be blocked by both R1 and R2, given
     that their geometry and Y coordinate is the same.

Ora, si riduce ad esso, se l'algoritmo interroga i tuoi oggetti uno per uno, allora è una questione di concorrenza, cioè in un certo senso, l'algoritmo dovrebbe controllare TUTTI gli oggetti allo stesso tempo, ma l'algoritmo ti limita a fare oggetti ed elaborarli uno alla volta ...

Se G viene verificato rispetto a R1 dopo che è stato verificato rispetto a R2, allora G sembrerebbe legalmente alla destra di R1 (se G dice che si avvicina a R1 con la direzione del vettore <-1, -1> con magnitudine arbitraria (o distanza) ), poiché il controllo tra R1 e G lo consente e dimentica il controllo tra R2 e G che è stato eseguito in precedenza.

Una soluzione che puoi fare è quella di raccogliere tutti i vettori di spostamento minimo in un array o qualsiasi struttura di dati desideri e sceglierne uno che risulti legale per TUTTI gli oggetti.

Si noti che in un determinato frame, l'oggetto (G per esempio) può avere solo UNA direzione. (oh amico, sembra il boyband ...)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.