DEV Community

loading...
Cover image for How to draw a spiral with Python turtle

How to draw a spiral with Python turtle

taarimalta
Updated on ・4 min read

In the previous post , we learnt how to draw a filled star using Python turtle. In this article lets do a spiral because why not.

Circle

We can easily draw a circle using turtle.circle but we're going to draw it in a different way

import turtle as t

t.tracer(10,1)

for i in range(360):
 t.forward(1)
 t.right(1)


t.update()
Enter fullscreen mode Exit fullscreen mode

In the code above, tracer and update commands are used to increase the drawing speed. We can remove them if we want.

image

The turtle moves a step forward then turns right by 1 degree. By the time the loop completes the turtle has turned by 360 degrees so has completed a full rotation and we get a circle

Increasing radius and rate of turn

Instead of moving at a constant distance what would happen if the turtle moves more on every iteration

for i in range(360):
 t.forward(i)
 t.right(1)
Enter fullscreen mode Exit fullscreen mode

i replaces 1 as parameter to forward

image

We'll get something that quickly moves past the screen. Let's see if we can make it turn faster

for i in range(360):
 t.forward(i)
 t.right(20)
Enter fullscreen mode Exit fullscreen mode

20 replaces 1 as parameter to right

image

Here's our spiral. But notice that the curve isn't smooth

Make the curve smoother

Let's see how we can make the spiral curve smoother. But first try out the following code

# Quadrant 1

t1 = t.Turtle()
t1.penup()
t1.goto(125, 125)
t1.pendown()
t1.circle(100)

# Quadrant 2

t2 = t.Turtle()
t2.penup()
t2.goto(-125, 125)
t2.pendown()
t2.circle(100, 270)

# Quadrant 3

t2 = t.Turtle()
t2.penup()
t2.goto(-125, -125)
t2.pendown()
t2.circle(100, 180)

# Quadrant 4

t3 = t.Turtle()
t3.penup()
t3.goto(125, -125)
t3.pendown()
t3.circle(100, 90)

Enter fullscreen mode Exit fullscreen mode

Code prints 4 circle sections in 4 quadrants

image

We can use turtle's circle function to draw a portion of a circle. We can use this feature to make our turtle move in a smoother way along the spiral

import turtle as t

t.tracer(10,1)

for i in range(360):
 t.circle(i,20)

t.update()
Enter fullscreen mode Exit fullscreen mode

forward and right function calls are replaced by circle

The circle function above moves the turtle forward but also turns by a certain angle. Here's what we get

image

We now have a smooth spiral!

Add more arms

But what if we wanted something that looks a little different - like a spiral galaxy or the milky way? We first need to add more arms.

To do this we're going to create multiple turtles

import turtle as t

t.tracer(10,1)

t1=t.Turtle()
t2=t.Turtle()
t1.setheading(0) # Looks to the right
t2.setheading(180) # Looks to the right

for x in range(360):
 radius = x
 angle = 1
 t1.circle(radius,angle)
 t2.circle(radius,angle)

t.update()

Enter fullscreen mode Exit fullscreen mode

In the code above, t1 and t2 are two turtles that have been initially set to look to the right and to the left respectively using the setheading command

image

Both turtle have now started their own spiral in their own direction. Now let's see how to make this more configurable

import turtle as t
t.tracer(10,1)

N = 10
angle = 1

turtles = []
for position in range(N):
  look_at = 360/N*position
  new = t.Turtle()
  new.setheading(look_at)
  turtles.append(new)

for radius in range(360):
  for my in turtles:
    my.circle(radius, angle)


t.update()
Enter fullscreen mode Exit fullscreen mode

We have simply changed the code such that any number of turtles can be created by changing N, and they all look towards different directions in a symmetric manner

image

Interestingly the spiral arms seem to intersect. We can prevent that from happening by making a few adjustments

import turtle as t

t.tracer(10,1)

N = 10
angle = 30

turtles = []
for position in range(N):
  look_at = 360/N*position
  new = t.Turtle()
  new.setheading(look_at)
  turtles.append(new)

for radius in range(360):
  for my in turtles:
    my.circle(radius*radius, angle)

t.update()
Enter fullscreen mode Exit fullscreen mode

We set angle to 30 and we squared the radius

By making the angle of turn on each iteration larger and increasing the rate at which the spiral increases (by squaring the radius - radius*radius) we can prevent the spirals from intersecting. (Note that I found this out by accident)

image

Yayy!

Discussion (0)