it-swarm.it

Esiste un algoritmo efficiente per generare uno scafo concavo 2D?

Avendo una serie di punti (2D) da un file GIS (una mappa della città), ho bisogno di generare il poligono che definisce il 'contorno' per quella mappa (il suo confine). I suoi parametri di input sarebbero i punti impostati e una "lunghezza massima del bordo". Emetterebbe quindi il poligono corrispondente (probabilmente non convesso).

La soluzione migliore che ho trovato finora è stata quella di generare i triangoli di Delaunay e quindi rimuovere i bordi esterni che sono più lunghi della lunghezza massima del bordo. Dopo che tutti i bordi esterni sono più corti, rimuovo semplicemente i bordi interni e ottengo il poligono che voglio. Il problema è che questo richiede molto tempo e mi chiedo se c'è un modo migliore.

59
Fabio Ceconello

Questo paper discute il Generazione efficiente di poligoni semplici per caratterizzare la forma di un insieme di punti nel piano e fornisce l'algoritmo. C'è anche un'applet Java che utilizza lo stesso algoritmo qui .

2
Amirali

Uno degli ex studenti del nostro laboratorio ha utilizzato alcune tecniche applicabili per la sua tesi di dottorato. Credo che uno di loro si chiami "forme alfa" e sia indicato nel seguente articolo:

http://www.cis.rit.edu/people/faculty/kerekes/pdfs/AIPR_2007_Gurram.pdf

Quel documento fornisce ulteriori riferimenti che puoi seguire.

10
nsanders

La risposta potrebbe essere ancora interessante per qualcun altro: si può applicare una variazione di dell'algoritmo della marching square , applicato (1) all'interno dello scafo concavo, e (2) quindi on (es. 3) different scale che dipende dalla densità media dei punti. Le scale devono essere int moltiplicate l'una con l'altra, in modo da creare una griglia che puoi usare per un campionamento efficiente. Ciò consente di trovare rapidamente campioni vuoti = quadrati, campioni che si trovano completamente all'interno di un "cluster/nuvola" di punti e quelli che si trovano nel mezzo. Quest'ultima categoria può quindi essere utilizzata per determinare facilmente la polilinea che rappresenta una parte dello scafo concavo.

Tutto è lineare in questo approccio, non è necessaria alcuna triangolazione, non usa forme alfa ed è diverso dall'offerta commerciale/brevettata come descritto qui ( http://www.concavehull.com/ )

2
monnoo

I ragazzi qui affermano di aver sviluppato un k vicini più vicini si avvicinano per determinare lo scafo concavo di un insieme di punti che si comporta "quasi linearmente sul numero di punti". Purtroppo la loro carta sembra essere molto ben custodita e dovrete chiedere loro per questo.

Ecco un buon set di riferimenti che include quanto sopra e potrebbe portare a trovare un approccio migliore.

2
Vinko Vrsalovic

L'SDK interattivo di Bing Maps V8 ha un'opzione di scafo concavo all'interno delle operazioni di forma avanzate.

https://www.bing.com/mapspreview/sdkrelease/mapcontrol/isdk/advancedshapeoperations?toWww=1&redig=D53FACBB1A00423195C53D841EA0D14E#JS

All'interno di ArcGIS 10.5.1, l'estensione Analista 3D ha uno strumento Volume limite minimo con i tipi di geometria dello scafo concavo, sfera, busta o scafo convesso. Può essere utilizzato a qualsiasi livello di licenza.

C'è un algoritmo di scafo concavo qui: https://github.com/mapbox/concaveman

1
Jaybird64

Una soluzione semplice è quella di camminare attorno al bordo del poligono. Dato un Edge attuale o i punti di collegamento al contorno P0 e P1, il punto successivo sul confine P2 sarà il punto con la A più piccola possibile, dove

H01 = bearing from P0 to P1
H12 = bearing from P1 to P2
A = fmod( H12-H01+360, 360 )
|P2-P1| <= MaxEdgeLength

Quindi si imposta

P0 <- P1
P1 <- P2

e ripetere fino a tornare dove hai iniziato.

Questo è ancora O (N ^ 2), quindi dovrai ordinare un po 'la tua lista di punti. È possibile limitare l'insieme di punti che è necessario considerare a ogni iterazione se si ordinano punti, ad esempio, il loro rilevamento dal centroide della città.

1
Mike F

Puoi farlo in QGIS con questo plug-in; https://github.com/detlevn/QGIS-ConcaveHull-Plugin

A seconda di come ne hai bisogno per interagire con i tuoi dati, probabilmente vale la pena controllare come è stato fatto qui.

1
Cameron

Buona domanda! Non l'ho ancora provato, ma il mio primo scatto sarebbe stato questo metodo iterativo:

  1. Crea un set N ("non contenuto") e aggiungi tutti i punti del tuo set a N.
  2. Scegli 3 punti da N a caso per formare un poligono iniziale P. Rimuovili da N.
  3. Usa qualche algoritmo point-in-polygon e guarda i punti in N. Per ogni punto in N, se ora è contenuto in P, rimuovilo da N. Non appena trovi un punto in N che è ancora non contenuto in P, vai al passaggio 4. Se N diventa vuoto, hai finito.
  4. Chiama il punto che hai trovato A. Trova la linea in P più vicina ad A e aggiungi A nel mezzo.
  5. Torna al passaggio 3

Penso che funzionerebbe finché funzionerà abbastanza bene - una buona euristica per i tuoi primi 3 punti potrebbe essere d'aiuto.

In bocca al lupo!

1
Rob Dickerson

Come riferimento sfrenato, PostGIS inizia con un convogliatore e poi lo scava, puoi vederlo qui.

https://github.com/postgis/postgis/blob/380583da73227ca1a52da0e0b3413b92ae69af9d/postgis/postgis.sql.in#L5819

0
Evan Carroll

Una rapida soluzione approssimativa (utile anche per gli scafi convessi) consiste nel trovare i limiti nord e sud per ciascun piccolo elemento est-ovest.

Sulla base della quantità di dettagli che si desidera, creare una matrice di dimensioni fisse di limiti superiore/inferiore. Per ogni punto calcolare quale colonna E-W è presente e aggiornare i limiti superiore/inferiore per quella colonna. Dopo aver elaborato tutti i punti, è possibile interpolare i punti superiore/inferiore per le colonne mancanti.

Vale anche la pena fare un rapido controllo in anticipo per forme sottili molto lunghe e decidere se bin NS o Ew.

0
Martin Beckett