@@ -306,6 +306,87 @@ def distance(self, x: Number, y: Number) -> int:
306306 return 0
307307
308308
309+ class Club (PointCollection ):
310+ """
311+ Class for the club shape.
312+
313+ .. plot::
314+ :scale: 75
315+ :caption:
316+ This shape is generated using the panda dataset.
317+
318+ from data_morph.data.loader import DataLoader
319+ from data_morph.shapes.points import Club
320+
321+ _ = Club(DataLoader.load_dataset('panda')).plot()
322+
323+ Parameters
324+ ----------
325+ dataset : Dataset
326+ The starting dataset to morph into other shapes.
327+ """
328+
329+ def __init__ (self , dataset : Dataset ) -> None :
330+ x_bounds = dataset .data_bounds .x_bounds
331+ y_bounds = dataset .data_bounds .y_bounds
332+
333+ x_shift = sum (x_bounds ) / 2
334+ y_shift = sum (y_bounds ) / 2
335+ scale_factor = min (x_bounds .range , y_bounds .range ) / 75
336+
337+ # params for lobes
338+ radius = 15 * scale_factor
339+ top_lobe_y_offset = 18 * scale_factor
340+ bottom_lobes_x_offset = 15 * scale_factor
341+ bottom_lobes_y_offset = 9 * scale_factor
342+
343+ t = np .linspace (0 , (2 - 1 / 3 ) * np .pi , num = 30 )
344+
345+ # top lobe
346+ angle_offset = - 1 / 3 * np .pi
347+ x_top = radius * np .cos (t + angle_offset )
348+ y_top = radius * np .sin (t + angle_offset ) + top_lobe_y_offset
349+
350+ # bottom left lobe
351+ angle_offset = 1 / 3 * np .pi
352+ x_bottom_left = radius * np .cos (t + angle_offset ) - bottom_lobes_x_offset
353+ y_bottom_left = radius * np .sin (t + angle_offset ) - bottom_lobes_y_offset
354+
355+ # bottom right lobe
356+ angle_offset = np .pi
357+ x_bottom_right = radius * np .cos (t + angle_offset ) + bottom_lobes_x_offset
358+ y_bottom_right = radius * np .sin (t + angle_offset ) - bottom_lobes_y_offset
359+
360+ x_lobes = [x_top , x_bottom_left , x_bottom_right ]
361+ y_lobes = [y_top , y_bottom_left , y_bottom_right ]
362+
363+ # params for the stem
364+ stem_x_offset = 8 * scale_factor
365+ stem_y_offset = 34 * scale_factor
366+ stem_scaler = 0.35 / scale_factor
367+ stem_x_pad = 1.5 * scale_factor
368+
369+ # stem bottom
370+ x_line = np .linspace (- stem_x_offset , stem_x_offset , num = 8 )
371+ y_line = np .repeat (- stem_y_offset , 8 )
372+
373+ # left part of the stem
374+ x_left = np .linspace (- (stem_x_offset - stem_x_pad ), - stem_x_pad , num = 6 )
375+ y_left = stem_scaler * np .power (x_left + stem_x_offset , 2 ) - stem_y_offset
376+
377+ # right part of the stem
378+ x_right = np .linspace (stem_x_pad , stem_x_offset - stem_x_pad , num = 6 )
379+ y_right = stem_scaler * np .power (x_right - stem_x_offset , 2 ) - stem_y_offset
380+
381+ x_stem = [x_line , x_left , x_right ]
382+ y_stem = [y_line , y_left , y_right ]
383+
384+ xs = x_shift + np .concatenate (x_lobes + x_stem )
385+ ys = y_shift + np .concatenate (y_lobes + y_stem )
386+
387+ super ().__init__ (* np .stack ([xs , ys ], axis = 1 ))
388+
389+
309390class Spade (PointCollection ):
310391 """
311392 Class for the spade shape.
0 commit comments