Drawing a fractal tree in Python, not sure how to proceed

16,903

Solution 1

I really liked @cdlane answer, so I played with the code for a while. The tree now looks much better, and the code is much more readable, so I think it is worth sharing.

enter image description here

The code:

import turtle

WIDTH = 15
BRANCH_LENGTH = 120
ROTATION_LENGTH = 27


class Tree_Fractal(turtle.Turtle):
    def __init__(self, level):
        super(Tree_Fractal, self).__init__()
        self.level = level
        self.hideturtle()
        self.speed('fastest')
        self.left(90)
        self.width(WIDTH)
        self.penup()
        self.back(BRANCH_LENGTH * 1.5)
        self.pendown()
        self.forward(BRANCH_LENGTH)
        self.draw_tree(BRANCH_LENGTH, level)

    def draw_tree(self, branch_length, level):
        width = self.width()
        self.width(width * 3. / 4.)
        branch_length *= 3. / 4.
        self.left(ROTATION_LENGTH)
        self.forward(branch_length)

        if level > 0:
            self.draw_tree(branch_length, level - 1)
        self.back(branch_length)
        self.right(2 * ROTATION_LENGTH)
        self.forward(branch_length)

        if level > 0:
            self.draw_tree(branch_length, level - 1)
        self.back(branch_length)
        self.left(ROTATION_LENGTH)

        self.width(width)


if __name__ == '__main__':
    tree_level = 11  # choose
    tree = Tree_Fractal(tree_level)
    turtle.done()

Solution 2

Your code is basically correct, you mostly need to adjust your parameters. The example tree you're trying to match is larger than what you are drawing (likely reduced in that image) so increase your l parameter. The example tree has a couple more levels of recursion than yours so increase your lv parameter.

Finally, you need to reset the pen width based on the recursion level (and unset it on your way out.) The following rework of your code does this but needs further fine tuning:

import turtle

t = turtle.Turtle(shape="turtle")

t.lt(90)

lv = 13
l = 120
s = 17

t.width(lv)

t.penup()
t.bk(l)
t.pendown()
t.fd(l)

def draw_tree(l, level):
    width = t.width()  # save the current pen width

    t.width(width * 3.0 / 4.0)  # narrow the pen width

    l = 3.0 / 4.0 * l

    t.lt(s)
    t.fd(l)

    if level < lv:
        draw_tree(l, level + 1)
    t.bk(l)
    t.rt(2 * s)
    t.fd(l)

    if level < lv:
        draw_tree(l, level + 1)
    t.bk(l)
    t.lt(s)

    t.width(width)  # restore the previous pen width

t.speed("fastest")

draw_tree(l, 2)

turtle.done()
Share:
16,903
Admin
Author by

Admin

Updated on June 26, 2022

Comments

  • Admin
    Admin almost 2 years

    I have this so far in python

    import turtle
    import math
    t = turtle.Turtle()
    t.shape("turtle")
    t.lt(90)
    
    lv = 11
    l  = 100
    s  = 17
    
    t.penup()
    t.bk(l)
    t.pendown()
    t.fd(l)
    
    def draw_tree(l, level):
        l = 3.0/4.0*l
        t.lt(s)
        t.fd(l)
        level +=1
        if level<lv:
            draw_tree(l, level)
    
        t.bk(l)
        t.rt(2*s)
        t.fd(l)
        if level<=lv:
            draw_tree(l, level)
        t.bk(l)
        t.lt(s)
        level -=1
    
    t.speed(100)        
    draw_tree(l, 2)
    

    But I'm kind of stuck on how to proges, because I need to reach for building this tree. This is what I'm trying to produce:

    Fractal tree

    Can any one tell me what I am doing wrong?