One of the great things about Python Turtle Graphics is how it gives you instant visual feedback on what you program is doing. This makes it a very powerful tool for exploring many topics is Computer Science and programming in general. This article is about using Python Turtle Graphics to draw a fractal pattern, using an important programming technique called recursion. You can read more about recursion in general in this blog post. Here we will focus more on how Turtle Graphics is used to draw the pattern.
You can see the program in action here:
A fractal is repeating pattern which appears similar at different levels of magnification.
If you are a beginner at Python programming, the main code for this program will probably be a bit too advanced to understand. However, Even as a beginner you can get quite a bit of mileage out of playing with the values of these constants:
SPEED = 1
BG_COLOR = "blue"
PEN_COLOR = "lightgreen"
PEN_WIDTH = 5
FRACTAL_DEPTH = 3
Change their values and see what effect the have. For colours most common color names are possible – just remember to put the name inside ""
s like "dark orchid"
. There is a full list of possible colors available here.
A classic example of fractals in nature is fern leaves – notice how the original shape is repeated at a smaller scale within the leaf.
H-Tree Fractal with Python Turtle Graphics
The H-Tree Fractal is a fairly simple fractal with an easy rule for its construction.
The H-fractal is a fractal constructed by starting with the line segments corresponding to a capital letter H, then repeatedly placing smaller H’s centered at the top and bottom of each free vertical segment.
It can be described in other ways, and there are variations on the exact measurements, but for the way we will implement it, that description is the most helpful.
This is best understood with pictures:
Here is level 0 (Python folk like to count from zero….)
The next level or depth add H shapes at each of the corners of the previous version:
… and the pattern repeats..
The next level:
Python Code for Fractal H-Tree with Turtle Graphics
The most important work done by this program is by the calls to
recursive_draw(tur, x, y, width, height, count)
The arguments are for the turtle we wish to do our drawing, the x, y
coordinates where will will begin drawing our H, and the width/height for the H required at this particular level. Note that as the function calls itself to draw new H shpaes, these arguments change!
In order to understand how this program really works, you will need to look away from your screen temporarily. Get some plain paper or graph paper and a pencil, draw an x- and a y- axis, and start marking in some coordinate values. You can check your work by uncommenting the print
statement inside of draw_line()
to get a read on what is happening inside the program. For example:
recursive_draw
is initially called with recursive_draw(artist, - DRAWING_WIDTH / 2, - DRAWING_HEIGHT / 2, DRAWING_WIDTH, DRAWING_HEIGHT, FRACTAL_DEPTH)
This initial call to draw_line()
, which is called from recursive_draw()
, will use these coordinates:
Two very important things to note without which recursion cannot work are:
- The base case
- The recursive step
These are labeled with comments in the code. All recursive algorithms must approach a base case or they will never stop executing, until available memory runs out.
Python Code Listing for H-Tree Fractal
Here is the full listing for the Python Turtle Graphics H-tree fractal:
"""
H-Tree Fractal using recursion and Turtle Graphics.
Robin Andrews - https://compucademy.net/
"""
import turtle
SPEED = 5
BG_COLOR = "blue"
PEN_COLOR = "lightgreen"
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
DRAWING_WIDTH = 700
DRAWING_HEIGHT = 700
PEN_WIDTH = 5
TITLE = "H-Tree Fractal with Python Turtle Graphics"
FRACTAL_DEPTH = 3
def draw_line(tur, pos1, pos2):
# print("Drawing from", pos1, "to", pos2) # Uncomment for tracing the algorithm.
tur.penup()
tur.goto(pos1[0], pos1[1])
tur.pendown()
tur.goto(pos2[0], pos2[1])
def recursive_draw(tur, x, y, width, height, count):
draw_line(
tur,
[x + width * 0.25, height // 2 + y],
[x + width * 0.75, height // 2 + y],
)
draw_line(
tur,
[x + width * 0.25, (height * 0.5) // 2 + y],
[x + width * 0.25, (height * 1.5) // 2 + y],
)
draw_line(
tur,
[x + width * 0.75, (height * 0.5) // 2 + y],
[x + width * 0.75, (height * 1.5) // 2 + y],
)
if count <= 0: # The base case
return
else: # The recursive step
count -= 1
# Top left
recursive_draw(tur, x, y, width // 2, height // 2, count)
# Top right
recursive_draw(tur, x + width // 2, y, width // 2, height // 2, count)
# Bottom left
recursive_draw(tur, x, y + width // 2, width // 2, height // 2, count)
# Bottom right
recursive_draw(tur, x + width // 2, y + width // 2, width // 2, height // 2, count)
if __name__ == "__main__":
# Screen setup
screen = turtle.Screen()
screen.setup(SCREEN_WIDTH, SCREEN_HEIGHT)
screen.title(TITLE)
screen.bgcolor(BG_COLOR)
# Turtle artist (pen) setup
artist = turtle.Turtle()
artist.hideturtle()
artist.pensize(PEN_WIDTH)
artist.color(PEN_COLOR)
artist.speed(SPEED)
# Initial call to recursive draw function
recursive_draw(artist, - DRAWING_WIDTH / 2, - DRAWING_HEIGHT / 2, DRAWING_WIDTH, DRAWING_HEIGHT, FRACTAL_DEPTH)
# Every Python Turtle program needs this (or an equivalent) to work correctly.
turtle.done()
Happy computing!