renderpather, get_bounds includes repetitions, Boundable
This commit is contained in:
parent
22e1c6ae1d
commit
9a28e1617c
17 changed files with 366 additions and 161 deletions
|
|
@ -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)`
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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]))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue