def show_hull(cname, ccol): ccoords = coords[names==cname] hull = ConvexHull(ccoords) xs = ccoords.ix[:,0] ys = ccoords.ix[:,1] zs = ccoords.ix[:,2] #ax.scatter(xs, ys, zs, c=ccol, marker='o') for simplex in hull.simplices: s = ccoords.irow(simplex) #print s sx = list(s.ix[:,0]) sy = list(s.ix[:,1]) sz = list(s.ix[:,2]) sx.append(sx[0]) sy.append(sy[0]) sz.append(sz[0]) ax.plot(sx, sy, sz, ccol, alpha=0.2) hulld = Delaunay(ccoords.irow(hull.vertices)) hulld.find_simplex(coords) hcol = ['grey' if x<0 else 'green' for x in hulld.find_simplex(coords)] hxs = coords.ix[:,0] hys = coords.ix[:,1] hzs = coords.ix[:,2] ax.scatter(hxs, hys, hzs, c=hcol, marker='o', alpha=0.2)
def zonotope_quadrature_rule(avmap, N, NX=10000): """ Description of zonotope_quadrature_rule Arguments: vert: W1: N: NX: (default=10000) Outputs: points: weights: """ vert = avmap.domain.vertY W1 = avmap.domain.subspaces.W1 # number of dimensions m, n = W1.shape # points y = np.vstack((vert, maximin_design(vert, N))) T = Delaunay(y) c = [] for t in T.simplices: c.append(np.mean(T.points[t], axis=0)) points = np.array(c) # approximate weights Y_samples = np.dot(np.random.uniform(-1.0, 1.0, size=(NX,m)), W1) I = T.find_simplex(Y_samples) weights = np.zeros((T.nsimplex, 1)) for i in range(T.nsimplex): weights[i] = np.sum(I==i) / float(NX) return points.reshape((T.nsimplex,n)), weights.reshape((T.nsimplex,1))
def _simplex_interp(self, teff, logg, fe, model_indecies): """ Perform barycentric interpolation on simplecies Args: teff (float): effective temperature logg (float): surface gravity fe (float): metalicity model_indecies (array): models to use in the interpolation Returns: array: spectrum at teff, logg, fe """ ndim = 3 model_table = np.array(self.model_table['teff logg fe'.split()]) points = model_table[model_indecies] tri = Delaunay(points) # Delaunay triangulation p = np.array([teff, logg, fe]) # cartesian coordinates simplex = tri.find_simplex(p) r = tri.transform[simplex,ndim,:] Tinv = tri.transform[simplex,:ndim,:ndim] c = Tinv.dot(p - r) c = np.hstack([c,1.0-c.sum()]) # barycentric coordinates # (3,many array) model_indecies_interp = model_indecies[tri.simplices[simplex]] model_spectra = self.model_spectra[model_indecies_interp,:] flux = np.dot(c,model_spectra) if simplex==-1: return np.ones_like(flux) return flux
def __init__(self, target_image_dimensions, target_vertices=None): self.target_image_dimensions = target_image_dimensions # if target vertices are not set, assume we want to fill the entire targetImage if not target_vertices: rows, columns = target_image_dimensions[:2] self.target_vertices = np.array([[0, 0], [0, columns], [rows, 0], [rows, columns]]) else: self.target_vertices = target_vertices r0, c0 = np.round(np.mean(self.target_vertices, axis=0)).astype(np.int32) self.target_vertices = np.array(sorted(self.target_vertices, key=lambda (r, c): np.arctan2(r0 - r, c0 - c))) # get barycentric coordinates and corresponding points in target (new) image nys = np.arange(self.target_image_dimensions[0]) nxs = np.arange(self.target_image_dimensions[1]) image_pixels = np.transpose([np.repeat(nys, len(nxs)), np.tile(nxs, len(nys))]) triangles = Delaunay(self.target_vertices) memberships = triangles.find_simplex(image_pixels) # returns the triangle that each pixel is a member of Ts = triangles.transform[memberships, :2] # transformation matrices prs = image_pixels - triangles.transform[memberships, 2] # intermediate transformation barycentric_coordinates = np.array([Ts[i].dot(pr) for i, pr in enumerate(prs)]) barycentric_coordinates = np.hstack((barycentric_coordinates, 1 - np.sum(barycentric_coordinates, axis=1, keepdims=True))) target_vertices_indices = triangles.simplices[memberships] self.targetRow = image_pixels[:, 0] self.targetCol = image_pixels[:, 1] self.barycentric = barycentric_coordinates self.indices = target_vertices_indices
def draw_dimension(self, dimNumber): ''' Method to draw the points on the axes using the current dimension number ''' self.ax.cla() dim0 = self.combinations[self.dimNumber][0] dim1 = self.combinations[self.dimNumber][1] self.ax.plot(self.points[:,dim0][self.inCluster], self.points[:, dim1][self.inCluster], 'g.') self.ax.plot(self.points[:, dim0][self.outsideCluster], self.points[:,dim1][self.outsideCluster], marker='.', color='0.8', linestyle='None') self.ax.set_xlabel('Dimension {}'.format(dim0)) self.ax.set_ylabel('Dimension {}'.format(dim1)) plt.title('press c to cut, < or > to switch dimensions') self.fig.canvas.draw() ''' Method to take the current points from mouse input, convert them to a convex hull, and then update the inCluster and outsideCluster attributes based on the points that fall within the hull''' if not isinstance(hull, Delaunay): hull=Delaunay(hull) self.inCluster = hull.find_simplex(points)>=0 self.outsideCluster=np.logical_not(self.inCluster)
def triangulate(self, size): shape = self.mImg.shape spacing = max(shape) / size sigma = spacing / 4 coords = self._get_distributed_points(spacing, sigma, include_corners = True) tri = Delaunay(coords) im_pts = self.get_xy_features() # pt_tri_membership becomes a map which is the same size as the # original image (first two dimensions only). each element contains # the triangle ID of that point in the source image pt_tri_membership = tri.find_simplex(im_pts.astype(dtype = np.double)) pt_tri_membership.resize(shape[0], shape[1]) num_tri = np.max(pt_tri_membership) tri_map = np.copy(self.mImg) # replace elements of each triangle with the mean value of the color # channels from the original image for tri in range(num_tri + 1): this_tri = pt_tri_membership == tri if not np.any(this_tri): continue for col in range(shape[2]): tri_map[this_tri, col] = np.mean(self.mImg[this_tri, col]) return tri_map
def inside_convex_poly(pts): """Returns a function that checks if inputs are inside the convex hull of polyhedron defined by pts Alternative method to check is to get faces of the convex hull, then check if each normal is pointed away from each point. As it turns out, this is vastly slower than using qhull's find_simplex, even though the simplex is not needed. """ tri = Delaunay(pts) return lambda x: tri.find_simplex(x) != -1
def chromaticity_diagram_visual( samples=256, cmfs='CIE 1931 2 Degree Standard Observer', transformation='CIE 1931', parent=None): """ Creates a chromaticity diagram visual based on :class:`colour_analysis.visuals.Primitive` class. Parameters ---------- samples : int, optional Inner samples count used to construct the chromaticity diagram triangulation. cmfs : unicode, optional Standard observer colour matching functions used for the chromaticity diagram boundaries. transformation : unicode, optional {'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'} Chromaticity diagram transformation. parent : Node, optional Parent of the chromaticity diagram in the `SceneGraph`. Returns ------- Primitive Chromaticity diagram visual. """ cmfs = get_cmfs(cmfs) illuminant = DEFAULT_PLOTTING_ILLUMINANT XYZ_to_ij = ( CHROMATICITY_DIAGRAM_TRANSFORMATIONS[transformation]['XYZ_to_ij']) ij_to_XYZ = ( CHROMATICITY_DIAGRAM_TRANSFORMATIONS[transformation]['ij_to_XYZ']) ij_c = XYZ_to_ij(cmfs.values, illuminant) triangulation = Delaunay(ij_c, qhull_options='QJ') samples = np.linspace(0, 1, samples) ii, jj = np.meshgrid(samples, samples) ij = tstack((ii, jj)) ij = np.vstack((ij_c, ij[triangulation.find_simplex(ij) > 0])) ij_p = np.hstack((ij, np.full((ij.shape[0], 1), 0))) triangulation = Delaunay(ij, qhull_options='QJ') RGB = normalise(XYZ_to_sRGB(ij_to_XYZ(ij, illuminant), illuminant), axis=-1) diagram = Primitive(vertices=ij_p, faces=triangulation.simplices, vertex_colours=RGB, parent=parent) return diagram
def interp_weights(xyz, uvw,d=3): tri = Delaunay(xyz) simplex = tri.find_simplex(uvw) vertices = np.take(tri.simplices, simplex, axis=0) temp = np.take(tri.transform, simplex, axis=0) delta = uvw - temp[:, d] bary = np.einsum('njk,nk->nj', temp[:, :d, :], delta) return vertices, np.hstack((bary, 1 - bary.sum(axis=1, keepdims=True)))
def check_polygon_membership(cluster_boundary, points_to_check): cluster_boundary_points = [[x[0], x[1]] for x in cluster_boundary] hull = cluster_boundary_points if not isinstance(hull, Delaunay): hull = Delaunay(hull) gps_coords_to_check = [[x[0], x[1]] for x in points_to_check] point_in_cluster = [] for coord in gps_coords_to_check: point_in_cluster.append(1 if hull.find_simplex(coord) >= 0 else 0) return point_in_cluster
def inside_hull(self, labels): """This method checks whether a requested set of labels is inside the convex hull of the training data. Returns a bool. This method relies on Delauynay Triangulation and is thus exceedlingly slow for large dimensionality. """ L = flatten_struct(self.training_labels, use_labels=self.used_labels) l = flatten_struct(labels, use_labels=self.used_labels) hull = Delaunay(L.T) return hull.find_simplex(l.T) >= 0
def cut_cluster(self, points, hull): ''' Method to take the current points from mouse input, convert them to a convex hull, and then update the inCluster and outsideCluster attributes based on the points that fall within the hull''' if not isinstance(hull, Delaunay): hull=Delaunay(hull) self.inCluster = hull.find_simplex(points)>=0 self.outsideCluster=np.logical_not(self.inCluster)
def in_hull(p, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed """ if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def zonotope_quadrature_rule(avmap, N, NX=10000): """Quadrature rule on a zonotope. Quadrature when the dimension of the active subspace is greater than 1 and the simulation parameter space is bounded. Parameters ---------- avmap : ActiveVariableMap a domains.ActiveVariableMap N : int the number of quadrature nodes in the active variables NX : int, optional the number of samples to use to estimate the quadrature weights (default 10000) Returns ------- Yp : ndarray quadrature nodes on the active variables Yw : ndarray quadrature weights on the active variables See Also -------- integrals.quadrature_rule """ vert = avmap.domain.vertY W1 = avmap.domain.subspaces.W1 # number of dimensions m, n = W1.shape # points y = np.vstack((vert, maximin_design(vert, N))) T = Delaunay(y) c = [] for t in T.simplices: c.append(np.mean(T.points[t], axis=0)) points = np.array(c) # approximate weights Y_samples = np.dot(np.random.uniform(-1.0, 1.0, size=(NX,m)), W1) I = T.find_simplex(Y_samples) weights = np.zeros((T.nsimplex, 1)) for i in range(T.nsimplex): weights[i] = np.sum(I==i) / float(NX) Yp, Yw = points.reshape((T.nsimplex,n)), weights.reshape((T.nsimplex,1)) return Yp, Yw
def in_hull(p, hull): """ :param p: (N, K) test points :param hull: (M, K) M corners of a box :return (N) bool """ try: if not isinstance(hull, Delaunay): hull = Delaunay(hull) flag = hull.find_simplex(p) >= 0 except scipy.spatial.qhull.QhullError: print('Warning: not a hull %s' % str(hull)) flag = np.zeros(p.shape[0], dtype=np.bool) return flag
def in_hull(p, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed It returns a boolean array where True values indicate points that lie in the given convex hull """ from scipy.spatial import Delaunay if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def in_hull(p, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed From: https://stackoverflow.com/questions/16750618/whats-an-efficient-way-to-find-if-a-point-lies-in-the-convex-hull-of-a-point-cl """ if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def inConvexHull(dictionary, mx, my): """ Check if (mx,my) point is in the data dictionary. """ import numpy from scipy.spatial import Delaunay pointlist = [] for k in dictionary.keys(): for ki in dictionary[k].keys(): pointlist.append([k, ki]) p = numpy.array(pointlist) dela = Delaunay(p) return dela.find_simplex((mx, my)) >= 0
def remove_c3k_inside(self): """Returns a boolean array of same length as secondary describing whether that element of secondary is outside the hull formed by primary """ c3k = self.training_labels['miles_id'] == 'c3k' miles = ~c3k L = flatten_struct(self.training_labels[miles], use_labels=self.used_labels) l = flatten_struct(self.training_labels[c3k], use_labels=self.used_labels) hull = Delaunay(L.T) inside = hull.find_simplex(l.T) >= 0 #inside = self.inside_hull(self.training_labels[c3k]) bad = self.training_indices[c3k][inside] self.leave_out(bad) return bad
def test_find_nn_triangles_point(): r"""Test find natural neighbors for a point function.""" x = list(range(10)) y = list(range(10)) gx, gy = np.meshgrid(x, y) pts = np.vstack([gx.ravel(), gy.ravel()]).T tri = Delaunay(pts) tri_match = tri.find_simplex([4.5, 4.5]) truth = [62, 63] nn = find_nn_triangles_point(tri, tri_match, [4.5, 4.5]) assert_array_almost_equal(truth, nn)
def points_to_volume_3D(data3d, points): """ Not fixed yet. Should be better then slice version """ # hack move one point in next slice to make non planar object points[0, 2] += 1 points[-1, 2] += -1 hull = Delaunay(points) X, Y, Z = np.mgrid[:data3d.shape[0], :data3d.shape[1], :data3d.shape[2]] grid = np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T simplex = hull.find_simplex(grid) fill = grid[simplex >= 0, :] fill = (fill[:, 0], fill[:, 1], fill[:, 2]) data3d[fill] = 1
def test_find_nn_triangles_point(): r"""Test find natural neighbors for a point function.""" x = list(range(10)) y = list(range(10)) gx, gy = np.meshgrid(x, y) pts = np.vstack([gx.ravel(), gy.ravel()]).T tri = Delaunay(pts) tri_match = tri.find_simplex([4.5, 4.5]) truth = [62, 63] nn = find_nn_triangles_point(tri, tri_match, [4.5, 4.5]) assert_array_almost_equal(truth, nn)
def in_convex_hull(p, hull): """ Test if points in `p` are in the convex hull :param: p: should be a `NxK` coordinates of `N` points in `K` dimensions hull: either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed :return: boolean True or False, whether the point is in the convex hull """ from scipy.spatial import Delaunay if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def recover_ASAP_weights_using_scipy_delaunay(Hull_vertices, data): ############## copy from https://codereview.stackexchange.com/questions/41024/faster-computation-of-barycentric-coordinates-for-many-points (Gareth Rees) start = time.time() # Compute Delaunay triangulation of points. tri = Delaunay(Hull_vertices) end = time.time() print "delaunay time: ", end - start CHUNK_SIZE = 1000 for i in range(len(data) / CHUNK_SIZE): if i % 1000 == 0: print i end1 = time.time() targets = data[i * CHUNK_SIZE:(i + 1) * CHUNK_SIZE] # Find the tetrahedron containing each target (or -1 if not found) tetrahedra = tri.find_simplex(targets, tol=1e-6) # print tetrahedra[tetrahedra==-1] # Affine transformation for tetrahedron containing each target X = tri.transform[tetrahedra, :data.shape[1]] # Offset of each target from the origin of its containing tetrahedron Y = targets - tri.transform[tetrahedra, data.shape[1]] # First three barycentric coordinates of each target in its tetrahedron. # The fourth coordinate would be 1 - b.sum(axis=1), but we don't need it. b = np.einsum('...jk,...k->...j', X, Y) barycoords = np.c_[b, 1 - b.sum(axis=1)] end2 = time.time() rows = np.repeat( np.arange(len(targets)).reshape((-1, 1)), len(tri.simplices[0]), 1).ravel() cols = tri.simplices[tetrahedra].ravel() vals = barycoords.ravel() weights_list = scipy.sparse.coo_matrix( (vals, (rows, cols)), shape=(len(targets), len(Hull_vertices))).tocsr() end3 = time.time()
def generate_cache(self, minX, maxX, minY, maxY): points = numpy.array( [self.length_transform([s.x, s.y]) for s in self.sensors]) tri = Delaunay(points) minX = self.floor(minX) maxX = self.floor(maxX) minY = self.floor(minY) maxY = self.floor(maxY) self.simplex_lookup = {} for x in numpy.mgrid[minX:maxX:self.grid_size()]: for y in numpy.mgrid[minY:maxY:self.grid_size()]: x = self.floor(x) y = self.floor(y) self.simplex_lookup[(x, y)] = tri.vertices[tri.find_simplex( [x, y])]
def feasible_illuminance(self, illuminance_transfer_matrix, num_points): from scipy.spatial import Delaunay max_illuminance = np.sum(illuminance_transfer_matrix, axis=1) illuminance_set = np.meshgrid(*[np.linspace(i, j, num_points) for i, j in zip(np.zeros((self.num_user, 1)), max_illuminance)]) for i in range(self.num_user): illuminance_set[i] = illuminance_set[i].reshape((illuminance_set[i].size, 1)) illuminance_set = np.hstack(illuminance_set) d = [] for num in range(2 ** self.num_LED): d.append(list(bin(num)[2:].zfill(self.num_LED))) d = np.array(d, dtype=float).T x = np.dot(illuminance_transfer_matrix, d).T hull = Delaunay(x) in_hull = hull.find_simplex(illuminance_set) >= 0 illuminance_set = illuminance_set[in_hull, :] return illuminance_set
def tri_add(ref, que, k): ref = ref.numpy() que = que.numpy() tri = Delaunay(ref) index_tri = tri.find_simplex(que) _three_point = ref[tri.simplices[index_tri]] reque = (que - tri.transform[index_tri][:, 2]) renen = tri.transform[index_tri][:, :2] weight2 = np.matmul(renen, reque[:, :, np.newaxis]).squeeze() weight1 = 1 - weight2.sum(axis=-1) weight = np.concatenate([weight2, weight1[:, np.newaxis]], axis=-1) return torch.tensor(weight).float(), torch.tensor( tri.simplices[index_tri]).long()
def in_hull(p, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed Courtesy Juh_ on StackOverFlow """ from scipy.spatial import Delaunay if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def triangle_weights(self, knearest, **params): """Triangulate the k-nearest models, then use the barycenter of the enclosing simplex to interpolate. """ inparams = np.array([params[p] for p in self.stellar_pars]) dtri = Delaunay(self.model_points[knearest, :]) triangle_ind = dtri.find_simplex(inparams) inds = dtri.simplices[triangle_ind, :] transform = dtri.transform[triangle_ind, :, :] Tinv = transform[:self.ndim, :] x_r = inparams - transform[self.ndim, :] bary = np.dot(Tinv, x_r) last = 1.0 - bary.sum() wghts = np.append(bary, last) oo = inds.argsort() return inds[oo], wghts[oo]
def triangle_weights(self, knearest, **params): """Triangulate the k-nearest models, then use the barycenter of the enclosing simplex to interpolate. """ inparams = np.array([params[p] for p in self.stellar_pars]) dtri = Delaunay(self.model_points[knearest, :]) triangle_ind = dtri.find_simplex(inparams) inds = dtri.simplices[triangle_ind, :] transform = dtri.transform[triangle_ind, :, :] Tinv = transform[:self.ndim, :] x_r = inparams - transform[self.ndim, :] bary = np.dot(Tinv, x_r) last = 1.0 - bary.sum() wghts = np.append(bary, last) oo = inds.argsort() return inds[oo], wghts[oo]
class DelaunayEnvironment(Environment): def __init__(self, points, area, labels): Environment.__init__(self) self.area = area self.area_hull = Delaunay(area) self.points = points self.regions = labels self.get_voronoi() self.build_color_map() self.build_reachable_set() def add_symmetric(self): sym = [] a = list(self.area) for u, v in zip(a, a[1:] + a[0:1]): d = (u - v) n = np.array([d[1], -d[0]]) n = n / np.linalg.norm(n) sym += [p - 2 * n * (np.dot(n, p - u)) for p in self.points] self.points = np.array(list(self.points) + sym) def get_voronoi(self): self.add_symmetric() vor = Voronoi(self.points) index_inside_vectrices = set([]) for i, v in enumerate(vor.vertices): if self.in_area(v): index_inside_vectrices.add(i) elements = [] for r in vor.regions: if r and set(r).issubset(index_inside_vectrices): elements.append(r) index_inside_vectrices = list(index_inside_vectrices) reindex = {n: i for i, n in enumerate(index_inside_vectrices)} vectrices = [vor.vertices[n] for n in index_inside_vectrices] elements = [tuple([reindex[n] for n in e]) for e in elements] self.elements = elements self.vectrices = vectrices def in_area(self, p): return self.area_hull.find_simplex(p) >= 0
def DLN_swap(self, src_image, dst_image, plot=False): check, points, shapes = self.landmarks_detection(src_image, plot=False) if not check: return None, None src_box_coordinates, src_features, src_cropped = self.bounding_box( src_image, shapes[0]) check, points, shapes = self.landmarks_detection(dst_image, plot=False) if not check: return None, None dst_box_coordinates, dst_features, dst_cropped = self.bounding_box( dst_image, shapes[0]) triangles = Delaunay(dst_features) dst_box = self.get_box(dst_features) box_inices = triangles.find_simplex(dst_box) warped_image = np.zeros( (dst_cropped.shape[0], dst_cropped.shape[1], 3), dtype=np.uint8) for tri_index, tri in enumerate(triangles.simplices): tri_area = dst_box[box_inices == tri_index] x, y = tri_area.T barycentric = self.Barycentric(tri, tri_area, src_features, dst_features) warped_image[y, x] = self.bilinear_interpolate( src_cropped, barycentric) if plot: self.save_image('warped', warped_image) blended_src_image = self.blending(dst_features, dst_cropped, warped_image) des_swaped_image = self.replace(dst_image, dst_box_coordinates, blended_src_image) if plot: # self.save_image('warped', warped_image) # self.save_image('blended', blended_src_image) self.save_image('tri_swaped_image', des_swaped_image) return True, des_swaped_image
class DelaunayEnvironment(Environment): def __init__(self,points,area,labels): Environment.__init__(self) self.area = area self.area_hull = Delaunay(area) self.points = points self.regions = labels self.get_voronoi() self.build_color_map() self.build_reachable_set() def add_symmetric(self): sym = [] a = list(self.area) for u,v in zip(a,a[1:]+a[0:1]): d = (u-v) n = np.array([d[1],-d[0]]) n = n/np.linalg.norm(n) sym += [p-2*n*(np.dot(n,p-u)) for p in self.points] self.points = np.array(list(self.points) + sym) def get_voronoi(self): self.add_symmetric() vor = Voronoi(self.points) index_inside_vectrices = set([]) for i,v in enumerate(vor.vertices): if self.in_area(v): index_inside_vectrices.add(i) elements = [] for r in vor.regions: if r and set(r).issubset(index_inside_vectrices): elements.append(r) index_inside_vectrices = list(index_inside_vectrices) reindex = {n:i for i,n in enumerate(index_inside_vectrices)} vectrices = [vor.vertices[n] for n in index_inside_vectrices] elements = [tuple([reindex[n] for n in e]) for e in elements] self.elements = elements self.vectrices = vectrices def in_area(self,p): return self.area_hull.find_simplex(p)>=0
def __call__(self, image): # make a von Neumann structring element to create the boundaries s = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) b = np.squeeze(image.astype('bool')) b_erode_outline = np.logical_xor( binary_erosion(b, iterations=1, structure=s), b) # make the sentinels b_dilate = binary_dilation(b, iterations=3, structure=s) b_dilate_outline = np.logical_xor( binary_erosion(b_dilate, iterations=1, structure=s), b_dilate) # add a perimeter of ones to make sentinel points for the boundaries b_erode = np.logical_xor(b_erode_outline, b_dilate_outline) # pre weight the mask using only the region surrounding the cells mask = np.logical_xor(b, b_dilate) # assign xy points to the boundary pixels, then a Delaunay triangulation x, y = np.where(b_erode) points = np.column_stack((x, y)) tri = Delaunay(points) self.tri = tri # find the pixels of the background free_space_x, free_space_y = np.where(np.logical_not(b)) free_space = np.array( list(zip(free_space_x.tolist(), free_space_y.tolist()))) # calculate the weight map simplices = tri.find_simplex(free_space) weight_map = np.zeros(image.shape) # mean? d = np.array( [np.max(self.edist(s, p)) for s, p in zip(simplices, free_space)]) weight_map[free_space_x, free_space_y] = d.reshape((-1, )) mask = b.astype('float32') weight_map = gaussian_filter(weight_map, 1.) #self.sigma) weight_map = self.w0 * (1. - mask) * np.exp( -(weight_map * weight_map) / (2. * self.sigma**2 + 1e-99)) weight_map = weight_map + 1. + mask return weight_map
def is_within_mesh_volume(points, mesh, tolerance=None): """ Returns if given points are within given mesh volume using Delaunay triangulation. Parameters ---------- points : array_like Points to check if they are within `mesh` volume. mesh : array_like Points of the volume used to generate the Delaunay triangulation. tolerance : numeric, optional Tolerance allowed in the inside-triangle check. Returns ------- bool Is within mesh volume. Notes ----- - This definition requires *scipy* to be installed. Examples -------- >>> mesh = np.array([[-1.0, -1.0, 1.0], ... [1.0, -1.0, 1.0], ... [1.0, -1.0, -1.0], ... [-1.0, -1.0, -1.0], ... [0.0, 1.0, 0.0]]) >>> is_within_mesh_volume(np.array([0.0005, 0.0031, 0.0010]), mesh) array(True, dtype=bool) >>> a = np.array([[0.0005, 0.0031, 0.0010], ... [0.3205, 0.4131, 0.5100]]) >>> is_within_mesh_volume(a, mesh) array([ True, False], dtype=bool) """ if is_scipy_installed(raise_exception=True): from scipy.spatial import Delaunay triangulation = Delaunay(mesh) simplex = triangulation.find_simplex(points, tol=tolerance) simplex = np.where(simplex >= 0, True, False) return simplex
def test_find_local_boundary(): r"""Test find edges of natural neighbor triangle group function.""" x = list(range(10)) y = list(range(10)) gx, gy = np.meshgrid(x, y) pts = np.vstack([gx.ravel(), gy.ravel()]).T tri = Delaunay(pts) tri_match = tri.find_simplex([4.5, 4.5]) nn = find_nn_triangles_point(tri, tri_match, [4.5, 4.5]) edges = find_local_boundary(tri, nn) truth = {(45, 55), (44, 45), (55, 54), (54, 44)} assert truth == set(edges)
def test_find_local_boundary(): r"""Test find edges of natural neighbor triangle group function.""" x = list(range(10)) y = list(range(10)) gx, gy = np.meshgrid(x, y) pts = np.vstack([gx.ravel(), gy.ravel()]).T tri = Delaunay(pts) tri_match = tri.find_simplex([4.5, 4.5]) nn = find_nn_triangles_point(tri, tri_match, [4.5, 4.5]) edges = find_local_boundary(tri, nn) truth = [(45, 55), (44, 45), (55, 54), (54, 44)] assert_array_almost_equal(truth, edges)
class Hull(object): def __init__(self, points): self.hull = ConvexHull(points) self.delaunay = Delaunay(points.irow(self.hull.vertices)) self.tris = [np.array([[x for x in self.hull.points[s[i]]] for i in range(3)]) for s in self.hull.simplices] def centroid(self): return self.delaunay.points.mean(0) def distance(self, xi): ds = [pointTriangleDistance(tri, xi)[0] for tri in self.tris] #return min(np.abs(self.delaunay.plane_distance(xi))) return min(ds) def contains(self, X): return self.delaunay.find_simplex(X)
def remove_c3k_inside(self): """Returns a boolean array of same length as secondary describing whether that element of secondary is outside the hull formed by primary """ c3k = self.training_labels['miles_id'] == 'c3k' miles = ~c3k L = flatten_struct(self.training_labels[miles], use_labels=self.used_labels) l = flatten_struct(self.training_labels[c3k], use_labels=self.used_labels) hull = Delaunay(L.T) inside = hull.find_simplex(l.T) >= 0 #inside = self.inside_hull(self.training_labels[c3k]) bad = self.training_indices[c3k][inside] self.leave_out(bad) return bad
def Interpolate(paneldata, x, y): cord = np.array([x,y]) n = len(paneldata) tri = Delaunay(paneldata) triangleindex = tri.find_simplex(cord) intercords = tri.simplices[triangleindex] index1 = np.empty(2) index2 = np.empty(2) index3 = np.empty(2) if triangleindex >= 0: index1[0] = intercords[0] index2[0] = intercords[1] index3[0] = intercords[2] x1 = tri.points[intercords[0]][0] y1 = tri.points[intercords[0]][1] x2 = tri.points[intercords[1]][0] y2 = tri.points[intercords[1]][1] x3 = tri.points[intercords[2]][0] y3 = tri.points[intercords[2]][1] index1[1] = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3)) index2[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3)) index3[1] = 1 - index1[1] - index2[1] else: index1[0] = -1 index1[1] = 10000000 index2[0] = -1 index2[1] = 10000000 index3[0] = 1 index3[1] = 0 distance = np.empty(n) for i in range(n): distance[i] = np.linalg.norm(np.subtract(cord, paneldata[i])) if distance[i] < index1[1]: index2[0] = index1[0] index2[1] = index1[1] index1[0] = i index1[1] = distance[i] elif distance[i] < index2[1]: index2[0] = i index2[1] = distance[i] base = index1[1] + index2[1] index1[1] /= base index2[1] /= base ans = np.array([index1, index2, index3]) return ans
def inhull(p, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed Source: http://stackoverflow.com/questions/16750618 """ from scipy.spatial import Delaunay if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def project(points, query_points, skip_nan=True): """ Project query points in the (x,y)-plane onto a triangulation in (x, y, z). This triangulation is determined by the Delaunay triangulation in the (x, y) plane. Returns: tri : Triangulation proj : Projection of query points onto the triangulation. Any points that fall outside the triangulation are set to Nan unless `skip_nan` is True. skip_nan : Remove nan-values from output. """ from scipy.spatial import Delaunay import warnings deltri = Delaunay(points[:, 0:2]) tris = deltri.find_simplex(query_points[:, 0:2]) proj = np.zeros((query_points.shape[0], 3)) tol = 1e-12 for i, tri in enumerate(tris): # Skip query points outside domain if tri == -1: proj[i, :] = query_points[i, :] continue tripoints = points[deltri.simplices[tri, :], :] n = normal(tripoints) # Determine z-coordinate for query point (x,y), where z lies on the # triangle `tri` qp = query_points[i, :] tp = tripoints[0, :] proj[i, 0:2] = qp[0:2] if abs(n[2]) < tol: warnings.warn('Triangle is near orthogonal to projection plane') proj[i, 2] = -(n[0] * (qp[0] - tp[0]) + n[1] * (qp[1] - tp[1])) / n[2] + tp[2] if skip_nan: proj = proj[~np.isnan(proj[:, 0]), :] return deltri.simplices.copy(), proj
class BarycentricInterp(object): """ Triangular barycentric interpolation class """ tri = None def __init__(self, xyin, xyout, **kwargs): self.__dict__.update(kwargs) # Triangulate the input if self.tri is None: self.tri = Delaunay(xyin) self.weights, self.verts, self.simplex = self._calc_weights(xyout) def __call__(self, z, xyout=None, mask=False): """ Perform the interpolation """ if xyout is not None: self.weights, self.verts = self._calc_weights(xyout) zout = (z[self.verts]*self.weights).sum(axis=1) if mask: zout[self.simplex==-1] = np.nan return zout def _calc_weights(self, xyout): # Find the simplex (i.e. the cell or polygon number) where each point lies s = self.tri.find_simplex(xyout) # Compute the barycentric coordinates (these are the weights) X = self.tri.transform[s,:2] Y = xyout - self.tri.transform[s,2] b = np.einsum('ijk,ik->ij', X, Y) weights = np.c_[b, 1 - b.sum(axis=1)] # These are the vertices of the output points verts = self.tri.simplices[s] return weights, verts, s
def determine_orbits_that_cross_cluster(self, method='scipy', return_cluster_time=False, verbose=True): """ :return: """ # number of time steps that the simulation was run for if verbose: print('Determining crossing orbits') n_steps = self.particle_pos.shape[0] n_parti = self.particle_pos.shape[1] # analyse every step self.final_inside_hull = np.full((n_steps, n_parti), False) for i_s in range(n_steps): if method is 'shapely': # VERSION1: implementation using shapley - works only in 2D # create an convex hull out of cluster members positions points_obj = MultiPoint(self.cluster_memb_pos[ i_s, :, :].tolist()) # conversion to preserve z coordinate hull_obj = points_obj.convex_hull # investigate which points are in the hull inside_hull = [ hull_obj.contains(Point(particle_coord.tolist())) for particle_coord in self.particle_pos[i_s, :, :] ] self.final_inside_hull[i_s, :] = np.array(inside_hull) else: # VERSION2: using scipy ConvexHull and Delaunay teseltation # determine convex hull vertices from members points idx_hull_vert = ConvexHull( self.cluster_memb_pos[i_s, :, :]).vertices # create a Delaunay grid based on given points delanuay_surf = Delaunay( self.cluster_memb_pos[i_s, :, :][idx_hull_vert]) inside_hull = delanuay_surf.find_simplex( self.particle_pos[i_s, :, :]) >= 0 self.final_inside_hull[i_s, :] = np.array(inside_hull) if return_cluster_time: return np.sum(self.final_inside_hull, axis=0) * np.abs( self.step_years) / 1e6 else: self.particle['time_in_cluster'] = np.sum( self.final_inside_hull, axis=0) * np.abs(self.step_years) / 1e6
def contains(self, points): """ Check if all the XYZ points are inside the camera field of view Parameters ---------- points: array_like List of XYZ points Returns ------- all_inside: bool True if all the points are inside the FOV. False otherwise. """ hull = ConvexHull(self.corners) triangulation = Delaunay(self.corners[hull.vertices]) all_inside = np.alltrue(triangulation.find_simplex(points)>=0) return all_inside
def is_within_3d_box(points, corners3d): """ Check whether a point is within bbox Args: points: (N, 3) corners3d: (M, 8, 3), corners of M bboxes. Returns: flag: (M, N), bool """ num_objects = len(corners3d) flag = [] for i in range(num_objects): hull = Delaunay(corners3d[i]) flag.append(hull.find_simplex(points) >= 0) flag = np.stack(flag, axis=0) return flag
def in_table(self, varname, TinHP, Vf): """ Return whether the (TinHP, Vf) pair of values is inside or outside the performance data table of the heatpump for the specified varname. COP or CAP values evaluated outside the data table (extrapolation) must be used with care. """ # Based on this stackoverflow answer: # http://stackoverflow.com/a/16898636/4481445 y = self._hpdb[self.model][varname] indx = np.where(~np.isnan(y))[0] x1 = self._hpdb[self.model]['EWT'][indx] x2 = self._hpdb[self.model]['GPM'][indx] hull = Delaunay(np.vstack((x1, x2)).T) return bool(hull.find_simplex((TinHP, Vf)) >= 0)
def in_hull(self, p, hull): """ Test if point `p` is in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed """ q = np.array([p]) if not isinstance(hull,Delaunay): try: hull = Delaunay(hull) except scipy.spatial.qhull.QhullError: return False return hull.find_simplex(q)>=0
def points_to_volume_slice(data3d, points, label): """ Only planar points can be used """ # hack move one point in next slice to make non planar object z = points[0, 2] points_sl = points[:, :2] hull = Delaunay(points_sl) X, Y = np.mgrid[:data3d.shape[0], :data3d.shape[1]] grid = np.vstack([X.ravel(), Y.ravel()]).T simplex = hull.find_simplex(grid) fill = grid[simplex >= 0, :] fill = (fill[:, 1], fill[:, 0]) # contours = np.zeros(data3d.shape, np.int8) # contours[fill] = 1 data_slice = data3d[:, :, z] data_slice[fill] = label
def _outside_hull(points, hull): """ Returns boolean mask denoting which of <N> points lie outside the convex hull defined by <M> vertices. Args: points (np.ndarray) - N x 2 hull (np.ndarray) - M x 2 Returns: outside (np.ndarray[bool]) - length N """ if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(points) >= 0
def is_within_mesh_volume(points: ArrayLike, mesh: ArrayLike, tolerance: Optional[Floating] = None) -> NDArray: """ Return whether given points are within given mesh volume using Delaunay triangulation. Parameters ---------- points Points to check if they are within ``mesh`` volume. mesh Points of the volume used to generate the Delaunay triangulation. tolerance Tolerance allowed in the inside-triangle check. Returns ------- :class:`numpy.ndarray` Whether given points are within given mesh volume. Examples -------- >>> mesh = np.array( ... [[-1.0, -1.0, 1.0], ... [1.0, -1.0, 1.0], ... [1.0, -1.0, -1.0], ... [-1.0, -1.0, -1.0], ... [0.0, 1.0, 0.0]] ... ) >>> is_within_mesh_volume(np.array([0.0005, 0.0031, 0.0010]), mesh) array(True, dtype=bool) >>> a = np.array([[0.0005, 0.0031, 0.0010], ... [0.3205, 0.4131, 0.5100]]) >>> is_within_mesh_volume(a, mesh) array([ True, False], dtype=bool) """ triangulation = Delaunay(mesh) simplex = triangulation.find_simplex(points, tol=tolerance) simplex = np.where(simplex >= 0, True, False) return simplex
def warp(self, im1_pts, im2_pts, tri): tri_index = tri.simplices tri_num = len(tri_index) ps_1 = np.zeros((self.img_height*self.img_width,3), np.float32) ps_2 = np.zeros((self.img_height*self.img_width,3), np.float32) for i in range(self.img_height): for j in range(self.img_width): ps_1[i*self.img_width+j][0] = j ps_1[i*self.img_width+j][1] = i ps_1[i*self.img_width+j][2] = 1 row_ind = Delaunay.find_simplex(tri,ps_1[:,0:2]) #transform matrix for i in range(tri_num): tf_1 = np.array([[im1_pts[tri_index[i][0]][0],im1_pts[tri_index[i][1]][0],im1_pts[tri_index[i][2]][0]],[im1_pts[tri_index[i][0]][1],im1_pts[tri_index[i][1]][1],im1_pts[tri_index[i][2]][1]],[1,1,1]]) tf_2 = np.array([[im2_pts[tri_index[i][0]][0],im2_pts[tri_index[i][1]][0],im2_pts[tri_index[i][2]][0]],[im2_pts[tri_index[i][0]][1],im2_pts[tri_index[i][1]][1],im2_pts[tri_index[i][2]][1]],[1,1,1]]) tf_warp = np.dot(tf_1,np.linalg.pinv(tf_2)) ps_2[row_ind==i,:] = np.dot(ps_1[row_ind==i,:],np.transpose(tf_warp)) self.mask_x = np.reshape(ps_2[:,0],(self.img_height,self.img_width)) self.mask_y = np.reshape(ps_2[:,1],(self.img_height,self.img_width))
def __init__(self, is_target, image_dimensions, vertices=None): self.image_dimensions = image_dimensions # if vertices are not set, assume we want to use the entire image if vertices is None: rows, columns = image_dimensions[:2] self.vertices = np.array([[0, 0], [0, columns - 1], [rows - 1, 0], [rows - 1, columns - 1]]) else: self.vertices = vertices.reshape((-1, 2)) r0, c0 = np.mean(self.vertices, axis=0).astype(np.int32) self.vertices = np.array(sorted(self.vertices, key=lambda (r, c): np.arctan2(r0 - r, c0 - c))) # get barycentric coordinates and corresponding points in target (new) image nys = np.arange(self.image_dimensions[0]) nxs = np.arange(self.image_dimensions[1]) image_pixels = np.transpose([np.repeat(nys, len(nxs)), np.tile(nxs, len(nys))]) image_pixels = np.array(image_pixels) triangles = Delaunay(self.vertices) # code below is abbout 0.01 s memberships = triangles.find_simplex(image_pixels) # returns the triangle that each pixel is a member of Ts = triangles.transform[memberships, :2] # transformation matrices prs = image_pixels - triangles.transform[memberships, 2] # intermediate transformation # code below is almost 1 s bl = Ts[:, 0, 0] * prs[:, 0] + Ts[:, 0, 1] * prs[:, 1] br = Ts[:, 1, 0] * prs[:, 0] + Ts[:, 1, 1] * prs[:, 1] barycentric_coordinates = np.hstack((bl.reshape((-1, 1)), br.reshape((-1, 1)))) barycentric_coordinates = np.hstack((barycentric_coordinates, 1 - np.sum(barycentric_coordinates, axis=1, keepdims=True))) target_vertices_indices = triangles.simplices[memberships] self.is_target = is_target self.rows = image_pixels[:, 0] self.cols = image_pixels[:, 1] self.barycentric = barycentric_coordinates self.indices = target_vertices_indices
def is_within_mesh_volume(points, mesh, tolerance=None): """ Returns if given points are within given mesh volume using Delaunay triangulation. Parameters ---------- points : array_like Points to check if they are within ``mesh`` volume. mesh : array_like Points of the volume used to generate the Delaunay triangulation. tolerance : numeric, optional Tolerance allowed in the inside-triangle check. Returns ------- bool Is within mesh volume. Examples -------- >>> mesh = np.array( ... [[-1.0, -1.0, 1.0], ... [1.0, -1.0, 1.0], ... [1.0, -1.0, -1.0], ... [-1.0, -1.0, -1.0], ... [0.0, 1.0, 0.0]] ... ) >>> is_within_mesh_volume(np.array([0.0005, 0.0031, 0.0010]), mesh) array(True, dtype=bool) >>> a = np.array([[0.0005, 0.0031, 0.0010], ... [0.3205, 0.4131, 0.5100]]) >>> is_within_mesh_volume(a, mesh) array([ True, False], dtype=bool) """ triangulation = Delaunay(mesh) simplex = triangulation.find_simplex(points, tol=tolerance) simplex = np.where(simplex >= 0, True, False) return simplex
def interpolate_csv(lon_pts, lat_pts, bathymetry, filename): data = np.genfromtxt(filename, delimiter=',') print(lon_pts.size, lat_pts.size) xmax = np.amax(data[:, 0]) xmin = np.amin(data[:, 0]) ymax = np.amax(data[:, 1]) ymin = np.amin(data[:, 1]) print(xmin, xmax, ymin, ymax) #lon_idx = np.where((lon_pts > xmin) & (lon_pts < xmax)) #lat_idx = np.where((lat_pts > ymin) & (lat_pts < ymax)) #idx = np.intersect1d(lon_idx, lat_idx) data_pts = np.vstack((data[:, 0], data[:, 1])).T #data_pts = np.vstack((data[:,1],data[:,0])).T print(data_pts) print(data_pts.shape) hull = Delaunay(data_pts) mesh_pts = np.vstack((lon_pts, lat_pts)).T print(mesh_pts) print(mesh_pts.shape) idx = np.where(hull.find_simplex(mesh_pts) >= 0) xpts = lon_pts[idx] ypts = lat_pts[idx] xy_pts = np.vstack((xpts, ypts)).T print(xy_pts) print(xy_pts.shape) #bathy = interpolate.NearestNDInterpolator((data[:,0],data[:,1]),data[:,2]) bathy = interpolate.LinearNDInterpolator((data[:, 0], data[:, 1]), data[:, 2]) #bathy = interpolate.LinearNDInterpolator((data[:,1],data[:,0]),data[:,2]) bathy_int = bathy(xy_pts) bathymetry[idx] = bathy_int return bathymetry
class Triangulate(object): def fit(self, x, y): self.trainX = x self.trainy = y self.tri = Delaunay(x, furthest_site=False) def predict(self, x): simps = self.tri.find_simplex(x) y = np.zeros((len(simps),2)) for i in range(len(simps)): s = simps[i] simp = self.tri.simplices[s] if s > -1: p = x.iloc[i, :] ap, bp, cp = tuple(tuple(self.trainX.iloc[j]) for j in simp) am, bm, cm = tuple(tuple(self.trainy.iloc[j]) for j in simp) mp = tuple(p) w = weights(ap, bp, cp, mp) y[i,:] = new_point((am, bm, cm), w) return y
def in_hull(points, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed """ # if not isinstance(hull,Delaunay): del points['flight_name'] del points['output'] del points['TEMPS'] del hull['flight_name'] del hull['output'] del hull['TEMPS'] hull = Delaunay(hull.as_matrix()) return hull.find_simplex(points.as_matrix())>=0
def cut_cluster(self, points, hull): ''' Method to take the current points from mouse input, convert them to a convex hull, and then update the inCluster and outsideCluster attributes based on the points that fall within the hull''' #If the hull is not already a Delaunay instance, make it one if not isinstance(hull, Delaunay): hull=Delaunay(hull) #Save the old cluster for undo self.oldInsideCluster=self.inCluster self.oldOutsideCluster=self.outsideCluster #Find the ponts that are inside the hull inHull = hull.find_simplex(points)>=0 #Only take the points that are inside the hull and the cluster #so we can cut from different angles and preserve old cuts newInsidePoints = self.inCluster & inHull self.inCluster = newInsidePoints self.outsideCluster = np.logical_not(self.inCluster)