Skip to content

Commit

Permalink
[Merge] [#97] Add methods to reflect geometry in a layer or canvas ab…
Browse files Browse the repository at this point in the history
…out a line
  • Loading branch information
nathan-hess authored Sep 8, 2023
2 parents 2bf7551 + 8106116 commit 030c8aa
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
29 changes: 29 additions & 0 deletions mahautils/shapes/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,35 @@ def plot(self, units: Optional[str] = None,

return None

def reflect(self, pntA: Union[Array_Float2, 'CartesianPoint2D'],
pntB: Union[Array_Float2, 'CartesianPoint2D']) -> None:
"""Reflects all shapes in all layers of the canvas about a line
specified by two points
Parameters
----------
pntA : list or tuple or CartesianPoint2D
One point on the line across which the shape is to be reflected
pntB : list or tuple or CartesianPoint2D
Another point on the line across which the shape is to be reflected
"""
for layer in self:
layer.reflect(pntA=pntA, pntB=pntB)

def reflect_x(self) -> None:
"""Reflects all shapes in all layers of the canvas about
the :math:`x`-axis
"""
for layer in self:
layer.reflect_x()

def reflect_y(self) -> None:
"""Reflects all shapes in all layers of the canvas about
the :math:`y`-axis
"""
for layer in self:
layer.reflect_y()

def rotate(self, center: Union[Array_Float2, CartesianPoint2D],
angle: float, angle_units: str = 'rad') -> None:
"""Rotates all shapes in all layers of the canvas a given angle in
Expand Down
26 changes: 26 additions & 0 deletions mahautils/shapes/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,32 @@ def plot(self, units: Optional[str] = None,

return None

def reflect(self, pntA: Union[Array_Float2, 'CartesianPoint2D'],
pntB: Union[Array_Float2, 'CartesianPoint2D']) -> None:
"""Reflects all shapes in the layer about a line specified by two points
Parameters
----------
pntA : list or tuple or CartesianPoint2D
One point on the line across which the shape is to be reflected
pntB : list or tuple or CartesianPoint2D
Another point on the line across which the shape is to be reflected
"""
for shape in self:
shape.reflect(pntA=pntA, pntB=pntB)

def reflect_x(self) -> None:
"""Reflects all shapes in the layer about the :math:`x`-axis
"""
for shape in self:
shape.reflect_x()

def reflect_y(self) -> None:
"""Reflects all shapes in the layer about the :math:`y`-axis
"""
for shape in self:
shape.reflect_y()

def rotate(self, center: Union[Array_Float2, CartesianPoint2D],
angle: float, angle_units: str = 'rad') -> None:
"""Rotates all shapes in the layer a given angle in the :math:`xy`-plane
Expand Down
34 changes: 32 additions & 2 deletions tests/shapes/test_canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,41 @@ def setUp(self):
self.layer2 = Layer()
self.canvas = Canvas(self.layer1, self.layer2)

self.layer1.reflect = Mock()
self.layer2.reflect = Mock()

self.layer1.reflect_x = Mock()
self.layer2.reflect_x = Mock()

self.layer1.reflect_y = Mock()
self.layer2.reflect_y = Mock()

self.layer1.rotate = Mock()
self.layer1.rotate = Mock()
self.layer2.rotate = Mock()

self.layer1.translate = Mock()
self.layer1.translate = Mock()
self.layer2.translate = Mock()

def test_reflect(self):
# Verifies that reflecting a canvas reflects all layers in the canvas
self.canvas.reflect(pntA=(1, 2), pntB=(3, 4))

self.layer1.reflect.assert_called_once_with(pntA=(1, 2), pntB=(3, 4))
self.layer2.reflect.assert_called_once_with(pntA=(1, 2), pntB=(3, 4))

def test_reflect_x(self):
# Verifies that reflecting a canvas reflects all layers in the canvas
self.canvas.reflect_x()

self.layer1.reflect_x.assert_called_once()
self.layer2.reflect_x.assert_called_once()

def test_reflect_y(self):
# Verifies that reflecting a canvas reflects all layers in the canvas
self.canvas.reflect_y()

self.layer1.reflect_y.assert_called_once()
self.layer2.reflect_y.assert_called_once()

def test_rotate(self):
# Verifies that rotating a canvas rotates all layers in the canvas
Expand Down
36 changes: 36 additions & 0 deletions tests/shapes/test_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,18 @@ def setUp(self):

self.layer = Layer(self.circle1, self.circle2, self.closed_shape)

self.circle1.reflect = Mock()
self.circle2.reflect = Mock()
self.closed_shape.reflect = Mock()

self.circle1.reflect_x = Mock()
self.circle2.reflect_x = Mock()
self.closed_shape.reflect_x = Mock()

self.circle1.reflect_y = Mock()
self.circle2.reflect_y = Mock()
self.closed_shape.reflect_y = Mock()

self.circle1.rotate = Mock()
self.circle2.rotate = Mock()
self.closed_shape.rotate = Mock()
Expand All @@ -289,6 +301,30 @@ def setUp(self):
self.circle2.translate = Mock()
self.closed_shape.translate = Mock()

def test_reflect(self):
# Verifies that reflecting a layer reflects all shapes in the layer
self.layer.reflect(pntA=(1, 2), pntB=(3, 4))

self.circle1.reflect.assert_called_once_with(pntA=(1, 2), pntB=(3, 4))
self.circle2.reflect.assert_called_once_with(pntA=(1, 2), pntB=(3, 4))
self.closed_shape.reflect.assert_called_once_with(pntA=(1, 2), pntB=(3, 4))

def test_reflect_x(self):
# Verifies that reflecting a layer reflects all shapes in the layer
self.layer.reflect_x()

self.circle1.reflect_x.assert_called_once()
self.circle2.reflect_x.assert_called_once()
self.closed_shape.reflect_x.assert_called_once()

def test_reflect_y(self):
# Verifies that reflecting a layer reflects all shapes in the layer
self.layer.reflect_y()

self.circle1.reflect_y.assert_called_once()
self.circle2.reflect_y.assert_called_once()
self.closed_shape.reflect_y.assert_called_once()

def test_rotate(self):
# Verifies that rotating a layer rotates all shapes in the layer
self.layer.rotate(center=(5, 6), angle=700, angle_units='mm')
Expand Down

0 comments on commit 030c8aa

Please sign in to comment.