Qual è il modo più efficiente per trovare il punto di intersezione di un missile e un terreno bitmap?


10

In seguito alla mia precedente domanda sulla ricerca della pendenza di un terreno bitmap 2D, ora ho bisogno di conoscere il modo migliore per trovare il punto sul terreno 2D che il missile ha colpito. Ovviamente, posso vedere se qualche pixel sotto il missile interseca il terreno, ma dico che si è spostato abbastanza in profondità nel terreno.

Qual è il modo migliore per fare un passo indietro per trovare dove si è inizialmente scontrato? Potrei spostare X pixel alla volta verso la posizione precedente del missile, ma quale sarebbe un buon valore di X? E c'è un modo più intelligente? Forse spostando metà della distanza, quindi un quarto ecc.?


Il fenomeno che stai descrivendo è comunemente chiamato "tunneling", e il modo migliore per affrontarlo è introdurre un test di scansione - come TetraD e JasonD hanno entrambi menzionato di seguito.
jpaver,

solo dire "sweep test" non mi aiuta in realtà. Come posso farlo con un terreno bitmap?
Iain,

Il suggerimento di Jason sembra essere il migliore per me: un pixel alla volta.
jpaver,

Risposte:


3

Per i test di collisione non dovresti fare test statici tick-by-tick, dovresti fare test di tracce / sweep.

C'è un elenco esaustivo di varie formule per diversi tipi di primitivi qui: http://www.realtimerendering.com/intersections.html

Ovviamente, supponendo che tu possa abbattere il tuo terreno in una sorta di insieme di primitivi su cui puoi testare (cioè segmenti di linea). Ci sono vari modi per farlo.

Vedi anche questa domanda (solo leggermente correlata): qual è un buon algoritmo per rilevare la collisione tra sfere in movimento?


Stavo pensando a un terreno bitmap distruttibile come in Worms. Potresti generare in modo dinamico primitive da una bitmap o sarebbe troppo folle?
Iain,

1
Sono sicuro che potresti, ma potrebbe essere più facile / veloce eseguire test pixel per pixel per una bitmap arbitraria.
Tetrad,

CON UN QUADTREE !! (quindi non ci vorrà per sempre)
bobobobo,

3

La ricerca binaria non sarà di aiuto se hai piccoli frammenti di scenari e proiettili in rapido movimento: potresti perderli.

Penso che la tua migliore opzione sia quella di passare una linea attraverso la parte anteriore del proiettile lungo il percorso che prende, pixel alla volta. È possibile eseguire prima un controllo di delimitazione sull'intero volume per evitare di eseguire ogni passaggio.


Che cos'è la ricerca binaria?
Iain,

1
Spiacenti, la ricerca binaria è più o meno ciò di cui parlavi nella domanda. Si inizia nel mezzo e si divide lo spazio di ricerca per due fino a quando non si converge sulla risposta. È ottimale in molti casi, ma nel tuo caso non funzionerebbe (potresti saltare completamente la risposta corretta).
JasonD,

3

Dato che è improbabile che il missile si sposti su una grande quantità di pixel per ogni fotogramma (non sarebbe uniforme sullo schermo) non vedo alcun motivo per non controllare solo ogni pixel sul percorso. L'algoritmo di linea Bressenham è tuo amico e assicurati di avere anche una copia locale della tua bitmap poiché generalmente non vuoi accedere alla memoria video per ogni pixel. Questo presuppone che il tuo terreno bitmap sia completamente casuale (come per il terreno worm worm distruttibile). Se il tuo mondo è basato su tessere potresti saltare tutte le tessere che sai sono vuote per cominciare, ma come accennato prima, a meno che tu non abbia un'enorme quantità di missili da controllare non potrei pensare a una piattaforma che avrebbe bisogno che sia troppo lenta per testare pixel per pixel e non avrai bisogno di avere il tuo mondo definito in primitive (un clone di worm renderebbe così difficile)


sì, stavo pensando a un terreno simile a Worms. Potresti dividerlo in tessere dinamicamente, quindi contrassegnare solo le tessere vuote da non controllare? Se ci fossero molti missili contemporaneamente, ciò potrebbe accelerare un po 'le cose?
Iain,

Quindi pensi che dovrei spostarmi avanti pixel per pixel, controllando l'intersezione, piuttosto che fare un passo indietro?
Iain,

Penso che tutte e tre le risposte abbiano suggerito una ricerca in avanti. Il controllo all'indietro non funzionerà se il passaggio in avanti lo fa saltare alcuni scenari.
JasonD,

Sì, decisamente avanti.
Kaj,

1

Oltre alle altre risposte, ci sono alcune cose che puoi fare per accelerare ciò se vuoi fare un po 'di contabilità per quanto riguarda la "raccolta" di un mucchio di pixel in blocchi di "stato simile conosciuto". Ad esempio, potresti memorizzare l'altezza del pezzo di terreno più alto, in modo da poter dare per scontato che il missile non colpirà nulla fintanto che è al di sopra di esso. Potresti anche memorizzare l'altezza dello spazio "aereo" più basso, quindi saprai che se il missile arriva a quell'altitudine deve aver colpito qualcosa (anche se questo potrebbe essere meglio usato come controllo di sanità mentale). Andando oltre, è possibile memorizzare rettangoli che rappresentano aree che sono tutti terreno e altri rettangoli che sono tutti aria, ma che potrebbe essere più lavoro che valore.

In definitiva, il metodo migliore sarà probabilmente "immagazzinare dall'altezza di ogni colonna del terreno" e quindi calcolare l'altezza del missile ad ogni passo del suo percorso. Non posso parlare a giochi più moderni, ma credo che quando hai creato una "grotta" nella Terra bruciata, il terreno sopra quella grotta è caduto dritto, senza lasciare strapiombi. Se vuoi sporgenze il lavoro sarà un po 'più grande, ma sarà un'estensione di questa idea di base. (Suggerimento: far funzionare prima l'idea di base!)

Poiché il tuo terreno è presumibilmente completamente arbitrario, non ci sono scorciatoie. Anche se hai costretto il tuo terreno ad essere una spline o qualcosa del genere, questo si arrabbierà quando inizi a distruggerlo e i test di intersezione linea-spline sono iterativi e non perfetti o esaustivi e inutilmente lenti per il tuo tipo di problema.

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.