Skip to content

Commit

Permalink
Add spade shape (#225)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Romero <[email protected]>
Co-authored-by: Stefanie Molin <[email protected]>
  • Loading branch information
3 people authored Oct 5, 2024
1 parent 2b9cf42 commit 5726e35
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/data_morph/shapes/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ShapeFactory:
'rings': circles.Rings,
'star': polygons.Star,
'club': points.Club,
'spade': points.Spade,
}

AVAILABLE_SHAPES: list[str] = sorted(_SHAPE_MAPPING.keys())
Expand Down
59 changes: 59 additions & 0 deletions src/data_morph/shapes/points.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,3 +385,62 @@ def __init__(self, dataset: Dataset) -> None:
ys = y_shift + np.concatenate(y_lobes + y_stem)

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


class Spade(PointCollection):
"""
Class for the spade shape.
.. plot::
:scale: 75
:caption:
This shape is generated using the panda dataset.
from data_morph.data.loader import DataLoader
from data_morph.shapes.points import Spade
_ = Spade(DataLoader.load_dataset('panda')).plot()
Parameters
----------
dataset : Dataset
The starting dataset to morph into other shapes.
"""

def __init__(self, dataset: Dataset) -> None:
x_bounds = dataset.data_bounds.x_bounds
y_bounds = dataset.data_bounds.y_bounds

x_shift = sum(x_bounds) / 2
y_shift = sum(y_bounds) / 2

# graph upside-down heart
heart_points = Heart(dataset).points
heart_points[:, 1] = -heart_points[:, 1] + 2 * y_shift

# line base
line_x = np.linspace(-6, 6, num=12)
line_y = np.repeat(-16, 12)

# left wing
left_x = np.linspace(-6, 0, num=12)
left_y = 0.278 * np.power(left_x + 6, 2) - 16

# right wing
right_x = np.linspace(0, 6, num=12)
right_y = 0.278 * np.power(right_x - 6, 2) - 16

# shift and scale the base and wing
base_x = np.concatenate((line_x, left_x, right_x), axis=0)
base_y = np.concatenate((line_y, left_y, right_y), axis=0)

# scale by the half the widest width of the spade
scale_factor = (x_bounds[1] - x_shift) / 16
base_x = base_x * scale_factor + x_shift
base_y = base_y * scale_factor + y_shift

# combine the base and the upside-down heart
x = np.concatenate((heart_points[:, 0], base_x), axis=0)
y = np.concatenate((heart_points[:, 1], base_y), axis=0)

super().__init__(*np.stack([x, y], axis=1))
14 changes: 14 additions & 0 deletions tests/shapes/test_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,17 @@ class TestClub(PointsModuleTestBase):
[(20, 50), 5.941155],
[(10, 80), 10.288055],
]


class TestSpade(PointsModuleTestBase):
"""Test the Spade class."""

shape_name = 'spade'
distance_test_cases = [
[(19.97189615, 75.43271708), 0],
[(23.75, 55), 0],
[(11.42685318, 59.11304904), 0],
[(20, 75), 0.2037185],
[(0, 0), 57.350348],
[(10, 80), 10.968080],
]

0 comments on commit 5726e35

Please sign in to comment.