thomaso
thomaso

Reputation: 41

Generating square fractals with Python

I need to write a recursive function with level as parameter that generates square fractals. Each square has to have a square in 3 corners.

What it should look like, levels 1, 2, 3, 4 What it should look like, levels 1, 2, 3, 4.

I've tried something but I'm stuck. I get the first part done but then it gets stuck in the loop and I don't know how to continue.

This is what my code looks like:

from turtle import *

def fractal(level):
    global length
    if level == 1:
        forward(length)
        right(90); forward(length)
        right(90); forward(length)
        right(90); forward(length)
        return
    else:
        forward(length)
        length = (length / 2)
        fractal(level - 1)
        length = length * 2
        fractal(level)

length = 100
fractal(4)

Output: and the output

Upvotes: 1

Views: 2888

Answers (2)

cdlane
cdlane

Reputation: 41872

This code is overly complicated for achieving its goal. I see two reasons for that: first your length global complicates things and makes the code non-reentrant (consider two turtles on two threads running this function at the same time.) We need to make length an argument. Second, most folks new to recursion overthink the problem and don't let recursion to do the work for them. I would restructure this as follows:

from turtle import Screen, Turtle

def fractal(level, turtle, length, direction=90):
    for _ in range(3):
        turtle.forward(length)

        if level > 1:
            fractal(level - 1, turtle, length / 2, -direction)

        turtle.right(direction)

    turtle.forward(length)
    turtle.right(direction)

screen = Screen()

turtle = Turtle()
turtle.speed('fastest')  # because I have no patience

fractal(4, turtle, 100)

turtle.hideturtle()
screen.exitonclick()

the problem is that I HAVE to write a recursive function that can only use level as a parameter, nothing else. That's why I have length as a global variable.

We can lower the quality of the code to achieve your newly stated goals.

Note that without the if statement both programs simply draw a square, the basis of the fractal. It's the if statement that introduces the recursion and the modifications that make the images smaller and the recursion ultimately end:

from turtle import *

def fractal(level):
    global length, direction

    for _ in range(3):
        forward(length)

        if level > 1:
            length /= 2
            direction = - direction
            fractal(level - 1)
            direction = - direction
            length *= 2

        right(direction)

    forward(length)
    right(direction)

length = 100
direction = 90

fractal(4)

hideturtle()
exitonclick()

enter image description here

Upvotes: 1

HNMN3
HNMN3

Reputation: 542

You need to break the code somewhere so that it can return back to starting point. And in your code the turtle keeps turning after drawing square, for three corners you need to turn it twice. Check below code. It's giving expected output.

import turtle


def fractal(level, tob, turn_direction=2):
    global length
    if level == 1:
        tob.forward(length)
        tob.left(90)
        tob.forward(length)
        tob.left(90)
        tob.forward(length)
        tob.left(90)
        tob.forward(length)
        return
    else:
        tob.forward(length)
        length /= 2
        fractal(level - 1, tob)
        length *= 2
        if turn_direction == 0:
            tob.forward(length)
            return
        fractal(level, tob, turn_direction=turn_direction - 1)


length = 100
wn = turtle.Screen()
wn.bgcolor("light green")
wn.title("Turtle")
tur_ob = turtle.Turtle()

fractal(4, tur_ob)

Upvotes: 0

Related Questions