Add mirroring functions to patterns/subpatterns

This commit is contained in:
jan 2018-04-14 15:29:19 -07:00
parent d5a255a9d7
commit f580e784f7
2 changed files with 62 additions and 1 deletions

View File

@ -351,6 +351,40 @@ class Pattern:
entry.rotate(rotation) entry.rotate(rotation)
return self return self
def mirror_element_centers(self, axis: int) -> 'Pattern':
"""
Mirror the offsets of all shapes and subpatterns across an axis
:param axis: Axis to mirror across
:return: self
"""
for entry in self.shapes + self.subpatterns:
entry.offset[axis] *= -1
return self
def mirror_elements(self, axis: int) -> 'Pattern':
"""
Mirror each shape and subpattern across an axis, relative to its
center (offset)
:param axis: Axis to mirror across
:return: self
"""
for entry in self.shapes + self.subpatterns:
entry.mirror(axis)
return self
def mirror(self, axis: int) -> 'Pattern':
"""
Mirror the Pattern across an axis
:param axis: Axis to mirror across
:return: self
"""
self.mirror_elements(axis)
self.mirror_element_centers(axis)
return self
def scale_element_doses(self, factor: float) -> 'Pattern': def scale_element_doses(self, factor: float) -> 'Pattern':
""" """
Multiply all shape and subpattern doses by a factor Multiply all shape and subpattern doses by a factor

View File

@ -3,7 +3,7 @@
offset, rotation, scaling, and other such properties to the reference. offset, rotation, scaling, and other such properties to the reference.
""" """
from typing import Union from typing import Union, List
import numpy import numpy
from numpy import pi from numpy import pi
@ -26,11 +26,13 @@ class SubPattern:
_rotation = 0.0 # type: float _rotation = 0.0 # type: float
_dose = 1.0 # type: float _dose = 1.0 # type: float
_scale = 1.0 # type: float _scale = 1.0 # type: float
_mirrored = None # type: List[bool]
def __init__(self, def __init__(self,
pattern: 'Pattern', pattern: 'Pattern',
offset: vector2=(0.0, 0.0), offset: vector2=(0.0, 0.0),
rotation: float=0.0, rotation: float=0.0,
mirrored: List[bool]=None,
dose: float=1.0, dose: float=1.0,
scale: float=1.0): scale: float=1.0):
self.pattern = pattern self.pattern = pattern
@ -38,6 +40,9 @@ class SubPattern:
self.rotation = rotation self.rotation = rotation
self.dose = dose self.dose = dose
self.scale = scale self.scale = scale
if mirrored is None:
mirrored = [False, False]
self.mirrored = mirrored
# offset property # offset property
@property @property
@ -90,6 +95,17 @@ class SubPattern:
raise PatternError('Rotation must be a scalar') raise PatternError('Rotation must be a scalar')
self._rotation = val % (2 * pi) self._rotation = val % (2 * pi)
# Mirrored property
@property
def mirrored(self) -> List[bool]:
return self._mirrored
@mirrored.setter
def mirrored(self, val: List[bool]):
if is_scalar(val):
raise PatternError('Mirrored must be a 2-element list of booleans')
self._mirrored = val
def as_pattern(self) -> 'Pattern': def as_pattern(self) -> 'Pattern':
""" """
Returns a copy of self.pattern which has been scaled, rotated, etc. according to this Returns a copy of self.pattern which has been scaled, rotated, etc. according to this
@ -98,6 +114,7 @@ class SubPattern:
""" """
pattern = self.pattern.copy() pattern = self.pattern.copy()
pattern.scale_by(self.scale) pattern.scale_by(self.scale)
[pattern.mirror(ax) for ax, do in enumerate(self.mirrored) if do]
pattern.rotate_around((0.0, 0.0), self.rotation) pattern.rotate_around((0.0, 0.0), self.rotation)
pattern.translate_elements(self.offset) pattern.translate_elements(self.offset)
pattern.scale_element_doses(self.dose) pattern.scale_element_doses(self.dose)
@ -138,6 +155,16 @@ class SubPattern:
self.rotation += rotation self.rotation += rotation
return self return self
def mirror(self, axis: int) -> 'SubPattern':
"""
Mirror the subpattern across an axis.
:param axis: Axis to mirror across.
:return: self
"""
self.mirrored[axis] = not self.mirrored[axis]
return self
def get_bounds(self) -> numpy.ndarray or None: def get_bounds(self) -> numpy.ndarray or None:
""" """
Return a numpy.ndarray containing [[x_min, y_min], [x_max, y_max]], corresponding to the Return a numpy.ndarray containing [[x_min, y_min], [x_max, y_max]], corresponding to the