Trovare in quali punti triangolari si trovano


16

Supponiamo che io abbia una mesh 2D costituita da triangoli non sovrapposti e una serie di punti { p i } M i = 1N k{Tk}k=1N. Qual è il modo migliore per determinare in quale triangolo si trova ciascuno dei punti?{pi}i=1Mk=1NTK

Ad esempio, nella seguente immagine abbiamo , p 2T 4 , p 3T 2 , quindi vorrei una funzione f che restituisca l'elenco f ( p 1 , p 2 , p 3 ) = [ 2 ,p1T2p2T4p3T2f .f(p1,p2,p3)=[2,4,2]

inserisci qui la descrizione dell'immagine

Matlab ha la funzione pointlocation che fa quello che voglio per le mesh Delaunay, ma fallisce per le mesh generali.

Il mio primo (muto) pensiero è, per tutti i nodi , scorrere tutti i triangoli per scoprire quale triangolo p i è in Tuttavia, questo è è estremamente inefficiente -. Potrebbe essere necessario scorrere ogni triangolo per ogni punto, in modo da potrebbe richiedere O ( N M ) lavoro.pipiO(NM)

Il mio prossimo pensiero è, per tutti i punti , trovare la maglia nodo di via di ricerca più vicino-vicino più prossimo, quindi guardare attraverso triangoli collegati a quel nodo più vicino. In questo caso, il lavoro sarebbe O ( a M l o g ( N ) ) , dove a è il numero massimo di triangoli collegati a qualsiasi nodo della mesh. Ci sono un paio di problemi risolvibili ma fastidiosi con questo approccio,piO(aMlog(N))a

  • Richiede l'implementazione di un'efficace ricerca del vicino più vicino (o la ricerca di una libreria che lo possiede), che potrebbe essere un'attività non banale.
  • Richiede la memorizzazione di un elenco di quali triangoli sono collegati a ciascun nodo, per il quale il mio codice non è attualmente impostato - in questo momento c'è solo un elenco di coordinate del nodo e un elenco di elementi.

Nel complesso sembra inelegante e penso che dovrebbe esserci un modo migliore. Questo deve essere un problema che sorge molto, quindi mi chiedevo se qualcuno potesse raccomandare il modo migliore per avvicinarsi alla ricerca dei triangoli in cui si trovano i nodi, teoricamente o in termini di librerie disponibili.

Grazie!

Risposte:


16

Il solito metodo randomizzato di salto dei bordi dovrebbe funzionare. Fondamentalmente, inizia con qualsiasi triangolo della mesh, quindi determina quale dei bordi il punto target si trova sul lato opposto di. Cioè, determinare quale dei bordi, quando esteso ad una linea, separa il punto dall'interno del triangolo. Quando ci sono due possibilità, scegline una a caso, considera il triangolo adiacente a quel bordo condiviso e ripeti. La randomizzazione dovrebbe far convergere questo metodo con probabilità 1 per triangolazioni Delaunay e non riesco a pensare a un motivo per cui non funzionerebbe per triangolazioni arbitrarie.

Modifica : dovrei aggiungere che il salto dei bordi dovrebbe essere con una costante ragionevole per un singolo punto, quindi sarebbe O ( M log N ) per MO(logN)O(MlogN)M puntiTuttavia, se ordini i punti per località (come utilizzando prima un ordinamento della curva di Hilbert), puoi inizializzare ogni nuova query con il triangolo della query precedente, per ridurre ulteriormente il runtime (non sono un teorico CS quindi posso ' ti dico quale sarebbe il big-O).

Modifica2 : trovato questo PDF descrive un tale schema "ambulante" che è garantito per terminare e rivede gli approcci più ingenui.

Un'altra alternativa all'utilizzo dei quadrifogli è l'uso della gerarchia triangolare. Vedi Olivier Devillers. Triangolazione Delaunay incrementale randomizzata migliorata. Nel Proc. 14 ° Annu. ACM Sympos. Comput. Geom., Pagine 106-115, 1998. Funziona meglio con le triangolazioni di Delaunay, ma può funzionare anche con non-Delaunay.

Fondamentalmente qualsiasi cosa tu faccia per accelerare la posizione del punto, sarà necessario costruire una struttura di dati ausiliari. Nel caso di quadrifogli o di qualche altra suddivisione spaziale, è necessario costruire l'albero di suddivisione. Nel caso del salto dei bordi, è necessario costruire il triangolo adiacente alla struttura topologica. La gerarchia della triangolazione richiede anche la costruzione di un albero di triangolazioni più grossolane.


Victor: conosci qualche codice open source che impedisce l'approccio edge-hopping? Sembra che potrebbe essere un'ottima soluzione per il mio caso. (modello di tracciamento delle particelle guidato dai campi correnti in una griglia mesh traingualr) -Grazie
Chris Barker,

Ho un codice per questo e posso inviarlo a te; è in C / C ++. Non ho ancora avuto il tempo di ripulirlo e pubblicarlo su Github. Ho dovuto scriverlo almeno due volte nella mia vita, una volta con una struttura di dati halfedge, di nuovo con un quadedge, ma può essere facilmente utilizzato quando questi non sono disponibili e devi costruire tu stesso una struttura topologica. Cerca sulla pagina del mio profilo il mio sito Web, dove puoi trovare le informazioni di contatto. Possiamo discuterne ulteriormente offline.
Victor Liu,

Sono quasi finito di implementarlo in matlab usando l'ordinamento della curva di Hilbert e la camminata triangolare randomizzata. È un codice di ricerca: non ottimizzato, non documentato, ecc., Ma comunque abbastanza veloce - posso darti il ​​codice se sei interessato.
Nick Alger,

2
Informazioni su: "" "Il salto dei bordi dovrebbe essere O (logN)" "" Non lo vedo. Ad esempio, nel caso patologico di una grande striscia triangolare lunga (come un canale stretto solo su un triangolo largo), nel caso peggiore, dovresti saltare da un triangolo all'altro fino alla fine. Nel caso medio, a metà strada. Quindi se raddoppi il numero di triangoli, sarebbe O (N) Nel caso più normale di una disposizione quadrata di triangoli, mi aspetterei O (sqrt (N)). Oppure mi sfugge qualcosa? -Chris
Chris Barker il

@Chris - Benvenuto in scicomp! Come parte delle pulizie di Scicomp, ho migrato le tue risposte e la conseguente conversazione come commenti sulla risposta di Victor. Non vediamo l'ora della tua partecipazione al sito.
Aron Ahmadia,

8

Non sono convinto che la tua soluzione sia effettivamente corretta. Considera la situazione in cui hai questi nodi:

  • A: (-3, 1)
  • B: (0, 2)
  • C: (3, 1)
  • D: (0, -5)

Ci sono triangoli ABC e ACD. Ora B è il punto più vicino all'origine, ma l'origine è nel triangolo ACD, che non contiene B.

O(NM), ma in genere sarà più veloce, soprattutto per le triangolazioni di Delaunay e triangolazioni vicine a quella in un certo senso.

Vorrei prendere in considerazione l'opzione di costruire un quadrifoglio che contenga i triangoli stessi. Cioè, hai un albero quaternario che memorizza in ciascun nodo (che corrisponde a un rettangolo di selezione):

  • Le coordinate alle quali viene suddiviso il riquadro o, in alternativa, i riquadri di delimitazione dei quattro sottotitoli;
  • Puntatori ai sottotitoli;
  • L'insieme di triangoli che rientrano completamente nel riquadro di delimitazione di questo rettangolo, ma non completamente in nessuno dei quattro sottotitoli. In altre parole, i triangoli che si intersecano con uno qualsiasi dei due segmenti di linea di suddivisione del quadrifoglio.

Quando viene assegnato un punto P, attraversa tutti i nodi sul percorso dalla radice del quadrifoglio alla casella più piccola contenente P. Dovrai esaminare tutti i triangoli che incontri in quei nodi. Per una triangolazione "ben educata", dovrebbe esserci solo qualcosa di similen triangoli che devono essere esaminati a livello di un nodo che contiene n triangoli nella sua sottostruttura e la profondità dovrebbe essere limitata da logn. Per una triangolazione "mal condotta", potresti ottenere ilO(NM) opera.


Hmm hai ragione. D'altra parte, se la triangolazione fosse Delaunay, penso che il vicino più vicino funzionerebbe. È troppo restrittivo per quello che sto cercando di fare, ma nel caso di Delaunay considera il doppio diagramma Voronoi: le celle Voronoi sono l'insieme di punti più vicini a un nodo e i bordi dei triangoli delaunay incontrano tutti i bordi del Voronoi celle ad angolo retto, quindi qualsiasi punto deve trovarsi in un triangolo collegato al nodo più vicino. Mi chiedo se è così che funziona la funzione pointLocation di matlab sotto il cofano ..?
Nick Alger,

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.