-
-
Notifications
You must be signed in to change notification settings - Fork 24
Add infinity and figure eight target shapes #190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
98ebfac
92683cc
9d51b10
82f870e
dbb735c
0853d0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -131,6 +131,55 @@ def __init__(self, dataset: Dataset) -> None: | |
| ) | ||
|
|
||
|
|
||
| class Infinity(PointCollection): | ||
| """ | ||
| Class for the infinity 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 Infinity | ||
|
|
||
| _ = Infinity(DataLoader.load_dataset('panda')).plot() | ||
|
|
||
| Parameters | ||
| ---------- | ||
| dataset : Dataset | ||
| The starting dataset to morph into other shapes. | ||
|
|
||
| Notes | ||
| ----- | ||
| The formula for the infinity shape is directly taken from Lemniscate of | ||
| Bernoulli equation. | ||
| `Infinity Curve <https://mathworld.wolfram.com/Lemniscate.html>`_: | ||
|
|
||
| Weisstein, Eric W. "Lemniscate." From MathWorld-- | ||
| A Wolfram Web Resource. https://mathworld.wolfram.com/Lemniscate.html | ||
| """ | ||
|
|
||
| def __init__(self, dataset: Dataset, scale: float = 0.75) -> 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 | ||
|
|
||
| t = np.linspace(-3, 3, num=2000) | ||
|
|
||
| x = (np.sqrt(2) * np.cos(t)) / (1 + np.square(np.sin(t))) | ||
| y = (np.sqrt(2) * np.cos(t) * np.sin(t)) / (1 + np.square(np.sin(t))) | ||
|
|
||
| # scale by the half the widest width of the infinity | ||
| scale_factor = (x_bounds[1] - x_shift) * 0.75 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not use the y information here? Maybe pick one using the data? With the sheep for example, it seems like the figure eight is being drawn too tall, so we should probably take the minimum of the x and y scale factors and use that. Try plotting a dataset and the shape on top of each other and see how that looks. |
||
|
|
||
| super().__init__( | ||
| *np.stack([x * scale_factor + x_shift, y * scale_factor + y_shift], axis=1) | ||
| ) | ||
|
|
||
|
|
||
| class LeftParabola(PointCollection): | ||
| """ | ||
| Class for the left parabola shape. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using 2,000 points is a lot, the algorithm needs to calculate the distance to each point. Can we reduce this? For example, the heart only uses 80.