Source code for svgen.cartesian.rectangle.grid

"""
A module implementing grid interfaces for rectangles.
"""

# built-in
from typing import Iterable, NamedTuple, Tuple, Union

# internal
from svgen.cartesian.mutate import Translation
from svgen.cartesian.point import Point
from svgen.cartesian.rectangle import Rectangle


[docs] class RectangleIndex(NamedTuple): """An index into a rectangle grid.""" column: int row: int
[docs] class RectangleGrid(NamedTuple): """A class for locating points within a rectangle.""" rect: Rectangle columns: int rows: int @property def x_scale(self) -> float: """Get the scalar value for 'x' coordinates.""" return self.rect.width / float(self.columns) @property def y_scale(self) -> float: """Get the scalar value for 'y' coordinates.""" return self.rect.height / float(self.rows) def __call__(self, x: float, y: float) -> Point: """Get the true location of a point within this grid.""" # Ensure the coordinates are within the sub-divisions. assert x <= self.columns assert y <= self.rows return self.rect.origin.translate(x * self.x_scale, y * self.y_scale) @property def points(self) -> Iterable[Point]: """Iterate over points in the grid.""" for row in range(self.rows + 1): for col in range(self.columns + 1): yield self(col, row)
[docs] def box(self, x: float, y: float) -> Rectangle: """Get a rectangle object from provided coordinates.""" return Rectangle.create(self.x_scale, self.y_scale, self(x, y))
@property def boxes(self) -> Iterable[Rectangle]: """Iterate over boxes belonging to this grid.""" for row in range(self.rows): for col in range(self.columns): yield self.box(col, row) @property def enumerate_boxes(self) -> Iterable[Tuple[RectangleIndex, Rectangle]]: """Iterate over boxes belonging to this grid.""" for row in range(self.rows): for col in range(self.columns): yield RectangleIndex(col, row), self.box(col, row)
[docs] def adjust( self, columns: int = None, rows: int = None, rect: Rectangle = None ) -> "RectangleGrid": """Create a new grid from new parameters.""" if columns is None: columns = self.columns if rows is None: rows = self.rows if rect is None: rect = self.rect return RectangleGrid(rect, columns, rows)
[docs] def translate( self, dx: Union[Translation, float], *args, **kwargs ) -> "RectangleGrid": """Translate this rectangle grid.""" return RectangleGrid( self.rect.translate(dx, *args, **kwargs), self.columns, self.rows )