renderpather, get_bounds includes repetitions, Boundable

This commit is contained in:
jan 2023-04-13 17:54:52 -07:00
commit 9a28e1617c
17 changed files with 366 additions and 161 deletions

View file

@ -241,7 +241,7 @@ class Arc(Shape):
poly = Polygon(xys, offset=self.offset, rotation=self.rotation)
return [poly]
def get_bounds(self) -> NDArray[numpy.float64]:
def get_bounds_single(self) -> NDArray[numpy.float64]:
'''
Equation for rotated ellipse is
`x = x0 + a * cos(t) * cos(rot) - b * sin(t) * sin(phi)`

View file

@ -89,7 +89,7 @@ class Circle(Shape):
return [Polygon(xys, offset=self.offset)]
def get_bounds(self) -> NDArray[numpy.float64]:
def get_bounds_single(self) -> NDArray[numpy.float64]:
return numpy.vstack((self.offset - self.radius,
self.offset + self.radius))

View file

@ -152,7 +152,7 @@ class Ellipse(Shape):
poly = Polygon(xys, offset=self.offset, rotation=self.rotation)
return [poly]
def get_bounds(self) -> NDArray[numpy.float64]:
def get_bounds_single(self) -> NDArray[numpy.float64]:
rot_radii = numpy.dot(rotation_matrix_2d(self.rotation), self.radii)
return numpy.vstack((self.offset - rot_radii[0],
self.offset + rot_radii[1]))

View file

@ -309,21 +309,23 @@ class Path(Shape):
return polys
def get_bounds(self) -> NDArray[numpy.float64]:
def get_bounds_single(self) -> NDArray[numpy.float64]:
if self.cap == PathCap.Circle:
bounds = self.offset + numpy.vstack((numpy.min(self.vertices, axis=0) - self.width / 2,
numpy.max(self.vertices, axis=0) + self.width / 2))
elif self.cap in (PathCap.Flush,
PathCap.Square,
PathCap.SquareCustom):
elif self.cap in (
PathCap.Flush,
PathCap.Square,
PathCap.SquareCustom,
):
bounds = numpy.array([[+inf, +inf], [-inf, -inf]])
polys = self.to_polygons()
for poly in polys:
poly_bounds = poly.get_bounds_nonempty()
poly_bounds = poly.get_bounds_single_nonempty()
bounds[0, :] = numpy.minimum(bounds[0, :], poly_bounds[0, :])
bounds[1, :] = numpy.maximum(bounds[1, :], poly_bounds[1, :])
else:
raise PatternError(f'get_bounds() not implemented for endcaps: {self.cap}')
raise PatternError(f'get_bounds_single() not implemented for endcaps: {self.cap}')
return bounds

View file

@ -327,7 +327,7 @@ class Polygon(Shape):
) -> list['Polygon']:
return [copy.deepcopy(self)]
def get_bounds(self) -> NDArray[numpy.float64]: # TODO note shape get_bounds doesn't include repetition
def get_bounds_single(self) -> NDArray[numpy.float64]: # TODO note shape get_bounds doesn't include repetition
return numpy.vstack((self.offset + numpy.min(self.vertices, axis=0),
self.offset + numpy.max(self.vertices, axis=0)))

View file

@ -5,7 +5,7 @@ import numpy
from numpy.typing import NDArray, ArrayLike
from ..traits import (
Rotatable, Mirrorable, Copyable, Scalable, Bounded,
Rotatable, Mirrorable, Copyable, Scalable,
PositionableImpl, PivotableImpl, RepeatableImpl, AnnotatableImpl,
)
@ -25,7 +25,7 @@ normalized_shape_tuple = tuple[
DEFAULT_POLY_NUM_VERTICES = 24
class Shape(PositionableImpl, Rotatable, Mirrorable, Copyable, Scalable, Bounded,
class Shape(PositionableImpl, Rotatable, Mirrorable, Copyable, Scalable,
PivotableImpl, RepeatableImpl, AnnotatableImpl, metaclass=ABCMeta):
"""
Class specifying functions common to all shapes.
@ -118,7 +118,7 @@ class Shape(PositionableImpl, Rotatable, Mirrorable, Copyable, Scalable, Bounded
polygon_contours = []
for polygon in self.to_polygons():
bounds = polygon.get_bounds()
bounds = polygon.get_bounds_single()
if bounds is None:
continue
@ -250,7 +250,7 @@ class Shape(PositionableImpl, Rotatable, Mirrorable, Copyable, Scalable, Bounded
polygon_contours = []
for polygon in self.to_polygons():
# Get rid of unused gridlines (anything not within 2 lines of the polygon bounds)
bounds = polygon.get_bounds()
bounds = polygon.get_bounds_single()
if bounds is None:
continue

View file

@ -2,7 +2,7 @@ from typing import Sequence, Any
import copy
import numpy
from numpy import pi, inf
from numpy import pi, nan
from numpy.typing import NDArray, ArrayLike
from . import Shape, Polygon, normalized_shape_tuple
@ -151,15 +151,20 @@ class Text(RotatableImpl, Shape):
mirrored=(mirror_x, False),
))
def get_bounds(self) -> NDArray[numpy.float64]:
def get_bounds_single(self) -> NDArray[numpy.float64]:
# rotation makes this a huge pain when using slot.advance and glyph.bbox(), so
# just convert to polygons instead
bounds = numpy.array([[+inf, +inf], [-inf, -inf]])
polys = self.to_polygons()
for poly in polys:
poly_bounds = poly.get_bounds()
bounds[0, :] = numpy.minimum(bounds[0, :], poly_bounds[0, :])
bounds[1, :] = numpy.maximum(bounds[1, :], poly_bounds[1, :])
pbounds = numpy.full((len(polys), 2, 2), nan)
# bounds = numpy.array([[+inf, +inf], [-inf, -inf]])
for pp, poly in enumerate(polys):
pbounds[pp] = poly.get_bounds_nonempty()
# bounds[0] = numpy.minimum(bounds[0], poly_bounds[0])
# bounds[1] = numpy.maximum(bounds[1], poly_bounds[1])
bounds = numpy.vstack((
numpy.min(pbounds[: 0, :], axis=0),
numpy.max(pbounds[: 1, :], axis=0),
))
return bounds