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