Create Amazing Graphics with Python

Introduction

This project demonstrates how to create stunning fractal tree graphics using Python’s Turtle module. A fractal tree is a recursive structure that repeats a simple pattern at smaller scales, creating complex and intricate designs. The Turtle module is perfect for drawing such graphics because of its simple commands and ability to visualize recursion easily.

Prerequisites

To work on this project, you should have:

  • Basic knowledge of Python programming.
  • Familiarity with functions and recursion in Python.

Learning Objectives

By the end of this project, you will:

  • Understand how to use Python’s Turtle module for graphics.
  • Learn the concept of recursion and how to implement it.
  • Gain experience in creating fractal patterns using simple geometric transformations.

Installation Guide

To run this project, you need to have Python installed on your system. You can download it from python.org.

  1. Install Python: Follow the instructions on the Python website to install Python for your operating system.
  2. Install Turtle module: Turtle is included in the Python standard library, so you don’t need to install it separately. Just ensure that Python is properly installed.

Project Steps

  1. Initialize the Turtle environment: Set up the screen and the Turtle object.
  2. Define a recursive function: Create a function that draws a branch of the tree, reducing its length at each step.
  3. Call the function multiple times: Draw multiple branches with different angles and lengths to form a fractal tree.
  4. Customize colors and speed: Use different colors and adjust the speed for visual appeal.

Code

				
					import turtle as tu

roo = tu.Turtle()        # Turtle object
wn = tu.Screen()         # Screen Object
wn.bgcolor("black")      # Screen Bg color
wn.title("Fractal Tree Pattern")
roo.left(90)             # moving the turtle 90 degrees towards left
roo.speed(20)            # setting the speed of the turtle

def draw(l):             # recursive function taking length 'l' as argument
    if (l < 10): return
    else:
        roo.pensize(2)          # Setting Pensize
        roo.pencolor("yellow")  # Setting Pencolor as yellow
        roo.forward(l)          # moving turtle forward by 'l'
        roo.left(30)            # moving the turtle 30 degrees towards left
        draw(3 * l / 4)         # drawing a fractal on the left of the turtle object 'roo' with 3/4th of its length
        roo.right(60)           # moving the turtle 60 degrees towards right
        draw(3 * l / 4)         # drawing a fractal on the right of the turtle object 'roo' with 3/4th of its length
        roo.left(30)            # moving the turtle 30 degrees towards left
        roo.pensize(2)
        roo.backward(l)         # returning the turtle back to its original psition
        
draw(20)  # drawing 20 times
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("magenta")  # magenta
        roo.forward(l)
        roo.left(30)
        draw(3 * l / 4)
        roo.right(60)
        draw(3 * l / 4)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(20)
roo.left(270)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("red")  # red
        roo.forward(l)
        roo.left(30)
        draw(3 * l / 4)
        roo.right(60)
        draw(3 * l / 4)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(20)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor('#FFF8DC')  # white
        roo.forward(l)
        roo.left(30)
        draw(3 * l / 4)
        roo.right(60)
        draw(3 * l / 4)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(20)

def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor("lightgreen")  # lightgreen
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor("red")  # red
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)
roo.left(270)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor("yellow")  # yellow
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor('#FFF8DC')  # white
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)

def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("cyan")  # cyan
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("yellow")  # yellow
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
roo.left(270)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("magenta")  # magenta
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor('#FFF8DC')  # white
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
wn.exitonclick()
				
			

Code

				
					import turtle as tu

roo = tu.Turtle()        # Turtle object
wn = tu.Screen()         # Screen Object
wn.bgcolor("black")      # Screen Bg color
wn.title("Fractal Tree Pattern")
roo.left(90)             # moving the turtle 90 degrees towards left
roo.speed(20)            # setting the speed of the turtle

def draw(l):             # recursive function taking length 'l' as argument
    if (l < 10): return
    else:
        roo.pensize(2)          # Setting Pensize
        roo.pencolor("yellow")  # Setting Pencolor as yellow
        roo.forward(l)          # moving turtle forward by 'l'
        roo.left(30)            # moving the turtle 30 degrees towards left
        draw(3 * l / 4)         # drawing a fractal on the left of the turtle object 'roo' with 3/4th of its length
        roo.right(60)           # moving the turtle 60 degrees towards right
        draw(3 * l / 4)         # drawing a fractal on the right of the turtle object 'roo' with 3/4th of its length
        roo.left(30)            # moving the turtle 30 degrees towards left
        roo.pensize(2)
        roo.backward(l)         # returning the turtle back to its original psition
        
draw(20)  # drawing 20 times
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("magenta")  # magenta
        roo.forward(l)
        roo.left(30)
        draw(3 * l / 4)
        roo.right(60)
        draw(3 * l / 4)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(20)
roo.left(270)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("red")  # red
        roo.forward(l)
        roo.left(30)
        draw(3 * l / 4)
        roo.right(60)
        draw(3 * l / 4)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(20)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor('#FFF8DC')  # white
        roo.forward(l)
        roo.left(30)
        draw(3 * l / 4)
        roo.right(60)
        draw(3 * l / 4)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(20)

def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor("lightgreen")  # lightgreen
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor("red")  # red
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)
roo.left(270)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor("yellow")  # yellow
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(3)
        roo.pencolor('#FFF8DC')  # white
        roo.forward(l)
        roo.left(30)
        draw(4 * l / 5)
        roo.right(60)
        draw(4 * l / 5)
        roo.left(30)
        roo.pensize(3)
        roo.backward(l)

draw(40)

def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("cyan")  # cyan
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("yellow")  # yellow
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
roo.left(270)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor("magenta")  # magenta
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
roo.right(90)
roo.speed(2000)

# recursion
def draw(l):
    if (l < 10): return
    else:
        roo.pensize(2)
        roo.pencolor('#FFF8DC')  # white
        roo.forward(l)
        roo.left(30)
        draw(6 * l / 7)
        roo.right(60)
        draw(6 * l / 7)
        roo.left(30)
        roo.pensize(2)
        roo.backward(l)

draw(60)
wn.exitonclick()
				
			

Pseudo Code explaining this Python Project

				
					The pseudo code for drawing the fractal tree is as follows:
function draw(length)
    if length < 10
        return
    else
        set pen size and color
        move forward by length
        turn left by 30 degrees
        draw(3/4 of length)
        turn right by 60 degrees
        draw(3/4 of length)
        turn left by 30 degrees
        move backward by length

				
			

Pseudo Code explaining this Python Project

				
					The pseudo code for drawing the fractal tree is as follows:
function draw(length)
    if length < 10
        return
    else
        set pen size and color
        move forward by length
        turn left by 30 degrees
        draw(3/4 of length)
        turn right by 60 degrees
        draw(3/4 of length)
        turn left by 30 degrees
        move backward by length

				
			

Flow Chart

Code Explanation

  • Turtle Initialization: The turtle roo is initialized to draw the tree. The turtle’s speed and initial direction are set up.
  • Recursive Function: The draw function is defined to draw branches of the tree recursively. If the length of the branch is less than 10, the recursion stops.
  • Branch Drawing: For each recursive call, the turtle draws a branch, turns left, and draws the left subtree, then turns right to draw the right subtree.
  • Color and Pensize: Different colors and pen sizes are used to enhance the visual appeal of the fractal pattern.
  • Multiple Patterns: The draw function is called multiple times with different lengths and colors to create a diverse fractal design.

Challenges and Solutions

  • Understanding Recursion: Recursion can be complex, especially when visualizing its effect. Start with smaller values for l to see how recursion works.
  • Turtle Speed: The turtle may draw slowly with complex patterns. Increasing the speed using roo.speed(2000) helps visualize the pattern faster.
  • Color Overlap: Overlapping colors can make the pattern less appealing. Adjust the angles and branch lengths to reduce overlap.

Testing

  • Modify Parameters: Experiment with different lengths, angles, and colors to see how the pattern changes.
  • Edge Cases: Test with very small values for l to ensure the recursion stops as expected.

Additional Resources

FAQs

  1. What is the Turtle module used for?
    The Turtle module is used for creating simple graphics and drawings in Python. It provides a virtual canvas to visualize drawings through a turtle object.
  2. How does recursion work in this project?
    Recursion is used to draw branches of the fractal tree by calling the same function with a reduced branch length, creating a self-similar pattern.
  3. Can I use different shapes for the branches?
    Yes, you can experiment with different angles, shapes, and sizes for the branches by modifying the turtle’s movements in the draw function.
  4. How can I save the generated pattern as an image?
    You can use screen capture tools to save the window as an image, or use the turtle.getcanvas().postscript() method to export the drawing.
  5. Why does the turtle move back after drawing a branch?
    Moving back to the original position ensures that the turtle is correctly positioned to draw the next branch without overlapping with the previous one.

Project by Nimisha Agrawal and Documented by Aakarsh Pandey, Team edSlash.