Source code for compas.geometry.hull.hull_numpy


from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

from numpy import asarray
from scipy.spatial import ConvexHull


__all__ = [
    'convex_hull_numpy',
    'convex_hull_xy_numpy',
]


[docs]def convex_hull_numpy(points): """Compute the convex hull of a set of points. Parameters ---------- points : list XYZ coordinates of the points. Returns ------- tuple Indices of the points on the hull. Faces of the hull. Notes ----- The faces of the hull returned by this function do not necessarily have consistent cycle directions. To obtain a mesh with consistent cycle directions, construct a mesh from the returned vertices, this function should be used in combination with :func:`compas.topology.unify_cycles`. Examples -------- .. code-block:: python import random from compas.datastructures import Mesh from compas.geometry import distance_point_point from compas.geometry import convex_hull_numpy from compas.topology import unify_cycles from compas_viewers import MeshViewer radius = 5 origin = (0., 0., 0.) count = 0 points = [] while count < 10: x = (random.random() - 0.5) * radius * 2 y = (random.random() - 0.5) * radius * 2 z = (random.random() - 0.5) * radius * 2 pt = x, y, z if distance_point_point(origin, pt) <= radius: points.append(pt) count += 1 vertices, faces = convex_hull_numpy(points) i_index = {i: index for index, i in enumerate(vertices)} vertices = [points[index] for index in vertices] faces = [[i_index[i] for i in face] for face in faces] faces = unify_cycles(vertices, faces) mesh = Mesh.from_vertices_and_faces(vertices, faces) viewer = MeshViewer(mesh) viewer.setup() viewer.show() """ points = asarray(points) n, dim = points.shape assert 2 < dim, "The point coordinates should be at least 3D: %i" % dim points = points[:, :3] hull = ConvexHull(points) return hull.vertices, hull.simplices
[docs]def convex_hull_xy_numpy(points): """Compute the convex hull of a set of points in the XY plane. Warnings -------- This function requires Numpy ands Scipy. Parameters ---------- points : list XY(Z) coordinates of the points. Returns ------- list Indices of the points on the hull. list Faces of the hull. Notes ----- The faces of the hull returned by this function do not necessarily have consistent cycle directions. To obtain a mesh with consistent cycle directions, construct a mesh from the returned vertices, this function should be used in combination with :func:`compas.topology.unify_cycles`. Examples -------- .. code-block:: python # """ points = asarray(points) n, dim = points.shape assert 1 < dim, "The point coordinates should be at least 2D: %i" % dim points = points[:, :2] hull = ConvexHull(points) return hull.vertices, hull.simplices
# ============================================================================== # Main # ============================================================================== if __name__ == "__main__": import doctest doctest.testmod(globs=globals()) # # todo: distinguish between vertices of hull and internal vertices # import random # from compas.geometry import distance_point_point # from compas.datastructures import Mesh # from compas.datastructures import mesh_unify_cycles # from compas_viewers import MeshViewer # radius = 5 # origin = (0., 0., 0.) # count = 0 # points = [] # while count < 1000: # x = (random.random() - 0.5) * radius * 2 # y = (random.random() - 0.5) * radius * 2 # z = (random.random() - 0.5) * radius * 2 # pt = x, y, z # if distance_point_point(origin, pt) <= radius: # points.append(pt) # count += 1 # vertices, faces = convex_hull_numpy(points) # i_index = {i: index for index, i in enumerate(vertices)} # vertices = [points[index] for index in vertices] # faces = [[i_index[i] for i in face] for face in faces] # mesh = Mesh.from_vertices_and_faces(vertices, faces) # mesh_unify_cycles(mesh) # viewer = MeshViewer() # viewer.mesh = mesh # viewer.show()