Skip to content

Commit c82a381

Browse files
authored
Add center property to Interval and BoundingBox to simplify shape calculations (#263)
1 parent 2041588 commit c82a381

File tree

7 files changed

+50
-16
lines changed

7 files changed

+50
-16
lines changed

src/data_morph/bounds/bounding_box.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,15 @@ def range(self) -> Iterable[Number]:
167167
The range covered by the x and y bounds, respectively.
168168
"""
169169
return self.x_bounds.range, self.y_bounds.range
170+
171+
@property
172+
def center(self) -> Iterable[Number]:
173+
"""
174+
Calculate the center of the bounding box.
175+
176+
Returns
177+
-------
178+
Iterable[numbers.Number]
179+
The center of the x and y bounds, respectively.
180+
"""
181+
return self.x_bounds.center, self.y_bounds.center

src/data_morph/bounds/interval.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,15 @@ def range(self) -> Number:
164164
The range covered by the interval.
165165
"""
166166
return abs(self._bounds[1] - self._bounds[0])
167+
168+
@property
169+
def center(self) -> Number:
170+
"""
171+
Calculate the center of the interval.
172+
173+
Returns
174+
-------
175+
numbers.Number
176+
The center of the interval.
177+
"""
178+
return sum(self) / 2

src/data_morph/shapes/points/club.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,14 @@ class Club(PointCollection):
2929
"""
3030

3131
def __init__(self, dataset: Dataset) -> None:
32-
x_bounds = dataset.data_bounds.x_bounds
33-
y_bounds = dataset.data_bounds.y_bounds
34-
35-
x_shift = sum(x_bounds) / 2
36-
y_shift = sum(y_bounds) / 2
37-
scale_factor = min(x_bounds.range, y_bounds.range) / 75
32+
scale_factor = min(*dataset.data_bounds.range) / 75
3833

3934
x_lobes, y_lobes = self._get_lobes(scale_factor)
4035
x_stem, y_stem = self._get_stem(scale_factor)
4136

42-
xs = x_shift + np.concatenate(x_lobes + x_stem)
43-
ys = y_shift + np.concatenate(y_lobes + y_stem)
37+
x_center, y_center = dataset.data_bounds.center
38+
xs = x_center + np.concatenate(x_lobes + x_stem)
39+
ys = y_center + np.concatenate(y_lobes + y_stem)
4440

4541
super().__init__(*np.stack([xs, ys], axis=1))
4642

src/data_morph/shapes/points/heart.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ class Heart(PointCollection):
3636

3737
def __init__(self, dataset: Dataset) -> None:
3838
x_bounds = dataset.data_bounds.x_bounds
39-
y_bounds = dataset.data_bounds.y_bounds
40-
41-
x_shift = sum(x_bounds) / 2
42-
y_shift = sum(y_bounds) / 2
39+
x_shift, y_shift = dataset.data_bounds.center
4340

4441
t = np.linspace(-3, 3, num=80)
4542

src/data_morph/shapes/points/spade.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ class Spade(PointCollection):
3131

3232
def __init__(self, dataset: Dataset) -> None:
3333
x_bounds = dataset.data_bounds.x_bounds
34-
y_bounds = dataset.data_bounds.y_bounds
35-
36-
x_shift = sum(x_bounds) / 2
37-
y_shift = sum(y_bounds) / 2
34+
x_shift, y_shift = dataset.data_bounds.center
3835

3936
# upside-down heart
4037
heart_points = self._get_inverted_heart(dataset, y_shift)

tests/bounds/test_bounding_box.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,8 @@ def test_range(self):
205205
"""Test that the range property is working."""
206206
bbox = BoundingBox([0, 10], [5, 10])
207207
assert bbox.range == (10, 5)
208+
209+
def test_center(self):
210+
"""Test that the center property is working."""
211+
bbox = BoundingBox([0, 10], [5, 10])
212+
assert bbox.center == (5, 7.5)

tests/bounds/test_interval.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,18 @@ def test_range(self, limits, inclusive, expected):
172172
"""Test that the range property is working."""
173173
bounds = Interval(limits, inclusive)
174174
assert bounds.range == expected
175+
176+
@pytest.mark.parametrize('inclusive', [True, False])
177+
@pytest.mark.parametrize(
178+
('limits', 'expected'),
179+
[
180+
([-10, -5], -7.5),
181+
([-1, 1], 0),
182+
([2, 100], 51),
183+
],
184+
ids=str,
185+
)
186+
def test_center(self, limits, inclusive, expected):
187+
"""Test that the center property is working."""
188+
bounds = Interval(limits, inclusive)
189+
assert bounds.center == expected

0 commit comments

Comments
 (0)