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
¶
Return a BoundingBox for this volume
Returns:
-
BoundingBox–A BoundingBox instance that completely encloses this volume
check_box_overlap
¶
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
oboxvertices norpxyzare contained within self - 1-7 if some but not all of the vertices or
pxyzare contained within self - 8 if all of the vertices are contained within self (
pxyzmust then be contained within self by definition)
Parameters:
-
obox(BoundingBox) –The other box to check
Returns:
-
overlap(int) –The amount of overlap as defined above
contains
¶
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_point
¶
contains_pointlist
¶
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
count_inside
¶
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
BoundingBox
¶
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.
check_box_overlap
¶
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
oboxvertices norpxyzare contained within self, - 1-7 if some but not all of the vertices or
pxyzare contained within self, - 8 if all of the vertices are contained within self (
pxyzmust then be contained within self by definition)
Parameters:
-
obox(BoundingBox) –The other box to check
Returns:
-
overlap(int) –The amount of overlap as defined above
clip_to_box
¶
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:
-
obox(BoundingBox) –The box to clip to
Returns:
-
int–Returns 0 if any of the dx terms are 0, 1 otherwise
contains
¶
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_pointlist
¶
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]
count_inside
¶
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
get_box_vertex
¶
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
¶
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 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
¶
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
¶
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].
normalize_to_box
¶
Rescale and shift the coordinates to be bounded by the unit cube
project_point_on_box
¶
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
¶
Bases: BoundingVolume
A BoundingVolume in the shape of a sphere
check_box_overlap
¶
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
oboxvertices norpxyzare contained within self - 1-7 if some but not all of the vertices or
pxyzare contained within self - 8 if all of the vertices are contained within self (
pxyzmust then be contained within self by definition)
Parameters:
-
obox(BoundingBox) –The other box to check
Returns:
-
overlap(int) –The amount of overlap as defined above
contains
¶
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_point
¶
contains_pointlist
¶
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
count_inside
¶
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
Info
The following are not jitted and are intended to be used by regular python
code for creating the corresponding BoundingVolumes
make_bounding_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:
-
bbn(BoundingBox) –A BoundingBox object
Raises:
-
BoundingBoxError–if box is not a valid bounding box
See Also
make_bounding_sphere
¶
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:
-
sph(BoundingSphere) –A BoundingSphere object
Raises:
-
BoundingBoxError–if the sphere's bounding box is not a valid bounding box, e.g. the radius is too small.
check_valid
¶
Check if a bounding box array is valid
Tests that a numpy array has the following attributes:
- It has shape (6, )
- It has finite values
- Values 4-6 are positive
- 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_erroris True and box is invalid