Как установить длину каждой ветви с помощью рекурсивной функции? - PullRequest
0 голосов
/ 24 октября 2019

Я пишу код для создания фрактального дерева в python с использованием модуля tkinter. Я хочу, чтобы дерево соответствовало холсту с каждой новой ветвью, короче и тоньше в зависимости от длины предыдущей ветви. Также с ростом уровня дерева ствол становится короче, чтобы соответствовать размеру холста. Как установить значение y при уменьшении уровня дерева? Также я думаю, что есть некоторая ошибка в вычислении значения x, потому что одна ветвь длиннее другой. Какая ошибка и как ее исправить?

Вот код:

import tkinter as tk
import math

class FractalTree:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("FractalTree")
        self.root.resizable(0, 0)
        self.width = 1000
        self.height = 400
        self.canvas = tk.Canvas(self.root, width = self.width, height = self.height, bg="white")
        self.canvas.pack()
        self.frame = tk.Frame(self.root)
        self.frame.pack()
        self.label = tk.Label(self.frame, text = "Level: ").pack(side = tk.LEFT)
        self.level = tk.StringVar()
        self.entry = tk.Entry(self.frame, textvariable = self.level, justify = tk.RIGHT).pack(side = tk.LEFT)
        self.buttonUp = tk.Button(self.frame, text = "p", font = ("Wingdings 3", 5), command = self.upButton).pack(side = tk.TOP)
        self.buttonDown = tk.Button(self.frame, text = "q", font = ("Wingdings 3", 5), command = self.downButton).pack(side = tk.BOTTOM)
        self.angle = math.pi/6
        self.branchSize = 0.75
        self.branchWidth = 10
        self.root.mainloop()

    def display(self):
        self.canvas.delete("line")
        global treeLevel
        treeLevel = int(self.level.get())-1
        self.yFunc(treeLevel)
        return self.drawBranch(treeLevel, self.width/2, self.height, self.height, math.pi, self.branchWidth)

    def yFunc(self, treeLevel):
        global deltaY
        if(treeLevel == 0):
            deltaY = 1
            return deltaY
        elif(treeLevel > 0):
            if(treeLevel % 2 == 0):
                deltaY = deltaY + ((self.branchSize**treeLevel)*math.cos(self.angle))
                return deltaY
            elif(treeLevel %2 != 0):
                deltaY = deltaY + ((self.branchSize**treeLevel)*(math.cos(-self.angle)**(math.ceil(treeLevel/2))))
                return deltaY
            self.yFunc(treeLevel)

    def drawBranch(self, treeLevel, x1, y1, branchLen, branchAngle, lineWidth):
        if treeLevel >= 0:
            treeLevel -= 1
            x2 = x1 + int(math.sin(branchAngle) * branchLen)
            y2 = (y1 - int(y1 / deltaY))
            self.drawLine(x1, y1, x2, y2, lineWidth)
            lineWidth -= 1
            self.drawBranch(treeLevel, x2, y2, branchLen * self.branchSize, branchAngle - self.angle, lineWidth)
            self.drawBranch(treeLevel, x2, y2, branchLen * self.branchSize, branchAngle + self.angle, lineWidth)

    def drawLine(self, x1,y1, x2,y2, lineWidth):
        self.canvas.create_line(x1,y1, x2,y2, tags = "line", width = lineWidth)

    def upButton(self):
        global treeLevel
        if(len(self.level.get()) == 0):
            self.level.set(1)
        elif(len(self.level.get()) > 0):
            self.level.set(str(int(self.level.get()) + 1))
        self.display()

    def downButton(self):
        global treeLevel
        if(len(self.level.get()) == 0):
            self.level.set(1)
        elif(int(self.level.get()) <= 0):
            self.level.set(0)
        elif(len(self.level.get()) >= 0):
            self.level.set(str(int(self.level.get()) - 1))
        self.display()

FractalTree()
...