本物らしい木の描画:ソースコード

#coding: utf-8
"""タートル・グラフィックス:本物らしい木の描画
 参考文献「Turbo Graphics」(安齋利洋・伊吹龍著;1987年)"""


import myturtle
import tkinter as tk
from  tkinter.messagebox import showinfo 

#パラメター
xP=0
yP=-300
#angleMiki=15
#ratioMiki = 0.80
#angleEda=45
#ratioEda=0.70
length=150
ratioFutosa=0.7200
generation=10
fields =('幹角度', '幹比率', '枝角度', '枝比率')
defaults =('15', '0.80', '45', '0.70')


class Seed:
    """木の表現のためのパラメター類"""

def ki1(tane):
    global miki

    def edawakare(mikiT, length, thickness, depth):
        if(depth ==0 or length < 2 or thickness < 0.1 or keypressed):
            return
        miki=mikiT.clone()
        miki.reverse()
        miki.fd(length)
        eda=miki.clone()
        miki.lt(tane.angleMiki)
        edawakare(miki, length*tane.ratioMiki, thickness, depth-1)
        eda.rt(tane.angleEda)
        edawakare(eda, length*tane.ratioEda, thickness*tane.ratioFutosa, \
                  depth-1)

    def kiReset():
        global keypressed
        canvas.delete("all")
        miki.ht()
        miki.home()
        miki.lt(90)
        miki.setposition(tane.xP, tane.yP)
        keypressed=0

    kiReset()
    edawakare(miki, tane.length, 1, tane.generation)



def ki1Canvas():
    #種パラメタ
    entsV=fetchV(ents)
    angleMiki=entsV[0]
    ratioMiki =entsV[1]
    angleEda=entsV[2]
    ratioEda=entsV[3]
    print('単子葉植物',angleMiki, ratioMiki, angleEda, ratioEda)

    tane=Seed()
    tane.xP=xP
    tane.yP=yP
    tane.angleMiki=angleMiki
    tane.ratioMiki=ratioMiki
    tane.angleEda=angleEda
    tane.ratioEda=ratioEda
    tane.length=length
    tane.ratioFutosa=ratioFutosa
    tane.generation=generation
    
         
    ki1(tane)
    showinfo(message='描画完了')
    

def ki2(tane):
    global miki

    def edawakare(mikiT, length, thickness, depth):
        if(depth ==0 or length < 2 or thickness < 0.1 or keypressed):
            return
        miki=mikiT.clone()
        miki.reverse()
        #miki.fd(length)
        eda=miki.clone()
        miki.lt(tane.angleMiki)
        miki.fd(length) #追加
        edawakare(miki, length*tane.ratioMiki, thickness, depth-1)
        eda.rt(tane.angleEda)
        eda.fd(length)
        edawakare(eda, length*tane.ratioEda, thickness*tane.ratioFutosa, \
                  depth-1)
        
    def kiReset():
        global keypressed
        canvas.delete("all")
        miki.ht()
        miki.home()
        miki.lt(90)
        miki.setposition(tane.xP, tane.yP)
        keypressed=0
        

    kiReset()
    edawakare(miki, tane.length, 1, tane.generation)



def ki2Canvas():
    #種パラメタ
    entsV=fetchV(ents)
    angleMiki=entsV[0]
    ratioMiki =entsV[1]
    angleEda=entsV[2]
    ratioEda=entsV[3]
    print('双子葉植物', angleMiki, ratioMiki, angleEda, ratioEda)


    tane=Seed()
    tane.xP=xP
    tane.yP=yP
    tane.angleMiki=angleMiki
    tane.ratioMiki=ratioMiki
    tane.angleEda=angleEda
    tane.ratioEda=ratioEda
    tane.length=length
    tane.ratioFutosa=ratioFutosa
    tane.generation=generation
    
         
    ki2(tane)
    showinfo(message='描画完了')


def makeform(frame2):
    entries =[]
    for i, field in enumerate(fields):
        row=tk.Frame(frame2)
        lab=tk.Label(row,width=5, text=field, anchor='w')
        ent=tk.Entry(row, width=5)
        ent.insert(0, defaults[i])
        row.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
        lab.pack(side=tk.LEFT)
        ent.pack(side=tk.RIGHT, expand=tk.YES, fill=tk.X)
        entries.append(ent)

    return entries

def fetchV(entries):
    entsV=[]
    for entry in entries:
        entsV.append(float(entry.get()))

    return entsV

def setKeypressed(event):
    global keypressed
    keypressed=1
    print('中断')


if __name__ == '__main__':
    root = tk.Tk()
    #root.bind('', setKeypressed)
    root.geometry("915x800")
    #フレーム
    frame1=tk.Frame(root,)
    frame2=tk.Frame(root, width=100, height=800, bg="green")
    canvas = tk.Canvas(master = frame1, width = 800, height = 800, \
                       relief=tk.GROOVE, bd=2)
    canvas.pack()
    canvas.bind_all('<key>', setKeypressed)

    #Turtle
    miki=myturtle.MyRawTurtle(canvas)
    miki.lt(90)
    keypressed=0
    #種のパラメタ
    ents =makeform(frame2)
    

    lb1=tk.Label(master=frame2, text='木の描画', bg='green')
    lb1.pack()
    btn1=tk.Button(master = frame2, text = "単子葉植物", \
                   command = ki1Canvas)
    btn1.pack()
    btn2=tk.Button(master = frame2, text = "双子葉植物", \
                   command = ki2Canvas)
    btn2.pack()
    frame1.grid(column=0,row=0)
    frame2.grid(column=1,row=0)
    root.mainloop()