Рисование фрактального дерева в 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)

Но я как бы застрял в том, как работать, потому что мне нужно достать это дерево. Вот что я пытаюсь произвести:

Фрактальное дерево

Кто-нибудь может сказать мне, что я делаю не так?

3 ответа

Мне очень понравился ответ cdlane, поэтому я cdlane поиграл с кодом. Дерево теперь выглядит намного лучше, а код гораздо более читабельным, поэтому я думаю, что им стоит поделиться.

Код:

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()

Ваш код в основном правильный, вам в основном нужно настроить параметры. Дерево примеров, которое вы пытаетесь сопоставить, больше, чем то, что вы рисуете (вероятно, уменьшено на этом изображении), поэтому увеличьте l параметр. Дерево примеров имеет на несколько уровней рекурсии больше, чем ваш, поэтому увеличьте lv параметр.

Наконец, вам нужно сбросить ширину пера в зависимости от уровня рекурсии (и отменить его при выходе). Следующая доработка вашего кода делает это, но требует дальнейшей тонкой настройки:

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()

Вот как написать это в 17 строках (без функций):

import turtle
for i in range(2048): #how many branches(2 ** depth)
turtle.goto(0,0) #beginning of tree
turtle.setheading(90) #direction(try 270 for root effect)
turtle.hideturtle() #MUCH faster drawing and better view
a = str(bin(i)).replace('0b','') #binary is for two branches('0b' ignored)
a = list(str('0' * (11 - len(list(a)))) + a) #cake filling
turtle.speed(0) #no animation
turtle.pendown() #you probably wanna draw it
for f in range(len(a)): #depth
    b = 200 #primary branch length
    for l in range(f + 1): #more depth less length
        b /= 1.5 #the difference of branch length(b = b / float)
    turtle.width(b / 10) #branch width(for better effect)
    turtle.forward(b) #drawing a branch
    turtle.right((int(a[f]) - 0.5) * 60) #change 60 to any angle
turtle.penup() #also try without this line
Другие вопросы по тегам