def draw_voronoi(points_3d, pointsize=1): """ points_3d - (iter) - any iterable of numpy.ndarrays """ canvas = vpy.canvas(width=1280, height=720, background=vpy.vec(0.7,0.7,0.7)) draw_points(points_3d, color=vpy.vec(.3,.3,.8), radius=pointsize) vor = Voronoi(points_3d, incremental=False) if len(vor.vertices[0]) == 2: points = [] for point in vor.vertices: points.append(np.append(point, 0)) vor.vertices = points draw_points(vor.vertices, color=vpy.vec(.9,.5,0), radius=pointsize/2) draw_edges(vor, radius=pointsize/4)
num_region = len(region_index) file.writelines(str(num_region)) file.write("\n") for i in range(num_p): region_i = region_points[i] region_i = sortVertices(region_i) file.writelines(str(len(region_i))) file.write("\n") for j in range(len(region_i)): file.writelines(str(region_i[j][0]) + "\t" + str(region_i[j][1])) file.write("\n") file.close() # -> Visualization vor.vertices = np.round(vor.vertices, 2) new_vertices = vor.vertices[[check_in_bound(p, bound) for p in vor.vertices]] # plt.plot(new_vertices[:,0], new_vertices[:, 1], 'ko', ms=8) # # plt.plot(points[:,0], points[:, 1], 'go', ms=8) plt.plot(new_vertices[:, 0], new_vertices[:, 1], 'ko') plt.plot(points[:, 0], points[:, 1], 'go') for vpair in vor.ridge_vertices: if vpair[0] >= 0 and vpair[1] >= 0: v0 = vor.vertices[vpair[0]] v1 = vor.vertices[vpair[1]]
def finite_voronoi(vor, scale=1): """ finite_voronoi(vor, scale=1) Construct finite boundaries for Voronoi diagram. Parameters ---------- points : ndarray of floats, shape (npoints, 2) Coordinates of points to construct a convex hull from scale : float, optional Scale of extension lines. Some points may be outside their associated region if scale < 1 Attributes ---------- points : ndarray of double, shape (npoints, 2) Coordinates of input points. vertices : ndarray of double, shape (nvertices, 2) Coordinates of the Voronoi vertices. ridge_points : ndarray of ints, shape (nridges, 2) Indices of the points between which each Voronoi ridge lies. ridge_vertices : list of list of ints, shape (nridges, *) Indices of the Voronoi vertices forming each Voronoi ridge. regions : list of list of ints, shape (nregions, *) Indices of the Voronoi vertices forming each Voronoi region. point_region : list of ints, shape (npoints) Index of the Voronoi region for each input point. """ vor = Voronoi(points) # Calculate size of extension lines ptp_bound = vor.points.ptp(axis=0).max() * scale # Count number of new vertices required nv_existing = len(vor.vertices) nv_required = len([v for v in vor.ridge_vertices if v[0] < 0]) new_vertices = list(range(nv_existing, nv_existing + nv_required)) outer_vertices = [] center = vor.points.mean(axis=0) for idx, pointidx, simplex in zip(range(len(vor.ridge_points)), vor.ridge_points, vor.ridge_vertices): simplex = np.asarray(simplex) if np.any(simplex < 0): # Find finite end Voronoi vertex i = simplex[simplex >= 0][0] # Calculate tangent and normal t = vor.points[pointidx[1]] - vor.points[pointidx[0]] t /= np.linalg.norm(t) n = np.array([-t[1], t[0]]) # Draw line midpoint = vor.points[pointidx].mean(axis=0) direction = np.sign(np.dot(midpoint - center, n)) * n far_point = vor.vertices[i] + direction * ptp_bound outer_vertices.append(list(pointidx)) # Add start point to ridge vertices vor.ridge_vertices[idx][0] = len(vor.vertices) vor.vertices = np.vstack([vor.vertices, far_point]) # Assign points to outer vertices outer_points = list( set([item for sublist in outer_vertices for item in sublist])) for op in outer_points: p = [nv for nv, ov in zip(new_vertices, outer_vertices) if op in ov] vor.ridge_vertices = np.vstack([vor.ridge_vertices, p]) vor.ridge_points = np.vstack([vor.ridge_points, [op, -1]]) # Cycle through points for point_idx in range(len(vor.points)): region_idx = vor.point_region[point_idx] segs = vor.ridge_vertices[(vor.ridge_points == point_idx).any(axis=1)] # Remove first point from segment, to force correct direction segs[0, 0] = segs[0, 1] # Put segments in correct order for i in range(1, len(segs)): idx = np.where([np.any(np.in1d(segs[i - 1], s)) for s in segs[i:]])[0][-1] segs[i:] = np.roll(segs[i:], -idx, axis=0) # Extract vertices from segments pts = segs.flatten() _, i = np.unique(pts, return_index=True) vor.regions[region_idx] = pts[np.sort(i)] return vor