Skip to content

Bounding Volumes

packingcubes.bounding_box

Bounding boxes and related objects and classes

Classes:

  • BoundingVolume

    Abstract, convex 3D shape for computing containment tests.

  • BoundingBox

    BoundingVolume in the shape of a box (rectangular prism)

  • BoundingSphere

    A BoundingVolume in the shape of a sphere

BoundingVolume

Abstract, convex 3D shape for computing containment tests.

bounding_box

bounding_box()

Return a BoundingBox for this volume

Returns:

  • BoundingBox

    A BoundingBox instance that completely encloses this volume

check_box_overlap

check_box_overlap(obox)

Return the "overlap" between this volume and obox

Define pxyz as the closest point to our center on the obox We'll define the "overlap" as

  • 0 if none of the obox vertices nor pxyz are contained within self
  • 1-7 if some but not all of the vertices or pxyz are contained within self
  • 8 if all of the vertices are contained within self (pxyz must then be contained within self by definition)

Parameters:

Returns:

  • overlap ( int ) –

    The amount of overlap as defined above

contains

contains(xyz)

Check if points are inside volume

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test. (3,) arrays will be converted

Returns:

  • NDArray[bool_]

    Boolean array where True means point is inside volume

See Also

contains_pointlist, count_inside

contains_point

contains_point(x, y, z)

Check if point is inside volume

Parameters:

  • x (float) –

    3D coordinates of the point

  • y (float) –

    3D coordinates of the point

  • z (float) –

    3D coordinates of the point

Returns:

  • bool

    True if point is inside volume

See Also

contains_pointlist, count_inside

contains_pointlist

contains_pointlist(xyz)

Check if points are inside box

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test.

Returns:

  • NDArray[bool_]

    Boolean array where True means point is inside volumen

See Also

contains_point, count_inside

count_inside

count_inside(xyz)

Return a count of how many points in xyz are inside the volume

Prefer this function to sum(contains_pointlist) or similar to prevent unnecessary array creation.

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test.

Returns:

  • count ( int ) –

    The count of points that are inside this volume

See Also

contains_point, contains_pointlist

BoundingBox

BoundingBox(box)

Bases: BoundingVolume

BoundingVolume in the shape of a box (rectangular prism)

The data for this box is stored as (6,) float array, in the form [x, y, z, dx, dy, dz], where x/y/z are the coordinates of the front-bottom-left corner, and dx/y/z is the width/depth/height.

This is the main workhorse BoundingVolume implementation and performance of the various methods is essential.

dx property

dx

Return the width of this box

dy property

dy

Return the depth of this box

dz property

dz

Return the height of this box

position property

position

Return the position of the front-bottom-left corner

size property

size

Return the three size parameters of this box

x property

x

Return the x-coordinate of the front-bottom-left corner

y property

y

Return the y-coordinate of the front-bottom-left corner

z property

z

Return the z-coordinate of the front-bottom-left corner

__str__

__str__()

Return a string with information about this box

bounding_box

bounding_box()

Return the BoundingBox for this bounding box (a copy of self)

check_box_overlap

check_box_overlap(obox)

Return the "overlap" between this box and obox

Define pxyz as the closest point to our center on the obox

We'll define the "overlap" as

  • 0 if none of the obox vertices nor pxyz are contained within self,
  • 1-7 if some but not all of the vertices or pxyz are contained within self,
  • 8 if all of the vertices are contained within self (pxyz must then be contained within self by definition)

Parameters:

Returns:

  • overlap ( int ) –

    The amount of overlap as defined above

clip_to_box

clip_to_box(obox)

Clip this box so it entirely fits within obox

Note

This action is potentially unsafe! We do no checking that the new box is correct in terms of floating point precision.

Parameters:

Returns:

  • int

    Returns 0 if any of the dx terms are 0, 1 otherwise

contains

contains(xyz)

Check if points are inside box

Performance Note

Prefer using contains_point or contains_pointlist for performance reasons

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test. (3,) arrays will be converted

Returns:

  • in_box ( NDArray[bool_] ) –

    Boolean array where True means point is inside box

contains_point

contains_point(x, y, z)

Check if point is inside box

Parameters:

  • x (float) –

    3D coordinates of the point

  • y (float) –

    3D coordinates of the point

  • z (float) –

    3D coordinates of the point

Returns:

  • in_box ( bool ) –

    True if point is inside box

See Also

contains_pointlist, count_inside

contains_pointlist

contains_pointlist(xyz)

Check if points are inside box

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test.

Returns:

  • in_box ( NDArray[bool_] ) –

    Boolean array where True means point is inside box

See Also

contains_point, [count_inside]]][count_inside]

copy

copy()

Return a deep copy of this bounding box

count_inside

count_inside(xyz)

Return a count of how many points in xyz are inside the box

Prefer this function to sum(contains_pointlist) or similar to prevent unnecessary array creation.

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test.

Returns:

  • count ( int ) –

    The count of points that are inside this box

See Also

contains_point, contains_pointlist

get_box_center

get_box_center()

Return the coordinates of the center of the box

get_box_vertex

get_box_vertex(index, jitter=0)

Return the coordinates of the vertex at z-order index (1-based)

Note that a jitter can be applied. If so the coordinates will be the vertex of the box slightly (1%) smaller (larger) if jitter is positive (negative)

Parameters:

  • index (int) –

    Z-order (1-based) index of vertex

  • jitter (float, default: 0 ) –

    Jitter direction. Default 0 (no jitter)

Returns:

  • vertex ( ndarray ) –

    (3,) numpy array corresponding to the specified vertex

get_box_vertices

get_box_vertices(jitter=0)

Return the coordinates of the 8 box vertices in z-order

Note that a jitter can be applied. If so the coordinates will be the vertices of the box slightly (1%) smaller (larger) if jitter is positive (negative)

Parameters:

  • jitter (float, default: 0 ) –

    Jitter direction. Default 0 (no jitter)

Returns:

  • vertices ( ndarray ) –

    (6,3) numpy array corresponding to the box vertices in z-order

get_child_box

get_child_box(ind)

Get indth (0-indexed) new child box of current box

New child box is defined as the suboctant described by position ind with size (box[3]/2, box[4]/2, box[5]/2). The child box is not currently guaranteed to be a proper BoundingBox

Parameters:

  • ind (int) –

    Z-order index (0-indexed) of child box (i.e. 0<=ind<=7)

Returns:

  • child_box ( BoundingBox ) –

    A box half the size at the corresponding position

get_neighbor_boxes

get_neighbor_boxes()

Return the 26 boxes that would be the neighbors of this box in a uniform grid

Boxes are returned as a 26x6 array, where each row is a box. Order is z-order, so row 0 is the box at [x-dx,y-dy,z-dz], row 2 is [x+dx,y-dy,z-dz] and row 25 is [x+dx,y+dy,z+dz]

max_depth

max_depth()

Get max depth supported by this box

Max depth is defined as the maximum number of times this box can be split in half before x[i] + dx[i] == x[i].

midplane

midplane()

Return the 3 coordinates specifying the center of the box

normalize_to_box

normalize_to_box(coordinates)

Rescale and shift the coordinates to be bounded by the unit cube

project_point_on_box

project_point_on_box(xyz, jitter=0)

Return coordinates of projection of (x, y, z) on nearest box face.

This is the closest point on the box to (x, y, z). Can provide jitter to place point into/out of the box for determining sub-boxes.

Note: There is no checking for whether points are already inside box

Note: Jitter is not applied to points inside the box (so a point cannot be jittered out).

Parameters:

  • xyz (NDArray) –

    Point to project onto nearest box face. Expected to be shape (3,)

  • jitter (float, default: 0 ) –

    Flag to move projected point 1% into the box. Negative values to move the point out of the box are not yet supported. Default is 0

Returns:

  • pxyz ( ndarray ) –

    Projected coordinates

BoundingSphere

BoundingSphere(center, radius)

Bases: BoundingVolume

A BoundingVolume in the shape of a sphere

bounding_box

bounding_box()

Return a BoundingBox that would contain this sphere

check_box_overlap

check_box_overlap(obox)

Return the "overlap" between this box and obox

Define pxyz as the closest point to our center on the obox We'll define the "overlap" as

  • 0 if none of the obox vertices nor pxyz are contained within self
  • 1-7 if some but not all of the vertices or pxyz are contained within self
  • 8 if all of the vertices are contained within self (pxyz must then be contained within self by definition)

Parameters:

Returns:

  • overlap ( int ) –

    The amount of overlap as defined above

contains

contains(xyz)

Check if point is closer than (<=) radius to center.

Performance Note

Prefer using contains_point or contains_pointlist for performance reasons

Vectorizable.

Parameters:

  • xyz (NDArray) –

    Point(s) to check

Returns:

  • bool

    True if point is within radius of center

See Also

contains_pointlist, count_inside

contains_point

contains_point(x, y, z)

Check if point is inside sphere

Parameters:

  • x (float) –

    3D coordinates of the point

  • y (float) –

    3D coordinates of the point

  • z (float) –

    3D coordinates of the point

Returns:

  • in_sph ( bool ) –

    True if point is inside sphere

See Also

contains_pointlist, count_inside

contains_pointlist

contains_pointlist(xyz)

Check if points are inside sphere

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test.

Returns:

  • in_sph ( NDArray[bool_] ) –

    Boolean array where True means point is inside sphere

See Also

contains_point, count_inside

count_inside

count_inside(xyz)

Return a count of how many points in xyz are inside the sphere

Prefer this function to sum(contains_pointlist) or similar to prevent unnecessary array creation.

Parameters:

  • xyz (NDArray) –

    Array of points with shape Nx3 to test.

Returns:

  • count ( int ) –

    The count of points that are inside this sphere

See Also

contains_point, contains_pointlist

Info

The following are not jitted and are intended to be used by regular python code for creating the corresponding BoundingVolumes

make_bounding_box

make_bounding_box(box)

Convert a Boxlike object into a BoundingBox.

A valid boxlike object is one that passes the check_valid function. (i.e. a numpy array with in the form [x, y, z, dx, dy, dz] with the following conditions: finite, all |x[i]| * epsilon < dx[i]).

This function is preferred over instancing the class directly, since it has increased flexibility over input arguments.

Parameters:

  • box (BoxLike) –

    The boxlike object to convert. Object will attempt to be coerced into a valid form (e.g. a (1, 6) int array will be converted to a (6,) float64 array)

Returns:

Raises:

  • BoundingBoxError

    if box is not a valid bounding box

See Also

check_valid

make_bounding_sphere

make_bounding_sphere(radius, *, center=None, unsafe=False)

Convert a radius (and point) into an BoundingSphere

This function is preferred over instancing the class directly, since it has increased flexibility over input arguments.

Parameters:

  • radius (float) –

    Radius of the sphere

  • center (ArrayLike | None, default: None ) –

    Center coordinates of the sphere. [0,0,0] if not provided

  • unsafe (bool, default: False ) –

    Skip checking if the sphere's bounding box is invalid

Returns:

Raises:

  • BoundingBoxError

    if the sphere's bounding box is not a valid bounding box, e.g. the radius is too small.

check_valid

check_valid(box, *, raise_error=True)

Check if a bounding box array is valid

Tests that a numpy array has the following attributes:

  1. It has shape (6, )
  2. It has finite values
  3. Values 4-6 are positive
  4. Values 4-6 are larger than the floating point precision of the 1-3 values (i.e. box[0] + box[3] > box[0])

Parameters:

  • box (BoxLike) –

    Array to check

  • raise_error (bool, default: True ) –

    How to deal with an invalid box. Raise error on True (default) or return test results flag

Returns:

  • flag ( BoundingBoxValidFlag ) –

    Flag of all test results

Raises:

  • BoundingBoxError

    if raise_error is True and box is invalid