import numpy as np from scipy.spatial import ConvexHull from scipy.spatial import Delaunay import matplotlib.pyplot as plt np.random.seed(0) points = np.random.rand(30, 2) hull = ConvexHull(points) plt.plot(points[:,0], points[:,1], 'o') for simplex in hull.simplices: plt.plot(points[simplex, 0], points[simplex, 1], 'k-') point = np.array([ 0.01, 0.15 ]) plt.plot(point[0], point[1], 'o') hull = Delaunay(points) print(hull.find_simplex(point) >= 0) plt.show()
def create(self, k=5, r=40, sig1=8, sig2=13, p=2): """ Generate a Potential object with a 2D random potential. Args: **k (int)**: Determines the number of integers (k**2) to use to generate the convex hull that makes the blob. **r (float)**: The resolution size of the blob. **sig1 (float)**: The variance of the first Gaussian blur. **sig2 (float)**: The variance of the second Gaussian blur. **p (float)**: The exponent used to increase the contrast of the potential. Returns: An object of class Potential with a potential attribute and attributes corresponding to the parameters used to generate the potential. """ assert (k >= 2) & (k <= 7) assert (self.rescale_by_grid(r) < self.n_x) & (r > 0) assert sig1 > 0 assert sig2 > 0 assert p in [0.5, 1, 1.5, 2] # Create the n x n and n/2 x n/2 grids v = np.reshape(np.random.randint(low=0, high=2, size=16 * 16), newshape=(16, 16)) v = np.kron(v, np.ones((round(self.n_x / 16), round(self.n_y / 16)))) subgrid = np.reshape(np.random.randint(low=0, high=2, size=16 * 16), newshape=(16, 16)) subgrid = np.kron( subgrid, np.ones((round(self.n_x / 32), round(self.n_y / 32)))) # Center and diff the two grids lo_x = round(self.n_x / 4) hi_x = round(self.n_x / 4 * 3) lo_y = round(self.n_y / 4) hi_y = round(self.n_y / 4 * 3) v[lo_y:hi_y, lo_x:hi_x] = v[lo_y:hi_y, lo_x:hi_x] - subgrid # Run the first Gaussian blur v = gaussian_filter(v, sigma=sig1) # Create the convex hull from k**2 points points = np.random.rand(k**2, 2) * (self.rescale_by_grid(200)) points = points.astype(int) hull = ConvexHull(points) # Get the x and y points of the convex hull x = np.transpose(hull.points[hull.vertices])[0] x = np.append(x, x[0]) y = np.transpose(hull.points[hull.vertices])[1] y = np.append(y, y[0]) # Parameterize the boundary of the hull and interpolate t = np.arange(x.shape[0], dtype=float) t /= t[-1] nt = np.linspace(0, 1, 100) x = spline(t, x, nt) y = spline(t, y, nt) # Create a Delaunay hull for identifying points inside of the hull # The two args of np.zeros need to be scaled independently when n_x and n_y are allowed to vary # independently. hull = ConvexHull(np.transpose(np.array((x, y)))) hull = Delaunay(hull.points[hull.vertices]) coords = np.transpose( np.indices((round(self.rescale_by_grid(200)), round(self.rescale_by_grid(200))))) coords = coords.reshape(round(self.rescale_by_grid(200)**2), 2) in_hull = hull.find_simplex(coords) >= 0 # Rescale the blob # The two args of np.zeros need to be scaled independently when n_x and n_y are allowed to vary # independently. blob = np.zeros(shape=(round(self.rescale_by_grid(200)), round(self.rescale_by_grid(200)))) blob[np.transpose(coords[in_hull])[0], np.transpose(coords[in_hull])[1]] = 1 blob = ndimage.zoom( blob, self.rescale_by_grid(r) / self.rescale_by_grid(200)) # Create the final mask with the second Gaussian blur mask = np.zeros(shape=v.shape) x_offset = round((mask.shape[0] - blob.shape[0]) / 2) y_offset = round((mask.shape[1] - blob.shape[1]) / 2) mask[x_offset:blob.shape[0] + x_offset, y_offset:blob.shape[1] + y_offset] = blob mask = gaussian_filter(mask, sigma=sig2) v = np.abs(v) v = v**p v = v * mask v = np.max(v) - v + (1 - np.max(v)) params = dict(**self.params, **dict(potential=v, k=k, r=r, sig1=sig1, sig2=sig2, p=p)) return Potential(params=params)