oriented_bounding_box_numpy
- compas.geometry.oriented_bounding_box_numpy(points)[source]
Compute the oriented minimum bounding box of a set of points in 3D space.
- Parameters
points (array_like[point]) – XYZ coordinates of the points.
- Returns
list[[float, float, float]] – XYZ coordinates of 8 points defining a box.
- Raises
AssertionError – If the input data is 2D.
QhullError – If the data is essentially 2D.
Notes
The oriented (minimum) bounding box (OBB) of a given set of points is computed using the following procedure:
Compute the convex hull of the points.
For each of the faces on the hull:
Compute face frame.
Compute coordinates of other points in face frame.
Find “peak-to-peak” (PTP) values of point coordinates along local axes.
Compute volume of box formed with PTP values.
Select the box with the smallest volume.
Examples
Generate a random set of points with \(x \in [0, 10]\), \(y \in [0, 1]\) and \(z \in [0, 3]\). Add the corners of the box such that we now the volume is supposed to be \(30.0\).
>>> points = np.random.rand(10000, 3) >>> bottom = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]]) >>> top = np.array([[0.0, 0.0, 1.0], [1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [1.0, 1.0, 1.0]]) >>> points = np.concatenate((points, bottom, top)) >>> points[:, 0] *= 10 >>> points[:, 2] *= 3
Rotate the points around an arbitrary axis by an arbitrary angle.
>>> from compas.geometry import Rotation >>> from compas.geometry import transform_points_numpy >>> R = Rotation.from_axis_and_angle([1.0, 1.0, 0.0], 0.3 * 3.14159) >>> points = transform_points_numpy(points, R)
Compute the volume of the oriented bounding box.
>>> from compas.geometry import length_vector, subtract_vectors, close >>> bbox = oriented_bounding_box_numpy(points) >>> a = length_vector(subtract_vectors(bbox[1], bbox[0])) >>> b = length_vector(subtract_vectors(bbox[3], bbox[0])) >>> c = length_vector(subtract_vectors(bbox[4], bbox[0])) >>> close(a * b * c, 30.) True