diff --git a/masque/pattern.py b/masque/pattern.py index 2ed8251..abb310a 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -568,6 +568,17 @@ class Pattern(LockableImpl, AnnotatableImpl, Mirrorable, metaclass=AutoSlots): else: return numpy.vstack((min_bounds, max_bounds)) + def get_bounds_nonempty(self) -> NDArray[numpy.float64]: + """ + Convenience wrapper for `get_bounds()` which asserts that the Pattern as non-None bounds. + + Returns: + `[[x_min, y_min], [x_max, y_max]]` + """ + bounds = self.get_bounds() + assert(bounds is not None) + return bounds + def flatten(self: P) -> P: """ Removes all subpatterns and adds equivalent shapes. diff --git a/masque/shapes/path.py b/masque/shapes/path.py index 3bdffea..44d18de 100644 --- a/masque/shapes/path.py +++ b/masque/shapes/path.py @@ -332,7 +332,7 @@ class Path(Shape, metaclass=AutoSlots): bounds = numpy.array([[+inf, +inf], [-inf, -inf]]) polys = self.to_polygons() for poly in polys: - poly_bounds = poly.get_bounds() + poly_bounds = poly.get_bounds_nonempty() bounds[0, :] = numpy.minimum(bounds[0, :], poly_bounds[0, :]) bounds[1, :] = numpy.maximum(bounds[1, :], poly_bounds[1, :]) else: diff --git a/masque/traits/positionable.py b/masque/traits/positionable.py index c06cb84..b9c9259 100644 --- a/masque/traits/positionable.py +++ b/masque/traits/positionable.py @@ -65,9 +65,21 @@ class Positionable(metaclass=ABCMeta): def get_bounds(self) -> Optional[NDArray[numpy.float64]]: """ Returns `[[x_min, y_min], [x_max, y_max]]` which specify a minimal bounding box for the entity. + Returns `None` for an empty entity. """ pass + def get_bounds_nonempty(self) -> NDArray[numpy.float64]: + """ + Returns `[[x_min, y_min], [x_max, y_max]]` which specify a minimal bounding box for the entity. + Asserts that the entity is non-empty (i.e., `get_bounds()` does not return None). + + This is handy for destructuring like `xy_min, xy_max = entity.get_bounds_nonempty()` + """ + bounds = self.get_bounds() + assert(bounds is not None) + return bounds + class PositionableImpl(Positionable, metaclass=ABCMeta): """