Skip to content

Commit

Permalink
Adjust default centre for linear PolygonalROI; docs updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dhomeier committed May 19, 2022
1 parent f99a267 commit 9b5161d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
40 changes: 35 additions & 5 deletions glue/core/roi.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,25 @@ def to_polygon(self):
raise NotImplementedError()

def rotate_to(self, theta):
"""Rotate anticlockwise around center to position angle theta (radian)"""
"""
Rotate anticlockwise around center to position angle theta.
Parameters
----------
theta : float
Angle of anticlockwise rotation around center in radian.
"""
raise NotImplementedError()

def rotate_by(self, dtheta, **kwargs):
"""Rotate the Roi around center by angle dtheta (radian)"""
"""
Rotate the Roi around center by angle dtheta.
Parameters
----------
dtheta : float
Change in anticlockwise rotation angle around center in radian.
"""
self.rotate_to(getattr(self, 'theta', 0.0) + dtheta, **kwargs)

def copy(self):
Expand Down Expand Up @@ -697,9 +711,10 @@ def add_point(self, x, y):
self.vy.append(y)

def reset(self):
"""Reset the vertex lists"""
"""Reset the vertex lists and position angle"""
self.vx = []
self.vy = []
self.theta = 0

def replace_last_point(self, x, y):
if len(self.vx) > 0:
Expand Down Expand Up @@ -856,12 +871,27 @@ def move_to(self, xdelta, ydelta):

def rotate_to(self, theta, center=None):
"""
Rotate polygon by angle `theta` [radian] around `center` (default centroid).
Rotate polygon to position angle `theta` around `center`.
Parameters
----------
theta : float
Angle of anticlockwise rotation around center in radian.
center : pair of float, optional
Coordinates of center of rotation. Defaults to
:meth:`~glue.core.roi.PolygonalROI.centroid`, for linear
"polygons" to :meth:`~glue.core.roi.PolygonalROI.mean`.
"""

theta = 0 if theta is None else theta
center = self.centroid() if center is None else center
# For linear (1D) "polygons" centroid is not defined.
if center is None:
if self.area() == 0:
center = self.mean()
else:
center = self.centroid()
dtheta = theta - self.theta

if self.defined() and not np.isclose(dtheta % np.pi, 0.0, atol=1e-9):
dx, dy = np.array([self.vx, self.vy]) - np.array(center).reshape(2, 1)
self.vx, self.vy = (rotation_matrix_2d(dtheta) @ (dx, dy) +
Expand Down
14 changes: 14 additions & 0 deletions glue/core/tests/test_roi.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,20 @@ def test_rotate_triangle(self):
assert_almost_equal(self.roi.vx, (2/3, -1/3, 2/3), decimal=12)
assert_almost_equal(self.roi.vy, (0, 0, 1), decimal=12)

def test_rotate_polyline(self):
""" Test rotation of degenerate (linear) ROI around mean """
self.roi.reset()
self.roi.add_point(-2, 0)
self.roi.add_point(4, 0)
assert_almost_equal(self.roi.mean(), (1.0, 0.0), decimal=12)
self.roi.add_point(-0.5, 0)
self.roi.add_point(-1.5, 0)
assert_almost_equal(self.roi.mean(), (0.0, 0.0), decimal=12)
assert all(np.isnan(self.roi.centroid()))
self.roi.rotate_to(np.pi/2)
assert_almost_equal(self.roi.vx, (0, 0, 0, 0), decimal=12)
assert_almost_equal(self.roi.vy, (-2, 4, -0.5, -1.5), decimal=12)

def test_append_mock_points(self):
"""
Test that adding points on the side of square ROI conserves area and centroid.
Expand Down

0 comments on commit 9b5161d

Please sign in to comment.