Come ho trascorso una notevole quantità di tempo su questo, mi piacerebbe condividere la mia soluzione su come ottenere il Voronoi poligoni anziché solo i bordi.
Il codice è a https://gist.github.com/letmaik/8803860 e si estende sulla soluzione di tauran.
Innanzitutto, ho modificato il codice per fornirmi vertici e (coppie di) indici (= spigoli) separatamente, poiché molti calcoli possono essere semplificati quando si lavora su indici anziché coordinate punto.
Quindi, nel metodo voronoi_cell_lines
, determino quali bordi appartengono a quali celle. Per questo io uso la soluzione proposta di Alink da una domanda correlata. Cioè, per ogni spigolo trova i due punti di input più vicini (= celle) e crea una mappatura da quella.
L'ultimo passaggio consiste nel creare i poligoni effettivi (vedere metodo voronoi_polygons
).Innanzitutto, le celle esterne che hanno i bordi penzolanti devono essere chiuse. Questo è semplice come guardare attraverso tutti i bordi e verificare quali hanno solo un bordo vicino. Possono esserci zero o due di questi bordi. In caso di due, li collego introducendo un ulteriore margine.
Infine, i bordi non ordinati di ogni cella devono essere inseriti nell'ordine giusto per ricavarne un poligono.
L'utilizzo è:
P = np.random.random((100,2))
fig = plt.figure(figsize=(4.5,4.5))
axes = plt.subplot(1,1,1)
plt.axis([-0.05,1.05,-0.05,1.05])
vertices, lineIndices = voronoi(P)
cells = voronoi_cell_lines(P, vertices, lineIndices)
polys = voronoi_polygons(cells)
for pIdx, polyIndices in polys.items():
poly = vertices[np.asarray(polyIndices)]
p = matplotlib.patches.Polygon(poly, facecolor=np.random.rand(3,1))
axes.add_patch(p)
X,Y = P[:,0],P[:,1]
plt.scatter(X, Y, marker='.', zorder=2)
plt.axis([-0.05,1.05,-0.05,1.05])
plt.show()
cui uscite:
Il codice non è probabilmente adatto per un gran numero di punti di ingresso e può essere migliorata in alcune aree. Tuttavia, può essere utile per gli altri che hanno problemi simili.
torna di nuovo a questo, una risposta brillante, grazie mille! – EdwardAndo
+1. Grazie per questo codice. 'ncross2' prende' u' e 'v' sono argomenti, ma calcola un valore che dipende solo da' a' e 'b'. Forse 'a' e' b' dovrebbero essere sostituiti da 'u' e' v'? – unutbu
Trovare i bordi sull'infinito è piuttosto semplice usando l'attributo Convex_Hull. Posso postare il codice se lo desideri. – meawoppl