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)
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':
"""
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.
"""
from typing import Union
from typing import Union, List
import numpy
from numpy import pi
@ -26,11 +26,13 @@ class SubPattern:
_rotation = 0.0 # type: float
_dose = 1.0 # type: float
_scale = 1.0 # type: float
_mirrored = None # type: List[bool]
def __init__(self,
pattern: 'Pattern',
offset: vector2=(0.0, 0.0),
rotation: float=0.0,
mirrored: List[bool]=None,
dose: float=1.0,
scale: float=1.0):
self.pattern = pattern
@ -38,6 +40,9 @@ class SubPattern:
self.rotation = rotation
self.dose = dose
self.scale = scale
if mirrored is None:
mirrored = [False, False]
self.mirrored = mirrored
# offset property
@property
@ -90,6 +95,17 @@ class SubPattern:
raise PatternError('Rotation must be a scalar')
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':
"""
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.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.translate_elements(self.offset)
pattern.scale_element_doses(self.dose)
@ -138,6 +155,16 @@ class SubPattern:
self.rotation += rotation
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:
"""
Return a numpy.ndarray containing [[x_min, y_min], [x_max, y_max]], corresponding to the