Risposta alla collisione del gioco 2D: SAT e spostamento minimo lungo un determinato asse?


13

Sto cercando di implementare un sistema di collisione in un gioco 2D che sto realizzando. Il teorema dell'asse di separazione (come descritto dal tutorial sulla collisione della metanet ) sembra un modo efficiente e robusto di gestire il rilevamento delle collisioni, ma non mi piace molto il metodo di risposta alle collisioni che usano. Spostandosi ciecamente lungo l'asse di minima sovrapposizione, l'algoritmo ignora semplicemente la posizione precedente dell'oggetto in movimento, il che significa che non si scontra con l'oggetto fermo tanto quanto entra in esso e poi rimbalza.

Ecco un esempio di una situazione in cui questo avrebbe importanza:

Esempio

Secondo il metodo SAT sopra descritto, il rettangolo sarebbe semplicemente fuoriuscito dal triangolo perpendicolare alla sua ipotenusa:

Risposta in stile SAT

Tuttavia, realisticamente, il rettangolo dovrebbe fermarsi nell'angolo in basso a destra del triangolo, poiché quello sarebbe il punto di prima collisione se si muovesse continuamente lungo il suo vettore di spostamento:

Risposta realistica

Ora, questo potrebbe non avere importanza durante il gioco, ma mi piacerebbe sapere se esiste un modo per ottenere in modo efficiente e generalmente spostamenti accurati in questo modo. Ci ho messo il cervello da qualche giorno, e non voglio ancora arrendermi!

(Trasmissione incrociata da StackOverflow, spero che non sia contro le regole!)


È contro le regole. Non crosspost.
Attaccando

Sì, eliminalo da StackOverflow e tienilo qui: P
TravisG

gamedev.stackexchange.com/questions/9144/… Ho risposto alla tua domanda specifica qui.
ultifinito

Eliminato da SO.
Archagon,

Inizia una taglia, archagon: P Altrimenti, potrei doverlo fare. Questa domanda è davvero interessante e sarebbe fantastico vedere una risposta che fa molto di più che elencare un paio di riferimenti.
TravisG,

Risposte:


11

Ecco il metodo che ho trovato. Potrebbe essere difettoso, ma non ho ancora riscontrato alcun problema con la mia analisi superficiale. Funziona anche con poligoni arbitrari con alcune piccole modifiche.

Nelle illustrazioni seguenti, l'oggetto blu si sta muovendo e l'oggetto rosso è fermo. 1 Passaggio 1: per ciascun poligono, trovare i due punti più lontani lungo la proiezione di quel poligono sulla linea perpendicolare al vettore di movimento. 2 Passaggio 2: dividere ciascun poligono lungo la linea che collega questi punti. La metà del poligono che si trova di fronte all'altro poligono lungo il vettore di movimento è lo "scafo anteriore". Questa è l'unica parte del poligono che può eventualmente scontrarsi. 3 Passaggio 3:Proiettare un vettore da ciascun punto sullo "scafo anteriore" di ciascun poligono lungo il vettore di movimento verso il poligono opposto e verificarlo per l'intersezione con ciascun bordo dello "scafo anteriore" del poligono opposto. (Forse lento, ma i computer sono piuttosto veloci al giorno d'oggi - giusto?) (Mi dispiace per la freccia inclinata. Tutte le frecce dovrebbero essere parallele.) 4 Passaggio 4: Prendi il vettore più corto. Questa è l'esatta distanza di collisione. 5 Step 5: Voila! 6


2
È davvero impressionante. Hai per caso paragonato la velocità del tuo algoritmo al semplice multicampionamento (4x o 8x)?
TravisG,

Sfortunatamente no.
Archagon,

Impressionante, e sono sicuro che anche la matematica non è troppo complicata / intensiva. +1
you786

7

Dai un'occhiata a questa domanda simile: Risoluzione delle collisioni

E inoltre, da http://www.metanetsoftware.com/technique/tutorialA.html#section5 (a cui hai inviato un link a :))

SEZIONE 5: Oggetti in rapido movimento

Come accennato in precedenza, oggetti piccoli e / o in rapido movimento possono causare problemi quando si utilizza un test di collisione statica. Esistono diversi approcci che possono essere adottati per gestire tali oggetti: il più semplice è limitare il design del gioco in modo che tali oggetti non siano necessari.

Se devi assolutamente averli, ci sono due metodi comuni per trattare oggetti piccoli e / o in rapido movimento: test di collisione spazzata e multisampling.

- = sweep test = -

Invece di testare l'intersezione tra due forme statiche, possiamo invece creare nuove forme spazzando le forme originali lungo la loro traiettoria e testando la sovrapposizione tra queste forme spazzate.

L'idea di base è descritta in [Gomez], per i test di sweep cerchio-cerchio e AABB-AABB.

- = multicampionamento = -

Un'alternativa molto più semplice ai test spazzati è il multisample; invece di eseguire un singolo test statico nella nuova posizione dell'oggetto, eseguire diversi test in diverse posizioni situate tra la posizione precedente e nuova dell'oggetto. Questa tecnica è stata utilizzata per scontrarsi con il ragdoll a N.

Se ti assicuri che i campioni siano sempre distanziati a distanze inferiori al raggio dell'oggetto, questo produrrà risultati eccellenti. Nella nostra implementazione, limitiamo il numero massimo di campioni, quindi velocità molto elevate possono talvolta causare problemi; questo è qualcosa che può essere modificato in base all'applicazione specifica.

MODIFICARE

In sintesi e AFAIK, ci sono alcune soluzioni

  1. Limita il tuo gioco a non avere mai un oggetto piccolo e / o in rapido movimento che possa persino causare questo
  2. Implementa un sistema che impedisce che si verifichino collisioni, come descritto nel primo link che ho pubblicato
  3. Aumenta la frequenza di campionamento per oggetti in movimento veloci e / o piccoli
  4. ... forse di più, ma non sono un esperto.

1

Dipende se vuoi solo un movimento lineare o se devi anche affrontare un movimento angolare.

Un'alternativa all'utilizzo di SAT:

Nel caso del solo lineare è possibile eseguire il ray-cast contro la differenza di Minkowski dei due poligoni dall'origine nella direzione della velocità lineare delta degli oggetti.

Se il raggio colpisce l'MD, i due oggetti si scontreranno e il punto ferita ti dirà il momento t in cui si sono scontrati.

Ora, se gli oggetti si muovono e ruotano diventa più difficile, ma puoi comunque usare una tecnica simile. Advance Conservative ti permetterà di affrontare questo caso. Questa tecnica è iterativa; ogni iterazione genererà un nuovo MD e ti avvicinerà al momento dell'intersezione.

Ecco la bozza originale del documento sul Conservative Advancement:

http://www.continuousphysics.com/BulletContinuousCollisionDetection.pdf

Ho scritto un articolo che spiega la tecnica in dettaglio qui:

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

Spero che questi aiuti!

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.