Creare poligoni di Thiessen (Voronoi) usando le linee (anziché i punti) come caratteristiche di input?


24

Ho un insieme di funzioni di linea all'interno di un particolare confine poligonale. Per ogni linea, vorrei generare un poligono all'interno del quale ogni possibile punto è più vicino alla linea data rispetto a qualsiasi altra linea nel livello. L'ho fatto in passato per le funzioni di input dei punti usando la triangolazione Delaunay, ma se esiste un processo simile per farlo con le funzioni di linea non sono riuscito a trovarlo.

ETA: la soluzione di Geogeek mi era venuta in mente, ma nelle sezioni più dritte in cui le linee di input hanno meno vertici, i poligoni risultanti si avvicinano troppo (anche se si sovrappongono) a una linea che non dovrebbero. Qui, le linee rosse sono i miei input, puoi vedere i vertici e i poligoni di Thiessen generati da loro.

inserisci qui la descrizione dell'immagine

Forse una soluzione rapida e (molto) sporca potrebbe essere quella di convertire ogni linea in un insieme abbondante di punti equidistanti (anziché solo i vertici della linea), generare poligoni di Thiessen da quelli, quindi dissolverli in base all'ID della linea di origine.


4
I diagrammi di Voronoi che includono segmenti di linea insieme a punti non sono composti da "poligoni"; piuttosto, le loro cellule hanno confini che possono includere porzioni di parabole. Per questo motivo, uno dei modi più efficienti e precisi per creare tessellazioni Voronoi è utilizzare una rappresentazione raster. ESRI chiama questa procedura allocazione euclidea .
whuber

Risposte:


11

Per illustrare una soluzione di elaborazione raster / immagine, ho iniziato con l'immagine pubblicata. È di qualità molto inferiore rispetto ai dati originali, a causa della sovrapposizione di punti blu, linee grigie, regioni colorate e testo; e l'ispessimento delle linee rosse originali. Come tale rappresenta una sfida: tuttavia, possiamo ancora ottenere celle Voronoi con elevata precisione.

Ho estratto le parti visibili delle caratteristiche lineari rosse sottraendo il verde dal canale rosso e quindi dilatando ed erodendo le parti più luminose di tre pixel. Questo è stato usato come base per un calcolo della distanza euclidea:

i = Import["http://i.stack.imgur.com/y8xlS.png"];
{r, g, b} = ColorSeparate[i];
string = With[{n = 3}, Erosion[Dilation[Binarize[ImageSubtract[r, g]], n], n]];
ReliefPlot[Reverse@ImageData@DistanceTransform[ColorNegate[string]]]

Trama in rilievo

(Tutto il codice mostrato qui è Mathematica 8.)

Identificare le "creste" evidenti - che devono includere tutti i punti che separano due celle Voronoi adiacenti - e ricombinarle con lo strato di linea fornisce la maggior parte di ciò che è necessario procedere:

ridges = Binarize[ColorNegate[
   LaplacianGaussianFilter[DistanceTransform[ColorNegate[string]], 2] // ImageAdjust], .65];
ColorCombine[{ridges, string}]

Immagini combinate

La banda rossa rappresenta ciò che ho potuto salvare della linea e la banda ciano mostra le creste nella trasformazione della distanza. (C'è ancora molta spazzatura a causa delle interruzioni nella stessa linea originale.) Queste creste devono essere pulite e chiuse attraverso un'ulteriore dilatazione - due pixel lo faranno - e quindi possiamo identificare le regioni connesse determinate da le linee originali e le creste tra loro (alcune delle quali devono essere esplicitamente ricombinate):

Dilation[MorphologicalComponents[
  ColorNegate[ImageAdd[ridges, Dilation[string, 2]]]] /. {2 -> 5, 8 -> 0, 4 -> 3} // Colorize, 2]

Ciò che ciò ha realizzato, in effetti, è identificare cinque caratteristiche lineari orientate . Possiamo vedere tre caratteristiche lineari separate che emanano da un punto di confluenza. Ognuno ha due lati. Ho considerato il lato destro delle due caratteristiche più a destra come le stesse, ma altrimenti ho distinto tutto il resto, dando le cinque caratteristiche. Le aree colorate mostrano il diagramma Voronoi di queste cinque caratteristiche.

Risultato

Un comando di allocazione euclidea basato su un livello che distingue le tre caratteristiche lineari (che non avevo disponibile per questa illustrazione) non distinguerebbe i diversi lati di ciascuna caratteristica lineare, e quindi unirebbe le regioni verde e arancione che fiancheggiano la linea più a sinistra ; dividerebbe in due la caratteristica verde acqua più a destra; e combinerebbe quei pezzi divisi con le corrispondenti caratteristiche beige e magenta sugli altri lati.

Evidentemente, questo approccio raster ha il potere di costruire tessellazioni Voronoi di caratteristiche arbitrarie - punti, pezzi lineari e persino poligoni, indipendentemente dalle loro forme - e può distinguere i lati delle caratteristiche lineari.


1
Una soluzione simile è illustrata su mathematica.stackexchange.com/questions/20696/… .
whuber

5

Penso che tu possa:

  • Converti vertici di linea in punti (line_points).
  • Crea poligoni voronoi usando i punti (line_points).
  • Sciogli i poligoni risultanti utilizzando un attributo id che è stato salvato dal livello linea o mediante un unione spaziale con il livello linea.

Spero di aver davvero capito la tua domanda, altrimenti puoi fornire un disegno per spiegare meglio le tue esigenze.


2
Penso che tu l'abbia capito, e quella soluzione mi è venuta in mente, ma ti imbatti in problemi in cui le linee hanno meno vertici. Aggiornerò la mia domanda con uno screenshot.
Dan C

3
Funzionerebbe bene se rendessi i punti più densi lungo la linea. Sebbene un approccio basato su raster (come menziona whuber nei commenti sulla domanda), sospetto che sarebbe molto più efficiente di così.
Andy W,
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.