oriented_bounding_box_numpy

compas.geometry.oriented_bounding_box_numpy(points, tol=None)[source]

Compute the oriented minimum bounding box of a set of points in 3D space.

Parameters:
pointsarray_like[point]

XYZ coordinates of the points.

tolfloat, optional

Tolerance for evaluating if the length of the local z-axis is (close to) zero. In that case, the points are essentially 2D and the minimum area rectangle is computed instead. Default is TOL.absolute

Returns:
list[[float, float, float]]

XYZ coordinates of 8 points defining a box.

Raises:
ValueError

If the input data is not 3D.

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.0)
True