def get_graph_from_geometry(geometry): # let's transform the geometry into lists of channel names and coordinates chans, coords = zip(*[(ch, xy) for ch, xy in geometry.iteritems()]) # we'll perform the triangulation and extract the try: tri = spatial.Delaunay(coords) except QhullError: # oh no! we probably have a linear geometry. chans, coords = list(chans), list(coords) x, y = zip(*coords) # let's add a dummy channel and try again coords.append((max(x) + 1, max(y) + 1)) tri = spatial.Delaunay(coords) # then build the list of edges from the triangulation indices, indptr = tri.vertex_neighbor_vertices edges = [] for k in range(indices.shape[0] - 1): for j in indptr[indices[k]:indices[k + 1]]: try: edges.append((chans[k], chans[j])) except IndexError: # let's ignore anything connected to the dummy channel pass return edges
def get_graph_from_geometry(geometry): # let's transform the geometry into lists of channel names and coordinates chans, coords = zip(*[(ch, xy) for ch, xy in geometry.iteritems()]) # we'll perform the triangulation and extract the try: tri = spatial.Delaunay(coords) except: x, y = zip(*coords) coords = list(coords) coords.append((max(x) + 1, max(y) + 1)) tri = spatial.Delaunay(coords) # then build the list of edges from the triangulation indices, indptr = tri.vertex_neighbor_vertices print indices, indptr edges = [] for k in range(indices.shape[0] - 1): for j in indptr[indices[k]:indices[k + 1]]: try: edges.append((chans[k], chans[j])) except IndexError: # ignore dummy site pass return edges
def is_in_hull( points: ArrayLike, hull: Union[ss.Delaunay, ss.ConvexHull, ArrayLike]) -> np.ndarray: """ test if points in `points` are in `hull` Parameters ---------- points: array_like, an `NxK` coordinates of `N` points in `K` dimensions hull: Delaunay object or ConvexHull object, or array_like, the objects which defines the hull, essentially an `MxK` array of the coordinates of `M` points in `K`dimensions Returns ------- ndarray of bool """ if isinstance(hull, ss.Delaunay): _h = hull elif isinstance(hull, ss.ConvexHull): _h = ss.Delaunay(hull.points) else: _h = ss.Delaunay(hull) return _h.find_simplex(points) >= 0
def estimate(self, src, dst): """Set the control points with which to perform the piecewise mapping. Number of source and destination coordinates must match. Parameters ---------- src : (N, 2) array Source coordinates. dst : (N, 2) array Destination coordinates. """ # forward piecewise affine # triangulate input positions into mesh self._tesselation = spatial.Delaunay(src) # find affine mapping from source positions to destination self.affines = [] for tri in self._tesselation.vertices: affine = AffineTransform() affine.estimate(src[tri, :], dst[tri, :]) self.affines.append(affine) # inverse piecewise affine # triangulate input positions into mesh self._inverse_tesselation = spatial.Delaunay(dst) # find affine mapping from source positions to destination self.inverse_affines = [] for tri in self._inverse_tesselation.vertices: affine = AffineTransform() affine.estimate(dst[tri, :], src[tri, :]) self.inverse_affines.append(affine)
def match_candidates_by_graph( images_ref: List[str], images_cand: List[str], exifs: Dict[str, Any], reference: geo.TopocentricConverter, rounds: int, ): """Find by triangulating the GPS points on X/Y axises""" if len(images_cand) == 0 or rounds < 1: return set() images_cand_set = set(images_cand) images_ref_set = set(images_ref) images = list(images_cand_set | images_ref_set) representative_points = get_representative_points(images, exifs, reference) points = np.zeros((len(images), 2)) for i, point in enumerate(representative_points.values()): points[i] = point[0:2] def produce_edges(triangles): for triangle in triangles: for vertex1, vertex2 in combinations(triangle, 2): image1, image2 = images[vertex1], images[vertex2] if image1 == image2: continue pair_way1 = image1 in images_cand_set and image2 in images_ref_set pair_way2 = image2 in images_cand_set and image1 in images_ref_set if pair_way1 or pair_way2: yield sorted_pair(image1, image2), (vertex1, vertex2) pairs = set() # first round compute scale based on edges (and push delaunay edges) edge_distances = [] triangles = spatial.Delaunay(points).simplices for (image1, image2), (vertex1, vertex2) in produce_edges(triangles): pairs.add((image1, image2)) edge_distances.append(norm_2d(points[vertex1] - points[vertex2])) scale = np.median(edge_distances) # further rounds produces edges from jittered version of the original points # in order to get 'alternative' delaunay triangulations : a perfect square # will only produce one diagonal edge, so by jittering it, we get more # chances of getting such diagonal edges and having more diversity for _ in range(rounds): points_current = copy.copy(points) + np.random.rand(*points.shape) * scale triangles = spatial.Delaunay(points_current).simplices for (image1, image2), _ in produce_edges(triangles): pairs.add((image1, image2)) return pairs
def evaluate(self, points, values, rpoints, method="linear"): if len(np.array(points).shape) == 1: self._dim = 1 points = points[:, np.newaxis] elif len(points.shape) == 2: self._dim = points.shape[1] else: raise ValueError("Points must be ndarray of shape (npoints,dim)") methods = ["nearest", "linear", "cubic"] if not method in methods: raise ValueError("Supported methods: {}".format( ", ".join(methods))) if method == "cubic" and self._dim > 2: raise ValueError( "Cubic interpolator only supported for 1D and 2D data") nanmask = ~np.isnan(values) if not np.array_equal(self._points, points) \ or self._method != method \ or not np.array_equal(self._nanmask, nanmask): self._kdtree = spatial.cKDTree(points) if self._dim == 1: self._triangulation = None elif method == "nearest": self._triangulation = None elif method == "linear": self._triangulation = spatial.Delaunay(points) elif method == "cubic": self._triangulation = spatial.Delaunay(points[nanmask]) self._points = points self._method = method self._nanmask = nanmask if method == "nearest": ivalues = self._nearest_interpolator(rpoints, values) elif method == "linear": lval = self._linear_interpolator(rpoints, values) mask = np.isnan(lval) if np.any(mask): lval[mask] = self._nearest_interpolator( [x[mask] for x in rpoints], values) ivalues = lval elif method == "cubic": cval = self._cubic_interpolator(rpoints, values) nval = self._nearest_interpolator(rpoints, values) cval[np.isnan(nval)] = np.nan ivalues = cval return np.squeeze(ivalues)
def getBlendedImage(self, alpha): trianglePoints = spatial.Delaunay(self.endPoints).vertices sourceTarget = np.zeros(self.startImage.shape, dtype=np.uint8) endTarget = np.zeros(self.endImage.shape, np.uint8) for vertices in trianglePoints: # ALL COORDINATES ARE IN X,Y sourceP1 = (self.startPoints[vertices[0]][0], self.startPoints[vertices[0]][1]) sourceP2 = (self.startPoints[vertices[1]][0], self.startPoints[vertices[1]][1]) sourceP3 = (self.startPoints[vertices[2]][0], self.startPoints[vertices[2]][1]) endP1 = (self.endPoints[vertices[0]][0], self.endPoints[vertices[0]][1]) endP2 = (self.endPoints[vertices[1]][0], self.endPoints[vertices[1]][1]) endP3 = (self.endPoints[vertices[2]][0], self.endPoints[vertices[2]][1]) destP1 = ((1 - alpha) * sourceP1[0] + alpha * endP1[0], (1 - alpha) * sourceP1[1] + alpha * endP1[1]) destP2 = ((1 - alpha) * sourceP2[0] + alpha * endP2[0], (1 - alpha) * sourceP2[1] + alpha * endP2[1]) destP3 = ((1 - alpha) * sourceP3[0] + alpha * endP3[0], (1 - alpha) * sourceP3[1] + alpha * endP3[1]) sourceAffine = Affine(np.array([sourceP1, sourceP2, sourceP3]), np.array([destP1, destP2, destP3])) sourceAffine.transform(self.startImage, sourceTarget) endAffine = Affine(np.array([endP1, endP2, endP3]), np.array([destP1, destP2, destP3])) endAffine.transform(self.endImage, endTarget) return np.array((1 - alpha) * sourceTarget + alpha * endTarget, dtype=np.uint8)
def alpha_shape_auto(xys, step=1, verbose=False): triangulation = spat.Delaunay(xys) triangles = xys[triangulation.simplices] a_pts = triangles[:, 0, :] b_pts = triangles[:, 1, :] c_pts = triangles[:, 2, :] radii = r_circumcircle_triangle(a_pts, b_pts, c_pts) radii[np.isnan(radii)] = 0 # "Line" triangles to be kept for sure del triangles, a_pts, b_pts, c_pts radii_sorted_i = radii.argsort() triangles = triangulation.simplices[radii_sorted_i][::-1] radii = radii[radii_sorted_i][::-1] geoms_prev = alpha_geoms((1 / radii.max()) - 1e-10, triangles, radii, xys) xys_bb = np.array([*xys.min(axis=0), *xys.max(axis=0)]) if verbose: print('Step set to %i' % step) for i in range(0, len(radii), step): radi = radii[i] alpha = (1 / radi) - 1e-100 if verbose: print('%.2f%% | Trying a = %f'\ %((i+1)/radii.shape[0], alpha)) geoms = alpha_geoms(alpha, triangles, radii, xys) if (geoms.shape[0] != 1) or not (np.all(xys_bb == geoms.total_bounds)): break else: geoms_prev = geoms return geoms_prev[0] # Return a shapely polygon
def generate_throats(self): r""" Generate the throats (connections, numbering and types) """ self._logger.info("generate_throats: Define connections between pores") Np = self._net.get_num_pores() pts = self._net.pore_properties['coords'] #Generate 6 dummy domains to pad onto each face of real domain #This prevents surface pores from making long range connections to each other Lx = self.domain_size[0] Ly = self.domain_size[1] Lz = self.domain_size[2] f = 0.1; #Scale factor for size of dummy domains ptsX0 = np.hstack((-np.random.rand(Np*f,1)*Lx*f, np.random.rand(Np*f,1)*Ly, np.random.rand(Np*f,1)*Lz)) ptsY0 = np.hstack((np.random.rand(Np*f,1)*Lx, -np.random.rand(Np*f,1)*Ly*f, np.random.rand(Np*f,1)*Lz)) ptsZ0 = np.hstack((np.random.rand(Np*f,1)*Lx, np.random.rand(Np*f,1)*Ly, -np.random.rand(Np*f,1)*Lz*f)) ptsXX = np.hstack((np.random.rand(Np*f,1)*Lx*f+Lx, np.random.rand(Np*f,1)*Ly, np.random.rand(Np*f,1)*Lz)) ptsYY = np.hstack((np.random.rand(Np*f,1)*Lx, np.random.rand(Np*f,1)*Ly*f+Ly, np.random.rand(Np*f,1)*Lz)) ptsZZ = np.hstack((np.random.rand(Np*f,1)*Lx, np.random.rand(Np*f,1)*Ly, np.random.rand(Np*f,1)*Lz*f+Lz)) #Add dummy domains to real domain pts = np.concatenate([pts,ptsX0,ptsXX,ptsY0,ptsYY,ptsZ0,ptsZZ]) #Perform tessellation Tri = sptl.Delaunay(pts) adjmat = sprs.lil_matrix((Np,Np),dtype=int) for i in np.arange(0,np.shape(Tri.simplices)[0]): #Keep only simplices that are fully in real domain adjmat[Tri.simplices[i][Tri.simplices[i]<Np],Tri.simplices[i][Tri.simplices[i]<Np]] = 1 #Remove duplicate (lower triangle) and self connections (diagonal) #and convert to coo adjmat = sprs.triu(adjmat,k=1,format="coo") self._net.throat_properties['connections'] = np.vstack((adjmat.row, adjmat.col)).T self._net.throat_properties['type'] = np.zeros_like(adjmat.row) self._net.throat_properties['numbering'] = np.arange(0,np.size(adjmat.row)) self._logger.debug("generate_throats: End of method")
def min_dist(point_list): """ Find the minimum distance between two points in a point list using Delaunay triangulation. """ # Find the Delaunay triangulation mesh = spatial.Delaunay(point_list) # Get the edges of the triangulation edges = np.vstack((mesh.simplices[:, :2], mesh.simplices[:, -2:])) # The x- and y- coordinates of the edges x = mesh.points[edges[:, 0]] y = mesh.points[edges[:, 1]] # Calculate the lengths of the Delaunay edges, which are candidates for minimum distance dists = np.sqrt(np.sum((x - y)**2, axis=1)) idx = np.argmin(dists) idx1, idx2 = edges[idx] p1, p2 = point_list[edges[idx]] print('The closest points are:') print('Index: {}, coordinates: {}'.format(idx1, tuple(p1))) print('Index: {}, coordinates: {}'.format(idx2, tuple(p2))) return np.min(dists)
def _compute_hull(self, qhull_options): """Compute properties of the convex hull and set up the outer hull. """ self.inside_vertices = self.in_hull(self.vor.vertices) self.hull_points = self._flatten_simplices(self.hull.convex_hull) self.hull_center = np.mean(self.hull.points[self.hull_points], axis=0) # enlarge hull: # estimate area needed for a poisson process with same mean distance: new_area = 4.0 * self.mean_nearest_distance**2 * self.vor.npoints fac = np.sqrt(new_area / self.hull_area()) self.outer_hull_points = np.zeros( (len(self.hull_points), self.vor.ndim)) for k, point in enumerate(self.hull.points[self.hull_points]): point -= self.hull_center point *= fac point += self.hull_center self.outer_hull_points[k] = point # compute outer hull: self.outer_hull = sp.Delaunay(self.outer_hull_points, furthest_site=False, incremental=False, qhull_options=qhull_options) self.outer_min_bound = np.min(self.outer_hull_points, axis=0) self.outer_max_bound = np.max(self.outer_hull_points, axis=0)
def _generate_mesh(self, env): # generate nodes, first node is the goal points = env._generate_points(self._sample_num - 2) points = np.concatenate(([[env._end.x, env._end.y], [env._start.x, env._start.y]], points)) while True: dist_list = np.array([Point(xy[0], xy[1]).distance(env.obstacles) for xy in points]) collision_mask = dist_list < 1e-5 collision_count = np.sum(collision_mask) if collision_count == 0: break # resample points[collision_mask] = env._generate_points(collision_count) self._samples = MultiPoint(points) # generate triangles tesselation = sps.Delaunay(points) triangles = tesselation.simplices.copy() edges = set() for tri in triangles: sortnodes = np.sort(tri) edges.add((sortnodes[0], sortnodes[1])) edges.add((sortnodes[1], sortnodes[2])) edges.add((sortnodes[0], sortnodes[2])) line_list = [] obstacle_union = unary_union(env.obstacles) for n1, n2 in edges: line = LineString([self._samples[n1], self._samples[n2]]) if line.intersection(obstacle_union).is_empty: line_list.append((n1, n2)) self._connections = line_list
def rectangle(cls, parent, height, width, pos_com=(0.,0.)): ''' Generate a rectangle of given height, width and center of mass. Parameters ---------- parent : :class:`~nngt.SpatialGraph` or subclass The parent container. height : float Height of the rectangle. width : float Width of the rectangle. pos_com : tuple of floats, optional (default: (0., 0.)) Position of the rectangle's center of mass Returns ------- shape : :class:`~nngt.Shape` Rectangle shape. ''' shape = cls(parent) half_diag = np.sqrt(np.square(height/2.) + np.square(width/2.)) / 2. pos_com = np.array(pos_com) points = [ pos_com + [half_diag,half_diag], pos_com + [half_diag,-half_diag], pos_com - [half_diag,half_diag], pos_com - [half_diag,-half_diag] ] shape._convex_hull = sptl.Delaunay(points) shape._com = pos_com shape._area = height * width return shape
def build_tri(self): """ Create a matplotlib triangulation object from the grid Used primarily to contour the data (but also for interpolation) """ if '_tri' not in self.__dict__: maxfaces = self.nfaces.max() if maxfaces == 3: self._tri = tri.Triangulation(self.xp, self.yp, self.cells) else: # Need to compute a delaunay triangulation for mixed meshes pts = np.vstack([self.xp, self.yp]).T D = spatial.Delaunay(pts) self._tri = tri.Triangulation(self.xp, self.yp, D.simplices) # Compute a mask by removing triangles outside of the polygon xy = D.points cells = D.simplices xv,yv = circumcenter(xy[cells[:,0],0],\ xy[cells[:,0],1],\ xy[cells[:,1],0],\ xy[cells[:,1],1],\ xy[cells[:,2],0],\ xy[cells[:,2],1]) mask = self.find_cell(xv, yv) self._tri.set_mask(mask == -1)
def _interp_functor(interpolator, xi, points, *points_props): points = np.array(points) points_props = tuple(map(np.array, points_props)) xi = tuple(map(np.array, xi)) delaunay = (spatial.Delaunay(points) if points.shape[1] >= 2 else Delaunay1D(points[:, 0])) simplex_map = delaunay.find_simplex(np.stack(xi, axis=-1)) simplex_outer_loc = np.unique(delaunay.convex_hull) simplex_outer_base = points[simplex_outer_loc] simplex_outer_args = tuple(arg[simplex_outer_loc] for arg in points_props) interp = (interpolator(xi, simplex_outer_base, *simplex_outer_args) if len(simplex_outer_loc) == points.shape[0] - 1 else np.full(xi[0].shape, np.nan)) for i, s in enumerate(delaunay.simplices): mask = simplex_map == i masked_xi = tuple(dim[mask] for dim in xi) simplex_base = points[s] simplex_args = tuple(arg[s] for arg in points_props) interp[mask] = interpolator(masked_xi, simplex_base, *simplex_args) return interp
def triangleRemoval(triangulation, heights, K): """ removes triangulation from the delaunay triangulation :param triangulation: delaunay triangulation object :param heights: 1d array of the heights of the triangle points :param K: number of triangles to keep :return: simplified triangulation using triangle removal method """ deleted_points = [] while triangulation.simplices.shape[0] > K: area = computeTriArea(triangulation) tri_to_delete = triangulation.simplices[np.argmin(area)] points_to_delete = tri_to_delete # indices of the points of the triangle we deleting deleted_points.append( np.hstack((np.take(triangulation.points, tri_to_delete, axis=0), np.take(heights, tri_to_delete, axis=0)))) # deleting the chosen points and their heights temp_points = np.delete(triangulation.points, [*points_to_delete], axis=0) heights = np.delete(heights, [*points_to_delete], axis=0) triangulation = spat.Delaunay(temp_points) print("number of triangles is ", triangulation.simplices.shape[0]) # progress indication return triangulation, heights, np.vstack(deleted_points)
def vertexRemoval(triangulation, heights, K): """ detects and removes a vertex from a given set of points. returns an updated delaunay triangulation :param triangulation: delaunay triangulation object :param heights: 1d array of the heights of the triangle points :param K: number of triangles to keep :return: simplified triangulation using vertex removal method """ deleted_points = [] while triangulation.simplices.shape[0] > K: area = computeTriArea(triangulation) tri_to_delete = triangulation.simplices[np.argmin(area)] points_to_delete = tri_to_delete[ 0] # indices of the points of the triangle we are deleting deleted_points.append( np.hstack((triangulation.points[points_to_delete], heights[points_to_delete]))) # deleting the chosen points and their heights temp_points = np.delete(triangulation.points, points_to_delete, axis=0) heights = np.delete(heights, points_to_delete, axis=0) triangulation = spat.Delaunay(temp_points) print("number of triangles is ", triangulation.simplices.shape[0]) # progress indication return triangulation, heights, np.vstack(deleted_points)
def _find_delaunay(df, parameters=None, call_num=None): method_key = get_method_key('neighbours') cutoff = get_param_val(parameters[method_key]['cutoff']) points = df[['x', 'y']].values particle_ids = df[['particle']].values.flatten() tess = sp.Delaunay(points) list_indices, point_indices = tess.vertex_neighbor_vertices # neighbour_ids = [particle_ids[point_indices[a:b].tolist()] for a, b in zip(list_indices[:-1], list_indices[1:])] neighbour_ids = [ point_indices[a:b].tolist() for a, b in zip(list_indices[:-1], list_indices[1:]) ] dist = sp.distance.squareform(sp.distance.pdist(points)) neighbour_dists = [(dist[i, row] < cutoff).tolist() for i, row in enumerate(neighbour_ids)] indices = [] for index, row in enumerate(neighbour_ids): indices.append([ particle_ids[neighbour_ids[index][j]] for j, dummy in enumerate(row) if neighbour_dists[index][j] ]) df.loc[:, ['neighbours']] = indices return df
def refine_by_delaunay(self, triangles): """refines given elements by the delaunay refinement method""" p = self.node_list t = self.face_list for tr in triangles: pmid = (p[t[tr][0]] + p[t[tr][1]] + p[t[tr][2]]) / 3 p = np.append(p, [pmid], axis=0) self.edge_length /= 2 dp = self.edge_length for i in range(1, int(ceil(1 / dp))): p = np.append(p, [[i * dp, 0]], axis=0) for i in range(int(ceil(.5 / dp))): p = np.append(p, [[1, i * dp]], axis=0) for i in range(int(ceil(.5 / dp))): p = np.append(p, [[1 - i * dp, .5]], axis=0) for i in range(int(ceil(.5 / dp))): p = np.append(p, [[.5, .5 + i * dp]], axis=0) for i in range(int(ceil(.5 / dp))): p = np.append(p, [[.5 - i * dp, 1]], axis=0) for i in range(int(ceil(1 / dp))): p = np.append(p, [[0, 1 - i * dp]], axis=0) p = unique2d(p) t = spspatial.Delaunay(p).vertices # remove triangles where centroid outside boundary (good enough...) pmid = p[t].sum(1) / 3 t = t[self.fd(pmid) < 1e-15] t = [Face(t[i]) for i in range(len(t))] self.node_list = p self.face_list = t
def delaunay(points, shape=[1, 1, 1]): r""" Generate a network based on Delaunay triangulation of random points Parameters ---------- points : array_like or int Can either be an N-by-3 array of point coordinates which will be used, or a scalar value indicating the number of points to generate shape : array_like Indicates the size and shape of the domain Returns ------- network : dict A dictionary containing 'vert.coords' and 'edge.conns' tri : Delaunay tessellation object The Delaunay tessellation object produced by ``scipy.spatial.Delaunay`` """ points = tools.parse_points(points=points, shape=shape) mask = ~np.all(points == 0, axis=0) tri = sptl.Delaunay(points=points[:, mask]) coo = tri_to_am(tri) d = {} d['vert.coords'] = points d['edge.conns'] = np.vstack((coo.row, coo.col)).T return d, tri
def make(self, key): density = 110000 # per cubic mm xyz = np.stack((design.Geometry.EPixel() & key).fetch('e_loc')) margin = 75 bounds_min = xyz.min(axis=0) - margin bounds_max = xyz.max(axis=0) + margin volume = (bounds_max - bounds_min).prod() * 1e-9 npoints = int(volume * density + 0.5) # generate random points that aren't too close min_distance = 10.0 # cells aren't not allowed any closer points = np.empty((npoints, 3), dtype='float32') replace = np.r_[:npoints] while replace.size: points[replace, :] = np.random.rand(replace.size, 3) * (bounds_max - bounds_min) + bounds_min replace = spatial.cKDTree(points).query_pairs(min_distance, output_type='ndarray')[:, 0] # eliminate points that are too distant inner = (spatial.Delaunay(xyz).find_simplex(points)) != -1 d, _ = spatial.cKDTree(points[inner, :]).query(points[~inner, :], distance_upper_bound=margin) points = np.vstack((points[inner, :], points[~inner, :][d < margin, :])) self.insert1(dict( key, margin=margin, density=density, npoints=points.shape[0], min_distance=min_distance, points=points, volume=spatial.ConvexHull(points).volume * 1e-9, inner_count=inner.sum()))
def DrawVoronoiTesselation(hdf5_file, frame=0): """ wanted structure: np.array([[3, 0], [4.2, 1], [0, 8], ...]) :return: """ x_gfp, y_gfp, x_rfp, y_rfp = GetXandYcoordinatesPerFrame(hdf5_file=hdf5_file, frame=frame) #x_gfp, y_gfp, x_rfp, y_rfp = ConvertXandYcoordinates(x_gfp, y_gfp, x_rfp, y_rfp) # Restructure so that you get a matrix; merge channels as the cell identity is not important in this case: points = [] for x, y in zip(x_gfp + x_rfp, y_gfp + y_rfp): points.append([x, y]) points = np.array(points) vor = sp.Voronoi(points) tri = sp.Delaunay(points) fig = sp.voronoi_plot_2d(vor) fig = sp.delaunay_plot_2d(tri) plt.grid(which='major') plt.show() plt.close() return vor, tri
def mkPlns(plnOr, org=[0, 0, 0], bxSdLen=1, scl=1, res=100, transp=0.5): edge = True smooth = True shader = 'shaded' glOpt = 'translucent' plnClr = [1, 0, 1, transp] # plnVert=np.array([list(itTl.product([0,1],repeat=3))])[0] if np.array_equal(plnOr, np.array([1, 1, 1])): plnVert = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) # plnFc= elif np.array_equal(plnOr, np.array([1, 1, 0])): plnVert = np.array([[1, 0, 0], [1, 1, 0], [0, 1, 1], [0, 0, 1]]) elif np.array_equal(plnOr, np.array([1, 0, 0])): plnVert = np.array([[1, 0, 0], [1, 1, 1], [1, 1, 0], [1, 0, 1]]) plnFc = spatial.Delaunay(plnVert) plnDat = gl.MeshData(vertexes=plnVert, faces=plnFc.convex_hull) plnObj = gl.GLSurfacePlotItem(plnVert, drawEdges=edge, smooth=smooth, color=(plnClr[0], plnClr[1], plnClr[2], plnClr[3]), shader=shader, glOptions=glOpt) plnObj.translate(org[0] + bxSdLen / 2, org[0] + bxSdLen / 2, org[0] + bxSdLen / 2) return plnObj
def voronoiVessels(nPoints=10): # Generate a bunch of points that pass the box extents slightly xyz = random.uniform(-1.2, 1.2, size=(nPoints, 3)) # Triangulate them dt = spatial.Delaunay(xyz) # Set of already traced edges (2x speedup) tracedEdges = set() solid = np.zeros((100, 100, 100), dtype=np.uint8) # Go throrough the tetrahedra for n, tet in enumerate(dt.vertices): print(n, dt.vertices.shape) for eTuple in itertools.permutations(tet, 2): # Sort the edge indices to make matches eList = list(eTuple) eList.sort() eRef = "%i-%i" % tuple(eList) # If we already traced this edge, skip it if eRef in tracedEdges: continue tracedEdges.add(eRef) # Dereference the points of interest idx1, idx2 = eList pt1 = xyz[idx1, :] pt2 = xyz[idx2, :] # Trace the line onto our list solid |= doLineSegment(pt1, pt2) return solid
def __init__(self, startImage, startPoints, endImage, endPoints): # Validate startImage input. if not isinstance(startImage, np.ndarray): raise TypeError("startImage must be a numpy array.") # Validate startPoints input. if not isinstance(startPoints, np.ndarray): raise TypeError("startPoints must be a numpy array.") # Validate endImage input. if not isinstance(endImage, np.ndarray): raise TypeError("endImage must be a numpy array.") # Validate endPoints input. if not isinstance(endPoints, np.ndarray): raise TypeError("endPoints must be a numpy array.") # Define triangulation. simplices = spatial.Delaunay(startPoints).simplices # Initialize blender data. self.startImage = startImage self.startPoints = startPoints self.endImage = endImage self.endPoints = endPoints self.simplices = simplices
def checkTriangles(self): if self.chkTriangles.isChecked(): if self.startPoints is not None and self.startPoints.shape[0] == self.endPoints.shape[0] and self.startPoints.shape[0] > 2: # Initialize triangle color and simplices. if self.hasPresetPoints and self.hasCustomPoints: pen = QPen(QtCore.Qt.cyan) elif self.hasPresetPoints: pen = QPen(QtCore.Qt.red) else: pen = QPen(QtCore.Qt.blue) self.simplices = spatial.Delaunay(self.startPoints).simplices for triangle in self.simplices: # Draw triangles in start. sTri = QPolygonF([QPointF(self.startPoints[triangle[0]][0], self.startPoints[triangle[0]][1]), QPointF(self.startPoints[triangle[1]][0], self.startPoints[triangle[1]][1]), QPointF(self.startPoints[triangle[2]][0], self.startPoints[triangle[2]][1])]) self.startScene.addPolygon(sTri, pen) # Draw triangles in end. dTri = QPolygonF([QPointF(self.endPoints[triangle[0]][0], self.endPoints[triangle[0]][1]), QPointF(self.endPoints[triangle[1]][0], self.endPoints[triangle[1]][1]), QPointF(self.endPoints[triangle[2]][0], self.endPoints[triangle[2]][1])]) self.endScene.addPolygon(dTri, pen) else: # Remove triangles from start. for item in self.startScene.items(): if type(item) is QGraphicsPolygonItem: self.startScene.removeItem(item) # Remove triangles from end. for item in self.endScene.items(): if type(item) is QGraphicsPolygonItem: self.endScene.removeItem(item)
def in_tetrahedron(self, t, p, true_interior=False): """Checks if the point P, pointed to by vector p, is inside(including the surface) the tetrahedron If 'p' is not guaranteed a true tetrahedron, use interior(). :param t: ndarray The four points of a tetrahedron :param p: ndarray The point to be tested for inclusion in the tetrahedron. :param true_interior: bool Activate to exclude the surface of the tetrahedron from the search. :return: Bool True if q is inside or on the surface of the tetrahedron. """ # If the surface is to be excluded, return False if p is on the surface. if true_interior and (self.in_triangle(np.delete(t, 0, 0), p) or self.in_triangle(np.delete(t, 1, 0), p) or self.in_triangle(np.delete(t, 2, 0), p) or self.in_triangle(np.delete(t, 3, 0), p)): return False # Check if 'p' is in the tetrahedron. hull = spatial.Delaunay( t) # Generate a convexHull representation of the points return hull.find_simplex(p) >= 0 # return True if 'p' is a vertex.
def avgIm3(im1, im2, im3, pts1, pts2, pts3): ''' compute the morph result of three images ''' imout = np.zeros(im1.shape, dtype=np.int) pts_avg = 1 / 3 * pts1 + 1 / 3 * pts2 + 1 / 3 * pts3 tri = spatial.Delaunay(pts_avg) tri_pts = pts_avg[tri.simplices] tri_pts1 = pts1[tri.simplices] tri_pts2 = pts2[tri.simplices] tri_pts3 = pts3[tri.simplices] for i in range(len(tri_pts)): transfrom1 = solveAffineTransform(tri_pts[i], tri_pts1[i]) transfrom2 = solveAffineTransform(tri_pts[i], tri_pts2[i]) transfrom3 = solveAffineTransform(tri_pts[i], tri_pts3[i]) insiders = wholePtsInTriangle(tri_pts[i]) for insider in insiders: inv1 = np.dot(transfrom1, insider) inv2 = np.dot(transfrom2, insider) inv3 = np.dot(transfrom3, insider) imout[insider[0]][insider[1]] = \ (1/3* computeBilinear(inv1, im1) + \ 1/3 * computeBilinear(inv2, im2) + \ 1/3 * computeBilinear(inv3, im3)).astype(int) return imout
def mkOctHdr(org=[0,0,0],bxSdLen=1,scl=1,transp=0.5): clr=[0, 1, 1, transp] edge=True smooth=True shader='shaded' glOpt='translucent' trOcth=np.array([list(itTl.permutations([0.25,0.5,0.75,1],4))])[0] norm4du=np.array([np.sqrt(2)/2, -np.sqrt(2)/2, 0, 0]) norm4dv=np.array([np.sqrt(6)/6, np.sqrt(6)/6, -np.sqrt(2/3), 0]) norm4dw=np.array([np.sqrt(12)/12, np.sqrt(12)/12, np.sqrt(12)/12, -np.sqrt(3)/2]) ocThVert=np.array([scl*(np.sum(np.multiply(trOcth,np.tile(norm4du, (trOcth.shape[0],1))),axis=1)+0.5+org[0]), scl*(np.sum(np.multiply(trOcth,np.tile(norm4dv, (trOcth.shape[0],1))),axis=1)+0.5+org[1]), scl*(np.sum(np.multiply(trOcth,np.tile(norm4dw, (trOcth.shape[0],1))),axis=1)+0.5+org[2])]).T ocThHull=spatial.Delaunay(ocThVert) ocThObj=gl.MeshData(vertexes=ocThVert,faces=ocThHull.convex_hull) ocGrObj=gl.GLMeshItem(meshdata=ocThObj, drawEdges=edge, smooth=smooth, color=(clr[0], clr[1], clr[2], clr[3]), shader=shader, glOptions=glOpt) ocGrObj.translate(-((bxSdLen/2)+org[0]), -((bxSdLen/2)+org[1]), -((bxSdLen/2)+org[2])) ocGrObj.rotate(55,1,0,0) ocGrObj.rotate(45,0,0,1) ocGrObj.translate(((bxSdLen/2)+org[0]), ((bxSdLen/2)+org[1]), ((bxSdLen/2)+org[2])) return ocGrObj
def obtain_boundary(trj): t0 = trj.index.get_level_values("time").unique().values[0] Delaunay = spa.Delaunay(trj.loc[idx[t0, :], :].values) boundary = list(np.unique(Delaunay.convex_hull.flatten())) boundary = list( trj.loc[idx[t0, :], :].index.get_level_values("id").values[boundary]) return boundary