simetri.extensions.turtle_sg

Turtle graphics variant, with a twist.

  1"""Turtle graphics variant, with a twist."""
  2
  3from math import pi, radians
  4from typing import Sequence, List, Tuple, Optional, Any
  5from dataclasses import dataclass
  6
  7from ..graphics.batch import Batch
  8from ..graphics.shape import Shape
  9
 10from ..geometry.geometry import line_by_point_angle_length as get_pos
 11
 12
 13@dataclass
 14class State:
 15    """A state of the turtle.
 16
 17    Attributes:
 18        pos (tuple): The position of the turtle.
 19        angle (float): The angle of the turtle.
 20        pen_is_down (bool): Whether the pen is down.
 21    """
 22
 23    pos: tuple
 24    angle: float
 25    pen_is_down: bool
 26
 27class Turtle(Batch):
 28    """A Turtle graphics variant, with a twist.
 29
 30    This class implements a turtle graphics system that can be used to draw
 31    geometric shapes and patterns.
 32
 33    Args:
 34        *args: Variable length argument list passed to the parent class.
 35        in_degrees (bool, optional): Whether angles are measured in degrees. Defaults to False.
 36        **kwargs: Arbitrary keyword arguments passed to the parent class.
 37    """
 38
 39    def __init__(self, *args: Any, in_degrees: bool = False, **kwargs: Any) -> None:
 40        self.pos = (0, 0)
 41        self.stack = []
 42        self.lists = []
 43        self.current_list = [self.pos]
 44        super().__init__([], *args, **kwargs)
 45        self.pen_is_down = True
 46        self._set_aliasess()
 47        self.in_degrees = in_degrees
 48        if in_degrees:
 49            self.def_angle = 90
 50        else:
 51            self.def_angle = pi / 2
 52        self.def_dist = 20
 53        # start facing north
 54        if in_degrees:
 55            self._angle = 90
 56        else:
 57            self._angle = pi / 2
 58
 59    @property
 60    def angle(self) -> float:
 61        """Return the current angle of the turtle.
 62
 63        The angle is clamped to the appropriate range based on the angle mode.
 64
 65        Returns:
 66            float: The current angle, normalized to 0-360 degrees or 0-2π radians.
 67        """
 68        if self.in_degrees:
 69            res = self._angle % 360
 70        else:
 71            res = self._angle % (2 * pi)
 72
 73        return res
 74
 75    @angle.setter
 76    def angle(self, value: float) -> None:
 77        """Set the angle of the turtle.
 78
 79        Args:
 80            value (float): The new angle value in degrees or radians
 81                based on the turtle's configuration.
 82        """
 83        self._angle = value
 84
 85    def _forward_pos(self, dist: float = None) -> tuple:
 86        """Calculate the position after moving forward by the given distance.
 87
 88        Args:
 89            dist (float, optional): The distance to move. Defaults to self.def_dist.
 90
 91        Returns:
 92            tuple: The new position coordinates.
 93        """
 94        if self.in_degrees:
 95            angle = radians(self._angle)
 96        else:
 97            angle = self._angle
 98
 99        if dist is None:
100            dist = self.def_dist
101
102        return get_pos(self.pos, angle, dist)[1]
103
104    def forward(self, dist: float = None) -> None:
105        """Move the turtle forward by the given distance.
106
107        Moves the turtle and draws a line if the pen is down.
108
109        Args:
110            dist (float, optional): The distance to move forward. Defaults to self.def_dist.
111        """
112        x, y = self._forward_pos(dist)[:2]
113        self.pos = (x, y)
114        if self.pen_is_down:
115            self.current_list.append(self.pos)
116
117    def go(self, dist: float = None) -> None:
118        """Move the turtle forward without drawing.
119
120        Moves the turtle regardless of the pen state, and doesn't draw.
121        Saves the current path and starts a new one.
122
123        Args:
124            dist (float, optional): The distance to move forward. Defaults to self.def_dist.
125        """
126        x, y = self._forward_pos(dist)[:2]
127        self.pos = (x, y)
128        self.lists.append(self.current_list)
129        self.current_list = [self.pos]
130
131    def backward(self, dist: float = None) -> None:
132        """Move the turtle backward by the given distance.
133
134        Args:
135            dist (float, optional): The distance to move backward. Defaults to self.def_dist.
136        """
137        if dist is None:
138            dist = self.def_dist
139        self.forward(-dist)
140
141    def left(self, angle: float = None) -> None:
142        """Turn the turtle left by the given angle.
143
144        Args:
145            angle (float, optional): The angle to turn left. Defaults to self.def_angle.
146        """
147        if angle is None:
148            angle = self.def_angle
149        self._angle += angle
150
151    def right(self, angle: float = None) -> None:
152        """Turn the turtle right by the given angle.
153
154        Args:
155            angle (float, optional): The angle to turn right. Defaults to self.def_angle.
156        """
157        if angle is None:
158            angle = self.def_angle
159        self._angle -= angle
160
161    def turn_around(self) -> None:
162        """Turn the turtle around by 180 degrees.
163
164        Rotates the turtle 180 degrees from its current direction.
165        """
166        if self.in_degrees:
167            self._angle += 180
168        else:
169            self._angle += pi
170
171
172    def pen_up(self) -> None:
173        """Lift the pen.
174
175        Stops drawing and saves the current path when the turtle moves.
176        """
177        self.pen_is_down = False
178        self.lists.append(self.current_list)
179        self.current_list = []
180
181    def pen_down(self) -> None:
182        """Lower the pen.
183
184        Enables drawing when the turtle moves and adds the current position
185        to the current path.
186        """
187        self.pen_is_down = True
188        self.current_list.append(self.pos)
189
190    def move_to(self, pos: tuple) -> None:
191        """Move the turtle to the given position.
192
193        Args:
194            pos (tuple): The target position as (x, y) coordinates.
195        """
196        self.pos = pos
197        if self.pen_is_down:
198            self.current_list.append(self.pos)
199
200
201    def push(self) -> None:
202        """Save the current state of the turtle.
203
204        Stores the current position, angle, and pen state for later retrieval.
205        """
206        state = State(self.pos, self._angle, self.pen_is_down)
207        self.stack.append(state)
208
209    def pop(self) -> None:
210        """Restore the last saved state of the turtle.
211
212        Retrieves the most recently saved state and restores the turtle to it.
213        """
214        state = self.stack.pop()
215        self.pos = state.pos
216        self._angle = state.angle
217        self.pen_is_down = state.pen_is_down
218        self.lists.append(self.current_list)
219        self.current_list = [self.pos]
220
221    def reset(self) -> None:
222        """Reset the turtle to its initial state.
223
224        Appends the current shape to the batch and resets position, angle,
225        and pen state.
226        """
227        self.append(self.current_shape)
228        self.pos = (0, 0)
229        if self.in_degrees:
230            self._angle = 0
231        else:
232            self._angle = pi / 2
233        self.current_list = [self.pos]
234        self.pen_is_down = True
235
236    # aliases
237    def _set_aliasess(self) -> None:
238        """Set up aliases for turtle methods.
239
240        Creates shorthand method names commonly used in turtle graphics.
241        """
242        self.fd = self.forward
243        self.bk = self.backward
244        self.lt = self.left
245        self.rt = self.right
246        self.pu = self.pen_up
247        self.pd = self.pen_down
248        self.goto = self.move_to
249
250
251def add_digits(n: int) -> int:
252    """Return the sum of the digits of n.
253
254    Spirolateral helper function that adds all digits in a number.
255
256    Args:
257        n (int): The number to process.
258
259    Returns:
260        int: The sum of all digits in n.
261
262    Examples:
263        10 -> 1 + 0 -> 1
264        123 -> 1 + 2 + 3 -> 6
265    """
266    return sum((int(x) for x in str(n)))
267
268
269def spirolateral(
270    sequence: Sequence, angle: float, cycles: int = 15, multiplier: float = 50
271) -> Turtle:
272    """Draw a spirolateral with the given sequence and angle.
273
274    Args:
275        sequence (Sequence): Sequence of numbers determining segment lengths.
276        angle (float): Angle in degrees for turns.
277        cycles (int, optional): Number of cycles to draw. Defaults to 15.
278        multiplier (float, optional): Scaling factor for segment lengths. Defaults to 50.
279
280    Returns:
281        Turtle: The turtle object used for drawing.
282    """
283    turtle = Turtle(in_degrees=True)
284    count = 0
285    while count < cycles:
286        for i in sequence:
287            turtle.forward(multiplier * add_digits(i))
288            turtle.right(180 - angle)
289            count += 1
290    return turtle
291
292
293def spiral(turtle: Turtle, side: float, angle: float, delta: float, cycles: int = 15) -> Turtle:
294    """Draw a spiral with the given side, angle, delta, and cycles.
295
296    Args:
297        turtle (Turtle): The turtle object to use for drawing.
298        side (float): Initial length of the side.
299        angle (float): Angle to turn after drawing each side.
300        delta (float): Amount to increase the side length in each step.
301        cycles (int, optional): Number of segments to draw. Defaults to 15.
302
303    Returns:
304        Turtle: The turtle object used for drawing.
305    """
306    t = turtle
307    count = 0
308    while count < cycles:
309        t.forward(side)
310        t.right(angle)
311        side += delta
312        count += 1
313    return t
@dataclass
class State:
14@dataclass
15class State:
16    """A state of the turtle.
17
18    Attributes:
19        pos (tuple): The position of the turtle.
20        angle (float): The angle of the turtle.
21        pen_is_down (bool): Whether the pen is down.
22    """
23
24    pos: tuple
25    angle: float
26    pen_is_down: bool

A state of the turtle.

Attributes:
  • pos (tuple): The position of the turtle.
  • angle (float): The angle of the turtle.
  • pen_is_down (bool): Whether the pen is down.
State(pos: tuple, angle: float, pen_is_down: bool)
pos: tuple
angle: float
pen_is_down: bool
class Turtle(simetri.graphics.batch.Batch):
 28class Turtle(Batch):
 29    """A Turtle graphics variant, with a twist.
 30
 31    This class implements a turtle graphics system that can be used to draw
 32    geometric shapes and patterns.
 33
 34    Args:
 35        *args: Variable length argument list passed to the parent class.
 36        in_degrees (bool, optional): Whether angles are measured in degrees. Defaults to False.
 37        **kwargs: Arbitrary keyword arguments passed to the parent class.
 38    """
 39
 40    def __init__(self, *args: Any, in_degrees: bool = False, **kwargs: Any) -> None:
 41        self.pos = (0, 0)
 42        self.stack = []
 43        self.lists = []
 44        self.current_list = [self.pos]
 45        super().__init__([], *args, **kwargs)
 46        self.pen_is_down = True
 47        self._set_aliasess()
 48        self.in_degrees = in_degrees
 49        if in_degrees:
 50            self.def_angle = 90
 51        else:
 52            self.def_angle = pi / 2
 53        self.def_dist = 20
 54        # start facing north
 55        if in_degrees:
 56            self._angle = 90
 57        else:
 58            self._angle = pi / 2
 59
 60    @property
 61    def angle(self) -> float:
 62        """Return the current angle of the turtle.
 63
 64        The angle is clamped to the appropriate range based on the angle mode.
 65
 66        Returns:
 67            float: The current angle, normalized to 0-360 degrees or 0-2π radians.
 68        """
 69        if self.in_degrees:
 70            res = self._angle % 360
 71        else:
 72            res = self._angle % (2 * pi)
 73
 74        return res
 75
 76    @angle.setter
 77    def angle(self, value: float) -> None:
 78        """Set the angle of the turtle.
 79
 80        Args:
 81            value (float): The new angle value in degrees or radians
 82                based on the turtle's configuration.
 83        """
 84        self._angle = value
 85
 86    def _forward_pos(self, dist: float = None) -> tuple:
 87        """Calculate the position after moving forward by the given distance.
 88
 89        Args:
 90            dist (float, optional): The distance to move. Defaults to self.def_dist.
 91
 92        Returns:
 93            tuple: The new position coordinates.
 94        """
 95        if self.in_degrees:
 96            angle = radians(self._angle)
 97        else:
 98            angle = self._angle
 99
100        if dist is None:
101            dist = self.def_dist
102
103        return get_pos(self.pos, angle, dist)[1]
104
105    def forward(self, dist: float = None) -> None:
106        """Move the turtle forward by the given distance.
107
108        Moves the turtle and draws a line if the pen is down.
109
110        Args:
111            dist (float, optional): The distance to move forward. Defaults to self.def_dist.
112        """
113        x, y = self._forward_pos(dist)[:2]
114        self.pos = (x, y)
115        if self.pen_is_down:
116            self.current_list.append(self.pos)
117
118    def go(self, dist: float = None) -> None:
119        """Move the turtle forward without drawing.
120
121        Moves the turtle regardless of the pen state, and doesn't draw.
122        Saves the current path and starts a new one.
123
124        Args:
125            dist (float, optional): The distance to move forward. Defaults to self.def_dist.
126        """
127        x, y = self._forward_pos(dist)[:2]
128        self.pos = (x, y)
129        self.lists.append(self.current_list)
130        self.current_list = [self.pos]
131
132    def backward(self, dist: float = None) -> None:
133        """Move the turtle backward by the given distance.
134
135        Args:
136            dist (float, optional): The distance to move backward. Defaults to self.def_dist.
137        """
138        if dist is None:
139            dist = self.def_dist
140        self.forward(-dist)
141
142    def left(self, angle: float = None) -> None:
143        """Turn the turtle left by the given angle.
144
145        Args:
146            angle (float, optional): The angle to turn left. Defaults to self.def_angle.
147        """
148        if angle is None:
149            angle = self.def_angle
150        self._angle += angle
151
152    def right(self, angle: float = None) -> None:
153        """Turn the turtle right by the given angle.
154
155        Args:
156            angle (float, optional): The angle to turn right. Defaults to self.def_angle.
157        """
158        if angle is None:
159            angle = self.def_angle
160        self._angle -= angle
161
162    def turn_around(self) -> None:
163        """Turn the turtle around by 180 degrees.
164
165        Rotates the turtle 180 degrees from its current direction.
166        """
167        if self.in_degrees:
168            self._angle += 180
169        else:
170            self._angle += pi
171
172
173    def pen_up(self) -> None:
174        """Lift the pen.
175
176        Stops drawing and saves the current path when the turtle moves.
177        """
178        self.pen_is_down = False
179        self.lists.append(self.current_list)
180        self.current_list = []
181
182    def pen_down(self) -> None:
183        """Lower the pen.
184
185        Enables drawing when the turtle moves and adds the current position
186        to the current path.
187        """
188        self.pen_is_down = True
189        self.current_list.append(self.pos)
190
191    def move_to(self, pos: tuple) -> None:
192        """Move the turtle to the given position.
193
194        Args:
195            pos (tuple): The target position as (x, y) coordinates.
196        """
197        self.pos = pos
198        if self.pen_is_down:
199            self.current_list.append(self.pos)
200
201
202    def push(self) -> None:
203        """Save the current state of the turtle.
204
205        Stores the current position, angle, and pen state for later retrieval.
206        """
207        state = State(self.pos, self._angle, self.pen_is_down)
208        self.stack.append(state)
209
210    def pop(self) -> None:
211        """Restore the last saved state of the turtle.
212
213        Retrieves the most recently saved state and restores the turtle to it.
214        """
215        state = self.stack.pop()
216        self.pos = state.pos
217        self._angle = state.angle
218        self.pen_is_down = state.pen_is_down
219        self.lists.append(self.current_list)
220        self.current_list = [self.pos]
221
222    def reset(self) -> None:
223        """Reset the turtle to its initial state.
224
225        Appends the current shape to the batch and resets position, angle,
226        and pen state.
227        """
228        self.append(self.current_shape)
229        self.pos = (0, 0)
230        if self.in_degrees:
231            self._angle = 0
232        else:
233            self._angle = pi / 2
234        self.current_list = [self.pos]
235        self.pen_is_down = True
236
237    # aliases
238    def _set_aliasess(self) -> None:
239        """Set up aliases for turtle methods.
240
241        Creates shorthand method names commonly used in turtle graphics.
242        """
243        self.fd = self.forward
244        self.bk = self.backward
245        self.lt = self.left
246        self.rt = self.right
247        self.pu = self.pen_up
248        self.pd = self.pen_down
249        self.goto = self.move_to

A Turtle graphics variant, with a twist.

This class implements a turtle graphics system that can be used to draw geometric shapes and patterns.

Arguments:
  • *args: Variable length argument list passed to the parent class.
  • in_degrees (bool, optional): Whether angles are measured in degrees. Defaults to False.
  • **kwargs: Arbitrary keyword arguments passed to the parent class.
Turtle(*args: Any, in_degrees: bool = False, **kwargs: Any)
40    def __init__(self, *args: Any, in_degrees: bool = False, **kwargs: Any) -> None:
41        self.pos = (0, 0)
42        self.stack = []
43        self.lists = []
44        self.current_list = [self.pos]
45        super().__init__([], *args, **kwargs)
46        self.pen_is_down = True
47        self._set_aliasess()
48        self.in_degrees = in_degrees
49        if in_degrees:
50            self.def_angle = 90
51        else:
52            self.def_angle = pi / 2
53        self.def_dist = 20
54        # start facing north
55        if in_degrees:
56            self._angle = 90
57        else:
58            self._angle = pi / 2

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.
pos
stack
lists
current_list
pen_is_down
in_degrees
def_dist
angle: float
60    @property
61    def angle(self) -> float:
62        """Return the current angle of the turtle.
63
64        The angle is clamped to the appropriate range based on the angle mode.
65
66        Returns:
67            float: The current angle, normalized to 0-360 degrees or 0-2π radians.
68        """
69        if self.in_degrees:
70            res = self._angle % 360
71        else:
72            res = self._angle % (2 * pi)
73
74        return res

Return the current angle of the turtle.

The angle is clamped to the appropriate range based on the angle mode.

Returns:

float: The current angle, normalized to 0-360 degrees or 0-2π radians.

def forward(self, dist: float = None) -> None:
105    def forward(self, dist: float = None) -> None:
106        """Move the turtle forward by the given distance.
107
108        Moves the turtle and draws a line if the pen is down.
109
110        Args:
111            dist (float, optional): The distance to move forward. Defaults to self.def_dist.
112        """
113        x, y = self._forward_pos(dist)[:2]
114        self.pos = (x, y)
115        if self.pen_is_down:
116            self.current_list.append(self.pos)

Move the turtle forward by the given distance.

Moves the turtle and draws a line if the pen is down.

Arguments:
  • dist (float, optional): The distance to move forward. Defaults to self.def_dist.
def go(self, dist: float = None) -> None:
118    def go(self, dist: float = None) -> None:
119        """Move the turtle forward without drawing.
120
121        Moves the turtle regardless of the pen state, and doesn't draw.
122        Saves the current path and starts a new one.
123
124        Args:
125            dist (float, optional): The distance to move forward. Defaults to self.def_dist.
126        """
127        x, y = self._forward_pos(dist)[:2]
128        self.pos = (x, y)
129        self.lists.append(self.current_list)
130        self.current_list = [self.pos]

Move the turtle forward without drawing.

Moves the turtle regardless of the pen state, and doesn't draw. Saves the current path and starts a new one.

Arguments:
  • dist (float, optional): The distance to move forward. Defaults to self.def_dist.
def backward(self, dist: float = None) -> None:
132    def backward(self, dist: float = None) -> None:
133        """Move the turtle backward by the given distance.
134
135        Args:
136            dist (float, optional): The distance to move backward. Defaults to self.def_dist.
137        """
138        if dist is None:
139            dist = self.def_dist
140        self.forward(-dist)

Move the turtle backward by the given distance.

Arguments:
  • dist (float, optional): The distance to move backward. Defaults to self.def_dist.
def left(self, angle: float = None) -> None:
142    def left(self, angle: float = None) -> None:
143        """Turn the turtle left by the given angle.
144
145        Args:
146            angle (float, optional): The angle to turn left. Defaults to self.def_angle.
147        """
148        if angle is None:
149            angle = self.def_angle
150        self._angle += angle

Turn the turtle left by the given angle.

Arguments:
  • angle (float, optional): The angle to turn left. Defaults to self.def_angle.
def right(self, angle: float = None) -> None:
152    def right(self, angle: float = None) -> None:
153        """Turn the turtle right by the given angle.
154
155        Args:
156            angle (float, optional): The angle to turn right. Defaults to self.def_angle.
157        """
158        if angle is None:
159            angle = self.def_angle
160        self._angle -= angle

Turn the turtle right by the given angle.

Arguments:
  • angle (float, optional): The angle to turn right. Defaults to self.def_angle.
def turn_around(self) -> None:
162    def turn_around(self) -> None:
163        """Turn the turtle around by 180 degrees.
164
165        Rotates the turtle 180 degrees from its current direction.
166        """
167        if self.in_degrees:
168            self._angle += 180
169        else:
170            self._angle += pi

Turn the turtle around by 180 degrees.

Rotates the turtle 180 degrees from its current direction.

def pen_up(self) -> None:
173    def pen_up(self) -> None:
174        """Lift the pen.
175
176        Stops drawing and saves the current path when the turtle moves.
177        """
178        self.pen_is_down = False
179        self.lists.append(self.current_list)
180        self.current_list = []

Lift the pen.

Stops drawing and saves the current path when the turtle moves.

def pen_down(self) -> None:
182    def pen_down(self) -> None:
183        """Lower the pen.
184
185        Enables drawing when the turtle moves and adds the current position
186        to the current path.
187        """
188        self.pen_is_down = True
189        self.current_list.append(self.pos)

Lower the pen.

Enables drawing when the turtle moves and adds the current position to the current path.

def move_to(self, pos: tuple) -> None:
191    def move_to(self, pos: tuple) -> None:
192        """Move the turtle to the given position.
193
194        Args:
195            pos (tuple): The target position as (x, y) coordinates.
196        """
197        self.pos = pos
198        if self.pen_is_down:
199            self.current_list.append(self.pos)

Move the turtle to the given position.

Arguments:
  • pos (tuple): The target position as (x, y) coordinates.
def push(self) -> None:
202    def push(self) -> None:
203        """Save the current state of the turtle.
204
205        Stores the current position, angle, and pen state for later retrieval.
206        """
207        state = State(self.pos, self._angle, self.pen_is_down)
208        self.stack.append(state)

Save the current state of the turtle.

Stores the current position, angle, and pen state for later retrieval.

def pop(self) -> None:
210    def pop(self) -> None:
211        """Restore the last saved state of the turtle.
212
213        Retrieves the most recently saved state and restores the turtle to it.
214        """
215        state = self.stack.pop()
216        self.pos = state.pos
217        self._angle = state.angle
218        self.pen_is_down = state.pen_is_down
219        self.lists.append(self.current_list)
220        self.current_list = [self.pos]

Restore the last saved state of the turtle.

Retrieves the most recently saved state and restores the turtle to it.

def reset(self) -> None:
222    def reset(self) -> None:
223        """Reset the turtle to its initial state.
224
225        Appends the current shape to the batch and resets position, angle,
226        and pen state.
227        """
228        self.append(self.current_shape)
229        self.pos = (0, 0)
230        if self.in_degrees:
231            self._angle = 0
232        else:
233            self._angle = pi / 2
234        self.current_list = [self.pos]
235        self.pen_is_down = True

Reset the turtle to its initial state.

Appends the current shape to the batch and resets position, angle, and pen state.

def add_digits(n: int) -> int:
252def add_digits(n: int) -> int:
253    """Return the sum of the digits of n.
254
255    Spirolateral helper function that adds all digits in a number.
256
257    Args:
258        n (int): The number to process.
259
260    Returns:
261        int: The sum of all digits in n.
262
263    Examples:
264        10 -> 1 + 0 -> 1
265        123 -> 1 + 2 + 3 -> 6
266    """
267    return sum((int(x) for x in str(n)))

Return the sum of the digits of n.

Spirolateral helper function that adds all digits in a number.

Arguments:
  • n (int): The number to process.
Returns:

int: The sum of all digits in n.

Examples:

10 -> 1 + 0 -> 1 123 -> 1 + 2 + 3 -> 6

def spirolateral( sequence: Sequence, angle: float, cycles: int = 15, multiplier: float = 50) -> Turtle:
270def spirolateral(
271    sequence: Sequence, angle: float, cycles: int = 15, multiplier: float = 50
272) -> Turtle:
273    """Draw a spirolateral with the given sequence and angle.
274
275    Args:
276        sequence (Sequence): Sequence of numbers determining segment lengths.
277        angle (float): Angle in degrees for turns.
278        cycles (int, optional): Number of cycles to draw. Defaults to 15.
279        multiplier (float, optional): Scaling factor for segment lengths. Defaults to 50.
280
281    Returns:
282        Turtle: The turtle object used for drawing.
283    """
284    turtle = Turtle(in_degrees=True)
285    count = 0
286    while count < cycles:
287        for i in sequence:
288            turtle.forward(multiplier * add_digits(i))
289            turtle.right(180 - angle)
290            count += 1
291    return turtle

Draw a spirolateral with the given sequence and angle.

Arguments:
  • sequence (Sequence): Sequence of numbers determining segment lengths.
  • angle (float): Angle in degrees for turns.
  • cycles (int, optional): Number of cycles to draw. Defaults to 15.
  • multiplier (float, optional): Scaling factor for segment lengths. Defaults to 50.
Returns:

Turtle: The turtle object used for drawing.

def spiral( turtle: Turtle, side: float, angle: float, delta: float, cycles: int = 15) -> Turtle:
294def spiral(turtle: Turtle, side: float, angle: float, delta: float, cycles: int = 15) -> Turtle:
295    """Draw a spiral with the given side, angle, delta, and cycles.
296
297    Args:
298        turtle (Turtle): The turtle object to use for drawing.
299        side (float): Initial length of the side.
300        angle (float): Angle to turn after drawing each side.
301        delta (float): Amount to increase the side length in each step.
302        cycles (int, optional): Number of segments to draw. Defaults to 15.
303
304    Returns:
305        Turtle: The turtle object used for drawing.
306    """
307    t = turtle
308    count = 0
309    while count < cycles:
310        t.forward(side)
311        t.right(angle)
312        side += delta
313        count += 1
314    return t

Draw a spiral with the given side, angle, delta, and cycles.

Arguments:
  • turtle (Turtle): The turtle object to use for drawing.
  • side (float): Initial length of the side.
  • angle (float): Angle to turn after drawing each side.
  • delta (float): Amount to increase the side length in each step.
  • cycles (int, optional): Number of segments to draw. Defaults to 15.
Returns:

Turtle: The turtle object used for drawing.