def voxel_matches_polygon(self, coordinate_list): for voxel_coords in coordinate_list: voxel_coords = np.asarray(voxel_coords) rmax = voxel_coords[:, 0].max() rmin = voxel_coords[:, 0].min() zmax = voxel_coords[:, 1].max() zmin = voxel_coords[:, 1].min() router = 1.5 * rmax rinner = 0.5 * rmin zupper = 1.5 * zmax if zmax > 0 else 0.5 * zmax zlower = 0.5 * zmin if zmin > 0 else 1.5 * zmin test_rs = np.linspace(rinner, router, int(100 * (router - rinner))) test_zs = np.linspace(zlower, zupper, int(100 * (zupper - zlower))) voxel_vertex_points = [Point2D(*v) for v in voxel_coords] voxel = AxisymmetricVoxel(voxel_vertex_points, parent=None, primitive_type='csg') polygon = Polygon(voxel_coords, closed=True) test_verts = list(itertools.product(test_rs, test_zs)) try: inside_poly = polygon.contains_points(test_verts) except AttributeError: # Polygon.contains_points was only introduced in Matplotlib 2.2. # Before that we need to convert to Path inside_poly = Path( polygon.get_verts()).contains_points(test_verts) inside_csg = [ any( child.contains(Point3D(r, 0, z)) for child in voxel.children) for (r, z) in test_verts ] self.assertSequenceEqual(inside_csg, inside_poly.tolist())
def voxel_matches_polygon(self, coordinate_list): for voxel_coords in coordinate_list: voxel_coords = np.asarray(voxel_coords) rmax = voxel_coords[:, 0].max() rmin = voxel_coords[:, 0].min() zmax = voxel_coords[:, 1].max() zmin = voxel_coords[:, 1].min() router = 1.5 * rmax rinner = 0.5 * rmin zupper = 1.5 * zmax if zmax > 0 else 0.5 * zmax zlower = 0.5 * zmin if zmin > 0 else 1.5 * zmin test_rs = np.linspace(rinner, router, int(50 * (router - rinner))) test_zs = np.linspace(zlower, zupper, int(50 * (zupper - zlower))) # Test for 0 area: not supported by mesh representation x, y = voxel_coords.T area = 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) if area == 0: continue voxel = AxisymmetricVoxel(voxel_coords, primitive_type='mesh') polygon = Polygon(voxel_coords, closed=True).get_path() test_verts = list(itertools.product(test_rs, test_zs)) inside_poly = polygon.contains_points(test_verts) inside_voxel = [any(child.contains(Point3D(r, 0, z)) for child in voxel.children) for (r, z) in test_verts] # Due to numerical precision, some points may be inside the # Matplotlib polygon but not the Mesh. Check in this case that the # "failing" points are just very close to the edge of the polygon fails = np.nonzero(np.not_equal(inside_voxel, inside_poly))[0] for fail in fails: if inside_voxel[fail] and not inside_poly[fail]: # Polygon should be made slightly bigger inside_poly[fail] = polygon.contains_point(test_verts[fail], radius=-0.01) elif inside_poly[fail] and not inside_voxel[fail]: # Polygon should be made slightly smaller inside_poly[fail] = polygon.contains_point(test_verts[fail], radius=0.01) self.assertSequenceEqual(inside_voxel, inside_poly.tolist(), "Failed for vertices {}".format(voxel_coords))
def _is_isolated(points, compare_id, event_region_coordinates, idx): if idx == 0: return True polygon = Polygon(event_region_coordinates) return not np.any(polygon.contains_points(points[:idx][compare_id[:idx] == compare_id[idx]]))