simetri.stars.stars

This module contains classes and functions for creating stars and rosettes.

  1"""This module contains classes and functions for creating stars and rosettes."""
  2
  3from math import pi, sin, cos
  4from typing import Union
  5
  6from ..graphics.batch import Batch
  7from ..graphics.shape import Shape
  8
  9from ..graphics.common import common_properties, axis_x, Line
 10from ..graphics.all_enums import Types
 11from ..geometry.geometry import intersect, distance
 12
 13
 14def rosette(
 15    n: int,
 16    kernel: Union[Shape, Batch],
 17    cyclic: bool = False,
 18    axis: Line = axis_x,
 19    merge: bool = True,
 20) -> Batch:
 21    """Returns a pattern with cyclic or dihedral symmetry with n petals.
 22
 23    Args:
 24        n (int): Number of petals.
 25        kernel (Union[Shape, Batch]): The base shape or batch to be used as a petal.
 26        cyclic (bool, optional): If True, creates a cyclic pattern. Defaults to False.
 27        axis (Line, optional): The axis for mirroring. Defaults to axis_x.
 28        merge (bool, optional): If True, merges shapes. Defaults to True.
 29
 30    Returns:
 31        Batch: The resulting pattern with n petals.
 32    """
 33    if cyclic:
 34        petal = kernel
 35    else:
 36        petal = kernel.mirror(axis, reps=1)
 37        if merge:
 38            petal = petal.merge_shapes()
 39    petal = petal.rotate(2 * pi / n, reps=n - 1)
 40
 41    return petal
 42
 43
 44class Star(Batch):
 45    """Represents a star shape with n points.
 46
 47    Args:
 48        n (int): Number of points of the star.
 49        inner_radius (float, optional): Inner radius of the star. Defaults to None.
 50        circumradius (float, optional): Circumradius of the star. Defaults to None.
 51        **kwargs: Additional keyword arguments.
 52    """
 53
 54    def __init__(
 55        self, n: int, inner_radius: float = None, circumradius: float = None, **kwargs
 56    ):
 57        if circumradius is not None and inner_radius is not None:
 58            raise ValueError(
 59                "Only one of circumradius or inner_radius can be specified."
 60            )
 61
 62        self.n = n
 63        self.circumradius = circumradius
 64        self.inner_radius = inner_radius
 65        if circumradius is None and inner_radius is None:
 66            self.inner_radius = 50
 67
 68        self.center = (0, 0)
 69        self.subtype = Types.STAR
 70        common_properties(self)
 71        self._initialize(n)
 72        super().__init__(**kwargs)
 73
 74    def _initialize(self, n):
 75        """Initializes the star with n points.
 76
 77        Args:
 78            n (int): Number of points of the star.
 79
 80        Raises:
 81            ValueError: If n is less than 7.
 82        """
 83        if n < 7:
 84            raise ValueError("n must be greater than 6")
 85        if self.inner_radius is None:
 86            r = 50
 87        else:
 88            r = self.inner_radius  # start with a reasonable value
 89        alpha = (n - 2) * pi / n
 90        beta = (pi - alpha) / 2
 91        gamma = 2 * pi / n
 92        theta = 3 * pi / n
 93        t = r * sin(theta)
 94        x = t / cos(beta)
 95
 96        x1, y1 = r * cos(theta), r * sin(theta)
 97        up1 = (x1, y1)
 98        up2_ = 100, r * sin(theta)
 99        line1 = Shape([up1, up2_])
100        lp1 = x1, -y1
101        lp2_ = 100, -r * sin(theta)
102        line2 = Shape([lp1, lp2_])
103        up1_ = intersect(line1, line2.copy().rotate(gamma))
104        up2 = up1_[0] + r, y1
105        up3 = up2[0] + x * sin(beta), 0
106
107        self._kernel2 = Shape([up1, up2, up3])
108        self._petal2 = self._kernel2.copy().mirror(axis_x, reps=1)
109        self._level2 = self._petal2.rotate(gamma, reps=n - 1)
110        self._r2 = distance((0, 0), up1)
111        self._circum2 = up3[0]
112
113        p1 = line1.copy().rotate(-gamma)[0]
114        p2 = intersect(line2.copy().rotate(gamma), line1.copy().rotate(-gamma))
115
116        self._kernel0 = Shape([p1, p2])
117        self._petal0 = self._kernel0.copy().mirror(axis_x, reps=1)
118        self._level0 = self._petal0.rotate(gamma, reps=n - 1)
119        self._r0 = distance((0, 0), p1)
120        self._circum0 = p2[0]
121
122        line3 = Shape([up1, up1_])
123        self._kernel1 = line3.rotate(-gamma / 2)
124        self._petal1 = self._kernel1.copy().mirror(axis_x, reps=1)
125        self._level1 = self._petal1.rotate(gamma, reps=n - 1)
126        self._r1 = distance((0, 0), up1)
127        self._circum1 = up1_[0]
128
129    def _calc_kernel(self, segments, n):
130        """Calculates the kernel shape for the star.
131
132        Args:
133            segments (Shape): The segments to be used for calculation.
134            n (int): Number of points of the star.
135
136        Returns:
137            tuple: A tuple containing the kernel shape, inner radius, and circumradius.
138        """
139        segments = segments.copy()
140        segments.rotate(pi / n)
141        segments = segments.mirror(axis_x, reps=1)
142        p3 = intersect(segments[0].vertex_pairs[1], segments[1].vertex_pairs[1])
143        p1, p2 = segments[0].vertex_pairs[0]
144        kernel = Shape([p1, p2, p3])
145        inner_radius = distance((0, 0), p1)
146        circumradius = distance((0, 0), p3)
147
148        return (kernel, inner_radius, circumradius)
149
150    def _get_kernel(self, level):
151        """Gets the kernel shape for the specified level.
152
153        Args:
154            level (int): The level of the star.
155
156        Returns:
157            tuple: A tuple containing the kernel shape, inner radius, and circumradius.
158        """
159        kernel = self._kernel2.copy()
160        for _ in range(level - 2):
161            kernel, inner_radius, circumradius = self._calc_kernel(kernel, self.n)
162        return kernel, inner_radius, circumradius
163
164    def _get_scale_factor(self, level, inner_radius=None, circumradius=None):
165        """Calculates the scale factor for the specified level.
166
167        Args:
168            level (int): The level of the star.
169            inner_radius (float, optional): Inner radius of the star. Defaults to None.
170            circumradius (float, optional): Circumradius of the star. Defaults to None.
171
172        Returns:
173            float: The scale factor.
174        """
175        if self.inner_radius is None:
176            if level == 0:
177                denom = self._circum0
178            elif level == 1:
179                denom = self._circum1
180            elif level == 2:
181                denom = self._circum2
182            else:
183                denom = circumradius
184            scale_factor = self.circumradius / denom
185        else:
186            if level == 0:
187                denom = self._r0
188            elif level == 1:
189                denom = self._r1
190            elif level == 2:
191                denom = self._r2
192            else:
193                denom = inner_radius
194            scale_factor = self.inner_radius / denom
195
196        return scale_factor
197
198    def kernel(self, level: int) -> Shape:
199        """Returns the kernel of the star at the specified level.
200
201        Args:
202            level (int): The level of the star.
203
204        Returns:
205            Shape: The kernel shape of the star.
206
207        Raises:
208            ValueError: If level is not a positive integer or zero.
209        """
210        if level < 0 or not isinstance(level, int):
211            raise ValueError("level must be a positive integer or zero.")
212        if level == 0:
213            scale_factor = self._get_scale_factor(0, self._r0, self._circum0)
214            kernel = self._kernel0.copy().scale(scale_factor)
215        elif level == 1:
216            scale_factor = self._get_scale_factor(1, self._r1, self._circum1)
217            kernel = self._kernel1.copy().scale(scale_factor)
218        elif level == 2:
219            scale_factor = self._get_scale_factor(2, self._r2, self._circum2)
220            kernel = self._kernel2.copy().scale(scale_factor)
221        else:
222            kernel, inner_radius, circumradius = self._get_kernel(level)
223            scale_factor = self._get_scale_factor(level, inner_radius, circumradius)
224            kernel = kernel.scale(scale_factor)
225
226        return kernel
227
228    def petal(self, level: int) -> Shape:
229        """Returns the petal of the star at the specified level.
230
231        Args:
232            level (int): The level of the star.
233
234        Returns:
235            Shape: The petal shape of the star.
236
237        Raises:
238            ValueError: If level is not a positive integer or zero.
239        """
240        if level < 0 or not isinstance(level, int):
241            raise ValueError("level must be a positive integer or zero.")
242        if level == 0:
243            scale_factor = self._get_scale_factor(0, self._r0, self._circum0)
244            petal = self._kernel0.copy().mirror(axis_x, reps=1).scale(scale_factor)
245        elif level == 1:
246            scale_factor = self._get_scale_factor(1, self._r1, self._circum1)
247            petal = self._kernel1.copy().mirror(axis_x, reps=1).scale(scale_factor)
248        elif level == 2:
249            scale_factor = self._get_scale_factor(2, self._r2, self._circum2)
250            petal = self._kernel2.copy().mirror(axis_x, reps=1).scale(scale_factor)
251        else:
252            kernel, inner_radius, circumradius = self._get_kernel(level)
253            scale_factor = self._get_scale_factor(level, inner_radius, circumradius)
254            petal = kernel.mirror(axis_x, reps=1).scale(scale_factor)
255
256        return petal
257
258    def level(self, n: int) -> Batch:
259        """Returns the star at the specified level.
260
261        Args:
262            n (int): The level of the star.
263
264        Returns:
265            Batch: The star shape at the specified level.
266
267        Raises:
268            ValueError: If level is not a positive integer or zero.
269        """
270        if n < 0:
271            raise ValueError("level must be a positive integer or zero.")
272        if n == 0:
273            scale_factor = self._get_scale_factor(0)
274            star = self._level0.copy().scale(scale_factor)
275            star.subtype = Types.STAR
276            star.circumradius = self._circum0 * scale_factor
277            star.inner_radius = self._r0 * scale_factor
278        elif n == 1:
279            scale_factor = self._get_scale_factor(1)
280            star = self._level1.copy().scale(scale_factor)
281            star.subtype = Types.STAR
282            star.circumradius = self._circum1 * scale_factor
283            star.inner_radius = self._r0 * scale_factor
284        elif n == 2:
285            scale_factor = self._get_scale_factor(2)
286            star = self._level2.copy().scale(scale_factor)
287            star.subtype = Types.STAR
288            star.circumradius = self._circum2 * scale_factor
289            star.inner_radius = self._r0 * scale_factor
290        else:
291            kernel, inner_radius, circumradius = self._get_kernel(n)
292            scale_factor = self._get_scale_factor(n, inner_radius, circumradius)
293            petal = kernel.mirror(axis_x, reps=1)
294            star = petal.rotate(2 * pi / self.n, reps=self.n - 1)
295            scale_factor = self._get_scale_factor(n, inner_radius, circumradius)
296            star = star.scale(scale_factor)
297            star.subtype = Types.STAR
298            star.circumradius = circumradius
299            star.inner_radius = inner_radius
300
301        return star
def rosette( n: int, kernel: Union[simetri.graphics.shape.Shape, simetri.graphics.batch.Batch], cyclic: bool = False, axis: Sequence[Sequence] = ((0.0, 0.0), (1.0, 0.0)), merge: bool = True) -> simetri.graphics.batch.Batch:
15def rosette(
16    n: int,
17    kernel: Union[Shape, Batch],
18    cyclic: bool = False,
19    axis: Line = axis_x,
20    merge: bool = True,
21) -> Batch:
22    """Returns a pattern with cyclic or dihedral symmetry with n petals.
23
24    Args:
25        n (int): Number of petals.
26        kernel (Union[Shape, Batch]): The base shape or batch to be used as a petal.
27        cyclic (bool, optional): If True, creates a cyclic pattern. Defaults to False.
28        axis (Line, optional): The axis for mirroring. Defaults to axis_x.
29        merge (bool, optional): If True, merges shapes. Defaults to True.
30
31    Returns:
32        Batch: The resulting pattern with n petals.
33    """
34    if cyclic:
35        petal = kernel
36    else:
37        petal = kernel.mirror(axis, reps=1)
38        if merge:
39            petal = petal.merge_shapes()
40    petal = petal.rotate(2 * pi / n, reps=n - 1)
41
42    return petal

Returns a pattern with cyclic or dihedral symmetry with n petals.

Arguments:
  • n (int): Number of petals.
  • kernel (Union[Shape, Batch]): The base shape or batch to be used as a petal.
  • cyclic (bool, optional): If True, creates a cyclic pattern. Defaults to False.
  • axis (Line, optional): The axis for mirroring. Defaults to axis_x.
  • merge (bool, optional): If True, merges shapes. Defaults to True.
Returns:

Batch: The resulting pattern with n petals.

class Star(simetri.graphics.batch.Batch):
 45class Star(Batch):
 46    """Represents a star shape with n points.
 47
 48    Args:
 49        n (int): Number of points of the star.
 50        inner_radius (float, optional): Inner radius of the star. Defaults to None.
 51        circumradius (float, optional): Circumradius of the star. Defaults to None.
 52        **kwargs: Additional keyword arguments.
 53    """
 54
 55    def __init__(
 56        self, n: int, inner_radius: float = None, circumradius: float = None, **kwargs
 57    ):
 58        if circumradius is not None and inner_radius is not None:
 59            raise ValueError(
 60                "Only one of circumradius or inner_radius can be specified."
 61            )
 62
 63        self.n = n
 64        self.circumradius = circumradius
 65        self.inner_radius = inner_radius
 66        if circumradius is None and inner_radius is None:
 67            self.inner_radius = 50
 68
 69        self.center = (0, 0)
 70        self.subtype = Types.STAR
 71        common_properties(self)
 72        self._initialize(n)
 73        super().__init__(**kwargs)
 74
 75    def _initialize(self, n):
 76        """Initializes the star with n points.
 77
 78        Args:
 79            n (int): Number of points of the star.
 80
 81        Raises:
 82            ValueError: If n is less than 7.
 83        """
 84        if n < 7:
 85            raise ValueError("n must be greater than 6")
 86        if self.inner_radius is None:
 87            r = 50
 88        else:
 89            r = self.inner_radius  # start with a reasonable value
 90        alpha = (n - 2) * pi / n
 91        beta = (pi - alpha) / 2
 92        gamma = 2 * pi / n
 93        theta = 3 * pi / n
 94        t = r * sin(theta)
 95        x = t / cos(beta)
 96
 97        x1, y1 = r * cos(theta), r * sin(theta)
 98        up1 = (x1, y1)
 99        up2_ = 100, r * sin(theta)
100        line1 = Shape([up1, up2_])
101        lp1 = x1, -y1
102        lp2_ = 100, -r * sin(theta)
103        line2 = Shape([lp1, lp2_])
104        up1_ = intersect(line1, line2.copy().rotate(gamma))
105        up2 = up1_[0] + r, y1
106        up3 = up2[0] + x * sin(beta), 0
107
108        self._kernel2 = Shape([up1, up2, up3])
109        self._petal2 = self._kernel2.copy().mirror(axis_x, reps=1)
110        self._level2 = self._petal2.rotate(gamma, reps=n - 1)
111        self._r2 = distance((0, 0), up1)
112        self._circum2 = up3[0]
113
114        p1 = line1.copy().rotate(-gamma)[0]
115        p2 = intersect(line2.copy().rotate(gamma), line1.copy().rotate(-gamma))
116
117        self._kernel0 = Shape([p1, p2])
118        self._petal0 = self._kernel0.copy().mirror(axis_x, reps=1)
119        self._level0 = self._petal0.rotate(gamma, reps=n - 1)
120        self._r0 = distance((0, 0), p1)
121        self._circum0 = p2[0]
122
123        line3 = Shape([up1, up1_])
124        self._kernel1 = line3.rotate(-gamma / 2)
125        self._petal1 = self._kernel1.copy().mirror(axis_x, reps=1)
126        self._level1 = self._petal1.rotate(gamma, reps=n - 1)
127        self._r1 = distance((0, 0), up1)
128        self._circum1 = up1_[0]
129
130    def _calc_kernel(self, segments, n):
131        """Calculates the kernel shape for the star.
132
133        Args:
134            segments (Shape): The segments to be used for calculation.
135            n (int): Number of points of the star.
136
137        Returns:
138            tuple: A tuple containing the kernel shape, inner radius, and circumradius.
139        """
140        segments = segments.copy()
141        segments.rotate(pi / n)
142        segments = segments.mirror(axis_x, reps=1)
143        p3 = intersect(segments[0].vertex_pairs[1], segments[1].vertex_pairs[1])
144        p1, p2 = segments[0].vertex_pairs[0]
145        kernel = Shape([p1, p2, p3])
146        inner_radius = distance((0, 0), p1)
147        circumradius = distance((0, 0), p3)
148
149        return (kernel, inner_radius, circumradius)
150
151    def _get_kernel(self, level):
152        """Gets the kernel shape for the specified level.
153
154        Args:
155            level (int): The level of the star.
156
157        Returns:
158            tuple: A tuple containing the kernel shape, inner radius, and circumradius.
159        """
160        kernel = self._kernel2.copy()
161        for _ in range(level - 2):
162            kernel, inner_radius, circumradius = self._calc_kernel(kernel, self.n)
163        return kernel, inner_radius, circumradius
164
165    def _get_scale_factor(self, level, inner_radius=None, circumradius=None):
166        """Calculates the scale factor for the specified level.
167
168        Args:
169            level (int): The level of the star.
170            inner_radius (float, optional): Inner radius of the star. Defaults to None.
171            circumradius (float, optional): Circumradius of the star. Defaults to None.
172
173        Returns:
174            float: The scale factor.
175        """
176        if self.inner_radius is None:
177            if level == 0:
178                denom = self._circum0
179            elif level == 1:
180                denom = self._circum1
181            elif level == 2:
182                denom = self._circum2
183            else:
184                denom = circumradius
185            scale_factor = self.circumradius / denom
186        else:
187            if level == 0:
188                denom = self._r0
189            elif level == 1:
190                denom = self._r1
191            elif level == 2:
192                denom = self._r2
193            else:
194                denom = inner_radius
195            scale_factor = self.inner_radius / denom
196
197        return scale_factor
198
199    def kernel(self, level: int) -> Shape:
200        """Returns the kernel of the star at the specified level.
201
202        Args:
203            level (int): The level of the star.
204
205        Returns:
206            Shape: The kernel shape of the star.
207
208        Raises:
209            ValueError: If level is not a positive integer or zero.
210        """
211        if level < 0 or not isinstance(level, int):
212            raise ValueError("level must be a positive integer or zero.")
213        if level == 0:
214            scale_factor = self._get_scale_factor(0, self._r0, self._circum0)
215            kernel = self._kernel0.copy().scale(scale_factor)
216        elif level == 1:
217            scale_factor = self._get_scale_factor(1, self._r1, self._circum1)
218            kernel = self._kernel1.copy().scale(scale_factor)
219        elif level == 2:
220            scale_factor = self._get_scale_factor(2, self._r2, self._circum2)
221            kernel = self._kernel2.copy().scale(scale_factor)
222        else:
223            kernel, inner_radius, circumradius = self._get_kernel(level)
224            scale_factor = self._get_scale_factor(level, inner_radius, circumradius)
225            kernel = kernel.scale(scale_factor)
226
227        return kernel
228
229    def petal(self, level: int) -> Shape:
230        """Returns the petal of the star at the specified level.
231
232        Args:
233            level (int): The level of the star.
234
235        Returns:
236            Shape: The petal shape of the star.
237
238        Raises:
239            ValueError: If level is not a positive integer or zero.
240        """
241        if level < 0 or not isinstance(level, int):
242            raise ValueError("level must be a positive integer or zero.")
243        if level == 0:
244            scale_factor = self._get_scale_factor(0, self._r0, self._circum0)
245            petal = self._kernel0.copy().mirror(axis_x, reps=1).scale(scale_factor)
246        elif level == 1:
247            scale_factor = self._get_scale_factor(1, self._r1, self._circum1)
248            petal = self._kernel1.copy().mirror(axis_x, reps=1).scale(scale_factor)
249        elif level == 2:
250            scale_factor = self._get_scale_factor(2, self._r2, self._circum2)
251            petal = self._kernel2.copy().mirror(axis_x, reps=1).scale(scale_factor)
252        else:
253            kernel, inner_radius, circumradius = self._get_kernel(level)
254            scale_factor = self._get_scale_factor(level, inner_radius, circumradius)
255            petal = kernel.mirror(axis_x, reps=1).scale(scale_factor)
256
257        return petal
258
259    def level(self, n: int) -> Batch:
260        """Returns the star at the specified level.
261
262        Args:
263            n (int): The level of the star.
264
265        Returns:
266            Batch: The star shape at the specified level.
267
268        Raises:
269            ValueError: If level is not a positive integer or zero.
270        """
271        if n < 0:
272            raise ValueError("level must be a positive integer or zero.")
273        if n == 0:
274            scale_factor = self._get_scale_factor(0)
275            star = self._level0.copy().scale(scale_factor)
276            star.subtype = Types.STAR
277            star.circumradius = self._circum0 * scale_factor
278            star.inner_radius = self._r0 * scale_factor
279        elif n == 1:
280            scale_factor = self._get_scale_factor(1)
281            star = self._level1.copy().scale(scale_factor)
282            star.subtype = Types.STAR
283            star.circumradius = self._circum1 * scale_factor
284            star.inner_radius = self._r0 * scale_factor
285        elif n == 2:
286            scale_factor = self._get_scale_factor(2)
287            star = self._level2.copy().scale(scale_factor)
288            star.subtype = Types.STAR
289            star.circumradius = self._circum2 * scale_factor
290            star.inner_radius = self._r0 * scale_factor
291        else:
292            kernel, inner_radius, circumradius = self._get_kernel(n)
293            scale_factor = self._get_scale_factor(n, inner_radius, circumradius)
294            petal = kernel.mirror(axis_x, reps=1)
295            star = petal.rotate(2 * pi / self.n, reps=self.n - 1)
296            scale_factor = self._get_scale_factor(n, inner_radius, circumradius)
297            star = star.scale(scale_factor)
298            star.subtype = Types.STAR
299            star.circumradius = circumradius
300            star.inner_radius = inner_radius
301
302        return star

Represents a star shape with n points.

Arguments:
  • n (int): Number of points of the star.
  • inner_radius (float, optional): Inner radius of the star. Defaults to None.
  • circumradius (float, optional): Circumradius of the star. Defaults to None.
  • **kwargs: Additional keyword arguments.
Star( n: int, inner_radius: float = None, circumradius: float = None, **kwargs)
55    def __init__(
56        self, n: int, inner_radius: float = None, circumradius: float = None, **kwargs
57    ):
58        if circumradius is not None and inner_radius is not None:
59            raise ValueError(
60                "Only one of circumradius or inner_radius can be specified."
61            )
62
63        self.n = n
64        self.circumradius = circumradius
65        self.inner_radius = inner_radius
66        if circumradius is None and inner_radius is None:
67            self.inner_radius = 50
68
69        self.center = (0, 0)
70        self.subtype = Types.STAR
71        common_properties(self)
72        self._initialize(n)
73        super().__init__(**kwargs)

Initialize a Batch object.

Arguments:
  • elements (Sequence[Any], optional): The elements to include in the batch.
  • modifiers (Sequence[Modifier], optional): The modifiers to apply to the batch.
  • subtype (Types, optional): The subtype of the batch.
  • kwargs (dict): Additional keyword arguments.
n
circumradius
inner_radius
center
subtype
def kernel(self, level: int) -> simetri.graphics.shape.Shape:
199    def kernel(self, level: int) -> Shape:
200        """Returns the kernel of the star at the specified level.
201
202        Args:
203            level (int): The level of the star.
204
205        Returns:
206            Shape: The kernel shape of the star.
207
208        Raises:
209            ValueError: If level is not a positive integer or zero.
210        """
211        if level < 0 or not isinstance(level, int):
212            raise ValueError("level must be a positive integer or zero.")
213        if level == 0:
214            scale_factor = self._get_scale_factor(0, self._r0, self._circum0)
215            kernel = self._kernel0.copy().scale(scale_factor)
216        elif level == 1:
217            scale_factor = self._get_scale_factor(1, self._r1, self._circum1)
218            kernel = self._kernel1.copy().scale(scale_factor)
219        elif level == 2:
220            scale_factor = self._get_scale_factor(2, self._r2, self._circum2)
221            kernel = self._kernel2.copy().scale(scale_factor)
222        else:
223            kernel, inner_radius, circumradius = self._get_kernel(level)
224            scale_factor = self._get_scale_factor(level, inner_radius, circumradius)
225            kernel = kernel.scale(scale_factor)
226
227        return kernel

Returns the kernel of the star at the specified level.

Arguments:
  • level (int): The level of the star.
Returns:

Shape: The kernel shape of the star.

Raises:
  • ValueError: If level is not a positive integer or zero.
def petal(self, level: int) -> simetri.graphics.shape.Shape:
229    def petal(self, level: int) -> Shape:
230        """Returns the petal of the star at the specified level.
231
232        Args:
233            level (int): The level of the star.
234
235        Returns:
236            Shape: The petal shape of the star.
237
238        Raises:
239            ValueError: If level is not a positive integer or zero.
240        """
241        if level < 0 or not isinstance(level, int):
242            raise ValueError("level must be a positive integer or zero.")
243        if level == 0:
244            scale_factor = self._get_scale_factor(0, self._r0, self._circum0)
245            petal = self._kernel0.copy().mirror(axis_x, reps=1).scale(scale_factor)
246        elif level == 1:
247            scale_factor = self._get_scale_factor(1, self._r1, self._circum1)
248            petal = self._kernel1.copy().mirror(axis_x, reps=1).scale(scale_factor)
249        elif level == 2:
250            scale_factor = self._get_scale_factor(2, self._r2, self._circum2)
251            petal = self._kernel2.copy().mirror(axis_x, reps=1).scale(scale_factor)
252        else:
253            kernel, inner_radius, circumradius = self._get_kernel(level)
254            scale_factor = self._get_scale_factor(level, inner_radius, circumradius)
255            petal = kernel.mirror(axis_x, reps=1).scale(scale_factor)
256
257        return petal

Returns the petal of the star at the specified level.

Arguments:
  • level (int): The level of the star.
Returns:

Shape: The petal shape of the star.

Raises:
  • ValueError: If level is not a positive integer or zero.
def level(self, n: int) -> simetri.graphics.batch.Batch:
259    def level(self, n: int) -> Batch:
260        """Returns the star at the specified level.
261
262        Args:
263            n (int): The level of the star.
264
265        Returns:
266            Batch: The star shape at the specified level.
267
268        Raises:
269            ValueError: If level is not a positive integer or zero.
270        """
271        if n < 0:
272            raise ValueError("level must be a positive integer or zero.")
273        if n == 0:
274            scale_factor = self._get_scale_factor(0)
275            star = self._level0.copy().scale(scale_factor)
276            star.subtype = Types.STAR
277            star.circumradius = self._circum0 * scale_factor
278            star.inner_radius = self._r0 * scale_factor
279        elif n == 1:
280            scale_factor = self._get_scale_factor(1)
281            star = self._level1.copy().scale(scale_factor)
282            star.subtype = Types.STAR
283            star.circumradius = self._circum1 * scale_factor
284            star.inner_radius = self._r0 * scale_factor
285        elif n == 2:
286            scale_factor = self._get_scale_factor(2)
287            star = self._level2.copy().scale(scale_factor)
288            star.subtype = Types.STAR
289            star.circumradius = self._circum2 * scale_factor
290            star.inner_radius = self._r0 * scale_factor
291        else:
292            kernel, inner_radius, circumradius = self._get_kernel(n)
293            scale_factor = self._get_scale_factor(n, inner_radius, circumradius)
294            petal = kernel.mirror(axis_x, reps=1)
295            star = petal.rotate(2 * pi / self.n, reps=self.n - 1)
296            scale_factor = self._get_scale_factor(n, inner_radius, circumradius)
297            star = star.scale(scale_factor)
298            star.subtype = Types.STAR
299            star.circumradius = circumradius
300            star.inner_radius = inner_radius
301
302        return star

Returns the star at the specified level.

Arguments:
  • n (int): The level of the star.
Returns:

Batch: The star shape at the specified level.

Raises:
  • ValueError: If level is not a positive integer or zero.