[apply_transform] include scale in transform
This commit is contained in:
parent
b8ee4bb05d
commit
da20922224
3 changed files with 24 additions and 12 deletions
|
|
@ -466,9 +466,11 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
memo = {}
|
||||
|
||||
if transform is None or transform is True:
|
||||
transform = numpy.zeros(4)
|
||||
transform = numpy.array([0, 0, 0, 0, 1], dtype=float)
|
||||
elif transform is not False:
|
||||
transform = numpy.asarray(transform, dtype=float)
|
||||
if transform.size == 4:
|
||||
transform = numpy.append(transform, 1.0)
|
||||
|
||||
original_pattern = pattern
|
||||
|
||||
|
|
|
|||
|
|
@ -191,10 +191,11 @@ class Ref(
|
|||
xys = self.offset[None, :]
|
||||
if self.repetition is not None:
|
||||
xys = xys + self.repetition.displacements
|
||||
transforms = numpy.empty((xys.shape[0], 4))
|
||||
transforms = numpy.empty((xys.shape[0], 5))
|
||||
transforms[:, :2] = xys
|
||||
transforms[:, 2] = self.rotation
|
||||
transforms[:, 3] = self.mirrored
|
||||
transforms[:, 4] = self.scale
|
||||
return transforms
|
||||
|
||||
def get_bounds_single(
|
||||
|
|
|
|||
|
|
@ -87,33 +87,41 @@ def apply_transforms(
|
|||
Apply a set of transforms (`outer`) to a second set (`inner`).
|
||||
This is used to find the "absolute" transform for nested `Ref`s.
|
||||
|
||||
The two transforms should be of shape Ox4 and Ix4.
|
||||
Rows should be of the form `(x_offset, y_offset, rotation_ccw_rad, mirror_across_x)`.
|
||||
The output will be of the form (O*I)x4 (if `tensor=False`) or OxIx4 (`tensor=True`).
|
||||
The two transforms should be of shape Ox5 and Ix5.
|
||||
Rows should be of the form `(x_offset, y_offset, rotation_ccw_rad, mirror_across_x, scale)`.
|
||||
The output will be of the form (O*I)x5 (if `tensor=False`) or OxIx5 (`tensor=True`).
|
||||
|
||||
Args:
|
||||
outer: Transforms for the container refs. Shape Ox4.
|
||||
inner: Transforms for the contained refs. Shape Ix4.
|
||||
tensor: If `True`, an OxIx4 array is returned, with `result[oo, ii, :]` corresponding
|
||||
outer: Transforms for the container refs. Shape Ox5.
|
||||
inner: Transforms for the contained refs. Shape Ix5.
|
||||
tensor: If `True`, an OxIx5 array is returned, with `result[oo, ii, :]` corresponding
|
||||
to the `oo`th `outer` transform applied to the `ii`th inner transform.
|
||||
If `False` (default), this is concatenated into `(O*I)x4` to allow simple
|
||||
If `False` (default), this is concatenated into `(O*I)x5` to allow simple
|
||||
chaining into additional `apply_transforms()` calls.
|
||||
|
||||
Returns:
|
||||
OxIx4 or (O*I)x4 array. Final dimension is
|
||||
`(total_x, total_y, total_rotation_ccw_rad, net_mirrored_x)`.
|
||||
OxIx5 or (O*I)x5 array. Final dimension is
|
||||
`(total_x, total_y, total_rotation_ccw_rad, net_mirrored_x, total_scale)`.
|
||||
"""
|
||||
outer = numpy.atleast_2d(outer).astype(float, copy=False)
|
||||
inner = numpy.atleast_2d(inner).astype(float, copy=False)
|
||||
|
||||
if outer.shape[1] == 4:
|
||||
outer = numpy.pad(outer, ((0, 0), (0, 1)), constant_values=1.0)
|
||||
if inner.shape[1] == 4:
|
||||
inner = numpy.pad(inner, ((0, 0), (0, 1)), constant_values=1.0)
|
||||
|
||||
# If mirrored, flip y's
|
||||
xy_mir = numpy.tile(inner[:, :2], (outer.shape[0], 1, 1)) # dims are outer, inner, xyrm
|
||||
xy_mir[outer[:, 3].astype(bool), :, 1] *= -1
|
||||
|
||||
# Apply outer scale to inner offset
|
||||
xy_mir *= outer[:, None, 4, None]
|
||||
|
||||
rot_mats = [rotation_matrix_2d(angle) for angle in outer[:, 2]]
|
||||
xy = numpy.einsum('ort,oit->oir', rot_mats, xy_mir)
|
||||
|
||||
tot = numpy.empty((outer.shape[0], inner.shape[0], 4))
|
||||
tot = numpy.empty((outer.shape[0], inner.shape[0], 5))
|
||||
tot[:, :, :2] = outer[:, None, :2] + xy
|
||||
|
||||
# If mirrored, flip inner rotation
|
||||
|
|
@ -122,6 +130,7 @@ def apply_transforms(
|
|||
|
||||
tot[:, :, 2] = rotations % (2 * pi)
|
||||
tot[:, :, 3] = (outer[:, None, 3] + inner[None, :, 3]) % 2 # net mirrored
|
||||
tot[:, :, 4] = outer[:, None, 4] * inner[None, :, 4] # net scale
|
||||
|
||||
if tensor:
|
||||
return tot
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue