### Lines

Let's start simply to get warmed up.  This will draw a square that is 25 pixels on a side.

```import board

turtle = turtle(board.DISPLAY)
print("Turtle time! Lets draw a simple square")

turtle.pencolor(Color.WHITE)
turtle.pendown()

for _ in range(4):
turtle.forward(25)
turtle.left(90)

while True:
pass```

### Dots

Next, put a 8 pixel radius dot at each corner. Remember that `dot()` doesn't effect the turtle's position or heading, so dots can be easily added to an existing script.

```import board

print("Turtle time! Lets draw a square with dots")

turtle = turtle(board.DISPLAY)
turtle.pendown()

for _ in range(4):
turtle.dot(8)
turtle.left(90)
turtle.forward(25)

while True:
pass ```

### Circles

Circles are a little tricker since the outline starts with the initial turtle position and heading. The nice thing is that the turtle ends up where it started, and with the same heading. The code below moves the turtle to near the right side of the screen and then points it to the left. It then draws 6 circles in different colors, moving left between each. By moving by the diameter we use, the circles don't overlap.

```import board

turtle = turtle(board.DISPLAY)

mycolors = [Color.WHITE, Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE, Color.PURPLE]
turtle.penup()
turtle.forward(130)
turtle.right(180)
turtle.pendown()

for i in range(6):
turtle.pencolor(mycolors[i])
turtle.circle(25)
turtle.penup()
turtle.forward(50)
turtle.pendown()

while True:
pass```

To have them overlap, reduce how far the turtle moves between each one.

### Scaling to the Screen

Since adafruit_turtle can be used on boards with different sized screens, it can be a good idea to scale drawings to fit on the screen. The library will clip drawings to the screen so if you draw off the edge your script won't crash, but the result might not look great. The script below shows an approach to scaling to the screen. It also shows how to detect that the turtle is back where it started, accounting for some rounding error.

```import board

turtle = turtle(board.DISPLAY)
starsize = min(board.DISPLAY.width, board.DISPLAY.height) * 0.9  # 90% of screensize

print("Turtle time! Lets draw a star")

turtle.pencolor(Color.BLUE)

turtle.penup()
turtle.goto(-starsize/2, 0)
turtle.pendown()

start = turtle.pos()
while True:
turtle.forward(starsize)
turtle.left(170)
if abs(turtle.pos() - start) < 1:
break

while True:
pass```

### Using Color

Changing color as you draw can produce startling results, as these scripts show:

```import board

turtle = turtle(board.DISPLAY)
benzsize = min(board.DISPLAY.width, board.DISPLAY.height) * 0.5

print("Turtle time! Lets draw a rainbow benzene")

colors = (Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.PURPLE)

turtle.pendown()
start = turtle.pos()

for x in range(benzsize):
turtle.pencolor(colors[x%6])
turtle.forward(x)
turtle.left(59)

while True:
pass```
```import board

turtle = turtle(board.DISPLAY)

turtle.pendown()

colors = [Color.ORANGE, Color.PURPLE]

for x in range(400):
turtle.pencolor(colors[x % 2])
turtle.forward(x)
turtle.left(91)

while True:
pass```

### Using `circle` for Polygons

Below is a design and script to make it using just lines and turns.

```import board

turtle = turtle(board.DISPLAY)

# turtle.penup()
# turtle.right(45)
# turtle.forward(90)
# turtle.right(75)

turtle.pendown()
for _ in range(21):
for _ in range(6):
turtle.forward(50)
turtle.right(61)
turtle.right(11.1111)

while True:
pass```

You can do something very similar using circles and the step parameter, though you may need to tweak some things since you're dealing with the radius instead of side length. This results is quite a bit less code. The following image and script show this.

```import board

turtle = turtle(board.DISPLAY)

turtle.pendown()
for _ in range(32):
turtle.circle(50, steps=6)
turtle.right(11.1111)

while True:
pass
```

### Fractals

Turtle graphics are quite handy for drawing fractals.

The first example is a hilbert curve.

```import board

def hilbert2(step, rule, angle, depth, t):
if depth > 0:
a = lambda: hilbert2(step, "a", angle, depth - 1, t)
b = lambda: hilbert2(step, "b", angle, depth - 1, t)
left = lambda: t.left(angle)
right = lambda: t.right(angle)
forward = lambda: t.forward(step)
if rule == "a":
left(); b(); forward(); right(); a(); forward(); a(); right(); forward(); b(); left()
if rule == "b":
right(); a(); forward(); left(); b(); forward(); b(); left(); forward(); a(); right()

turtle = turtle(board.DISPLAY)
turtle.penup()

turtle.goto(-80, -80)
turtle.pendown()
hilbert2(5, "a", 90, 5, turtle)

while True:
pass
```

Another interesting fractal is the Sierpinski triangle, shown below.

```import board

def getMid(p1,p2):
return ( (p1+p2) / 2, (p1 + p2) / 2) #find midpoint

def triangle(points, depth):

turtle.penup()
turtle.goto(points, points)
turtle.pendown()
turtle.goto(points, points)
turtle.goto(points, points)
turtle.goto(points, points)

if depth > 0:
triangle([points,
getMid(points, points),
getMid(points, points)],
depth-1)
triangle([points,
getMid(points, points),
getMid(points, points)],
depth-1)
triangle([points,
getMid(points, points),
getMid(points, points)],
depth-1)

turtle = turtle(board.DISPLAY)
big = min(board.DISPLAY.width / 2, board.DISPLAY.height / 2)
little = big / 1.4
seed_points = [[-big, -little],[0,big],[big,-little]] #size of triangle
triangle(seed_points,4)

while True:
pass```

The final example is a Koch snowflake. On the small displays we can get 4 generations before rounding errors start messing things up too much. Even so, it's a nice design. See below.

```import board

def f(side_length, depth, generation):
if depth == 0:
side = turtle.forward(side_length)
else:
side = lambda: f(side_length / 3, depth - 1, generation + 1)
side()
turtle.left(60)
side()
turtle.right(120)
side()
turtle.left(60)
side()

turtle = turtle(board.DISPLAY)

unit= min(board.DISPLAY.width / 3, board.DISPLAY.height / 4)
top_len = unit * 3
print(top_len)
turtle.penup()
turtle.goto(-1.5 * unit, unit)
turtle.pendown()

num_generations = 3
top_side = lambda: f(top_len, num_generations, 0)

top_side()
turtle.right(120)
top_side()
turtle.right(120)
top_side()

while True:
pass```

The script below is much the same, but overlays 3 generations in different colors. Beyond 3, rounding causes subsequent generations to not line up.

```import board

generation_colors = [Color.RED, Color.BLUE, Color.GREEN]

def f(side_length, depth, generation):
if depth == 0:
side = turtle.forward(side_length)
else:
side = lambda: f(side_length / 3, depth - 1, generation + 1)
side()
turtle.left(60)
side()
turtle.right(120)
side()
turtle.left(60)
side()

def snowflake(num_generations, generation_color):
top_side = lambda: f(top_len, num_generations, 0)
turtle.pencolor(generation_color)
top_side()
turtle.right(120)
top_side()
turtle.right(120)
top_side()

turtle = turtle(board.DISPLAY)

unit= min(board.DISPLAY.width / 3, board.DISPLAY.height / 4)
top_len = unit * 3
print(top_len)
turtle.penup()
turtle.goto(-1.5 * unit, unit)
turtle.pendown()

for generations in range(3):
snowflake(generations, generation_colors[generations])
turtle.right(120)

while True:
pass```

## Where to Find More

You can find much more information about turtle graphics as well as example scripts through an Internet search of "turtle python graphics examples" or some variation. Since turtle graphics are mainly in terms of moving and turning they can usually be converted to CircuitPython and the adafruit_turtle library.

Check out these example sites:

This guide was first published on Jul 03, 2019. It was last updated on Jul 03, 2019.