Algoritmo per vedere se due voxel sono interconnessi


11

Sto cercando un buon algoritmo per il seguente problema: Data una griglia 3D di voxel (che può essere vuota o riempita), se scelgo due voxel non adiacenti, voglio sapere se sono collegati tra loro altri voxel.

Ad esempio (per illustrare la situazione in 2D), dove # è un quadrato pieno:

  1 2 3
a # # #
b # #
c # # #

Se scelgo a3 e c3, voglio determinare il più rapidamente possibile se sono collegati; se esiste un percorso tra a3 e c3 attraverso i pixel riempiti. (La situazione reale è in una griglia voxel 3D, ovviamente.)

Ho esaminato gli algoritmi di alluvione e gli algoritmi di ricerca del percorso, ma non sono sicuro di quale scegliere. Entrambi svolgono un lavoro non necessario: Flood fill cerca di riempire tutti i voxel, ma questo non è necessario. Gli algoritmi di ricerca del percorso di solito si occupano di trovare il percorso più breve, il che non è necessario. Ho solo bisogno di sapere se c'è un percorso.

Quale algoritmo dovrei usare?

Modifica: sulla base dei commenti, penso che dovrei aggiungere quanto segue: il contenuto dei voxel non è noto in anticipo e inoltre, l'algoritmo è necessario per rilevare se la rimozione (svuotamento) di un voxel causerebbe la rottura del gruppo di voxel in due o più gruppi più piccoli.


Nel tuo esempio un percorso valido da a3 a c3 sarebbe il seguente c3->c2->b2->a2->a3:?

questo è corretto
Bram Vaessen del

Risposte:


12

A * funzionerebbe bene. Trovare il percorso è quello che vuoi, trovare il percorso più breve è altrettanto veloce (o più veloce) che trovare qualsiasi percorso. In questa situazione, A * è probabilmente il più adatto dato che hai un punto iniziale e finale. questo significa che hai l'euristica aggiunta per accelerare la ricerca.

Con A * in genere il primo percorso che trovi è il più breve, quindi non sta facendo un lavoro extra dopo che ha già trovato un percorso.

inserisci qui la descrizione dell'immagine

Per alcune ottimizzazioni, controlla qui la mia risposta .


sembra che spari davvero in avanti fino a quando non colpisce quel muro poi si insinua
GameDev-er

1
@ GameDev-er Sì, è a causa dell'euristica. Se non ci fossero ostacoli sarebbe una ricerca molto veloce, quasi una linea retta.
MichaelHouse

Con un migliore ordinamento dei nodi, questo espanderebbe prima il percorso più vicino al nodo finale. Se si dispone di una struttura dati veloce per ordinare i nodi, ordinarli per distanza dalla destinazione per il percorso più diretto.
MichaelHouse

9

Se sei pronto a fare un po 'di pre-elaborazione e ad assorbire i costi di archiviazione, il partizionamento dei voxel in gruppi collegati in fase di costruzione fornisce una risposta ovvia a "c'è un percorso". Esiste un percorso tra due voxel se fanno parte dello stesso gruppo. Il problema ovviamente è che devi archiviare le informazioni sul gruppo da qualche parte, e ciò dipende dal layout dei tuoi dati. Se stai memorizzando un semplice elenco, puoi semplicemente suddividerlo in più elenchi, uno per ciascun gruppo spazialmente connesso. Se ti stai organizzando in un qualche tipo di BVH, probabilmente potresti ottenere alcune efficienze ragionevolmente buone se puoi dire "tutti i voxel in questo nodo e sotto appartengono al gruppo X".

In alternativa, è possibile effettuare un pre-partizionamento spaziale e memorizzare alcuni set più piccoli di voxel "hub" per ciascun gruppo collegato. Quindi è possibile trovare il percorso dalla sorgente e indirizzare i voxel al voxel hub più vicino, che dovrebbe essere molto più breve / economico per calcolare il percorso. Se riesci a trovare un percorso da un voxel a un voxel hub, allora voxel fa parte del gruppo del voxel hub. Con la selezione intelligente di quei voxel hub, è possibile ridurre al minimo il numero di attraversamenti del percorso. Ad esempio, una sfera potrebbe avere un solo voxel hub al centro, ma un gruppo lungo e sottile potrebbe avere un voxel hub ogni X voxel lungo la sua lunghezza. Se i voxel di origine e di destinazione si trovano alle estremità della lunghezza, devono solo cercare al massimo X voxel di trovare un hub e anche se potrebbe esserci un numero enorme di voxel tra l'inizio e la fine della lunghezza,

Tutto dipende da quanto siano patologici i tuoi gruppi voxel: se ti aspetti un numero enorme di piccoli gruppi disconnessi, l'aumento dei costi di archiviazione supererà enormemente il successo delle prestazioni del solo pathfinding. Se ti aspetti un numero relativamente limitato di gruppi collegati ma di topologie dispari, l'individuazione di percorsi ingenui potrebbe essere estremamente costosa e il costo di archiviazione e l'individuazione di percorsi minimi è un'opzione molto più economica.


1
Questa è la risposta giusta, ma per implementarla in modo efficiente, non dovrebbe essere memorizzata come un elenco. Aggiungi un puntatore a ogni voxel che punta al suo "voxel rappresentativo", che imposti utilizzando l'algoritmo union-find. Si tratta di un costo di archiviazione costante per voxel e sostanzialmente lineare nel numero di fronti per i costi di calcolo.
Neil G,

Idee interessanti, ma ci sono due cose che potrebbero complicare la situazione. Il primo è che il contenuto della griglia voxel non è noto in anticipo, quindi per creare voxel hub, avrei anche bisogno di un algoritmo in grado di determinare quali voxel dovrebbero essere hub.
Bram Vaessen,

1
Il secondo problema è che l'algoritmo è necessario subito dopo la rimozione di un voxel, per determinare se il gruppo di cui faceva parte è suddiviso in gruppi più piccoli a causa della rimozione di quel voxel.
Bram Vaessen,

@BramVaessen Se stai cercando tutte le relazioni di interconnessione a coppie - e in particolare, se i gruppi "si separano " - allora è una questione leggermente diversa dalla semplice raggiungibilità (sebbene la raggiungibilità sia il modo più semplice di procedere); Vorrei incoraggiare l'aggiunta di maggiori dettagli su ciò che stai cercando alla domanda originale, in quanto potrebbe consentire risposte migliori al "problema alla base della domanda".
Steven Stadnicki,

Per tenerlo pulito, ho posto il mio problema iniziale in una domanda diversa qui gamedev.stackexchange.com/questions/50953/…
Bram Vaessen

4

Non ho molta familiarità con i voxel, ma immagino che potresti ottenere prestazioni abbastanza buone usando un algoritmo di ricerca best-first come A *. Il problema con l'utilizzo di A * in questo caso è che quello euristico che normalmente userebbe è progettato per dare la priorità alla ricerca del percorso più breve e non solo a "qualsiasi percorso" il più rapidamente possibile.

Potresti avere un po 'di fortuna usando un euristico alternativo che espande un minor numero di nodi come

f (p) = g (p) + w (p) * h (p)

dove w> = 1. diminuisci il valore di 'w' più ti avvicini all'obiettivo, dando così una priorità maggiore al costo del percorso 'g' più ti avvicini al voxel che stai cercando.

Spero che questo possa essere d'aiuto!

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.