from tkinter import*
from tkinter.ttk import*
import random
window=Tk()
window.title('Tree generator')
window.geometry("1250x700")
window.resizable(1,1)
#------------------------------------------------- adjust variables in this section
w=1250 # width of the canvas
h=650 # height of the canvas
trunk_len=50 # trunk height
fruit_rad=4 # fruit radius
trunk_width=3
branch_width=2
range_limit1,range_limit2,range_limit3=250,500,600 # higher numbers make larger trees.
colour1="black" # canvas background colour range_limit3 must be less then w/2 to fit within the canvas
colour2="white" # trunk colour
colour3="white" # branch colour
colour4="yellow"# fruit colour
#-------------------------------------------------------------------------------------------
frm1=Frame(window)
frm1.pack()
frm2=Frame(window)
frm2.pack()
frm3=Frame(window)
frm3.pack()
canvas = Canvas(frm3, background=colour1, height=h, width=w)
canvas.pack()
##### point={} is a dictionary with key=(x1,y1), value=(0:direction of the branch to it(1-5),
# 1:branches_from_it(0-3)
# eg at the beginning, point[(l/2,h-trunk_len)]=[3,0]
##### directions are as follows--> 1-left, 2-left&up, 3-up, 4-right&up, 5-right
##### intersect={} is a list of middlepoints of all lines. Used to prevent lines intersecting each other.
##### fresh_point=[] is a list of all generated points that haven't gone through the branch generation loop
# eg at the beginning, fresh_point=[(l/2,h-trunk_len)]
#-------------------------------------------------------------------------------------------
def generate_main(event):
global fruits, branches, point, intersect, fresh_point
bttn1.configure(text="Regenerate")
canvas.delete("all")
canvas.create_line(w/2,h,w/2,h-trunk_len, fill=colour2, width=trunk_width)
point={(w/2,h-trunk_len):[3,0]}
fresh_point=[(w/2,h-trunk_len)]
intersect=[]
while len(fresh_point)>0:
start_point=next(iter(fresh_point))
x1,y1=start_point[0],start_point[1]
spread1 =((h-y1)**2+(w/2-x1)**2)**(1/2)
print(spread1)
uniformity=round(scl2.get())
if spread1>=range_limit3:
fresh_point.remove(start_point)
continue
elif spread1>range_limit2:
tries=random.randint(uniformity+1,uniformity+2)
elif spread1>range_limit1:
tries=random.randint(uniformity+2,uniformity+3)
else:
tries=random.randint(uniformity,uniformity+1)
for i in range(tries):
if spread1>range_limit1:
drctn_new=define_direction1(point[(x1,y1)][0])
else:
drctn_new=define_direction2(point[(x1,y1)][0])
i1,j1=define_point(x1,y1,drctn_new)
if (i1,j1) in point or ((x1+i1)/2,(y1+j1)/2) in intersect :
continue
point[(i1,j1)]=[drctn_new,0]
point[start_point][1]=point[start_point][1]+1
fresh_point.append((i1,j1))
intersect.append(((x1+i1)/2,(y1+j1)/2))
canvas.create_line(x1,y1,i1,j1, fill=colour3, width=branch_width)
fresh_point.remove(start_point)
if chk.instate(['selected']):
fruit_grow(event)
return
def define_direction1(drctn):
a1=random.randint(1,6)
if drctn==1 :
if a1<=3:
drctn_new=1
else:
drctn_new=2
elif drctn==2:
if a1<=2:
drctn_new=1
elif a1 <=4:
drctn_new=2
else:
drctn_new=3
elif drctn==3:
if a1<=2:
drctn_new=2
elif a1 <=4:
drctn_new=3
else:
drctn_new=4
elif drctn==4:
if a1<=2:
drctn_new=3
elif a1 <=4:
drctn_new=4
else:
drctn_new=5
else:
if a1<=3:
drctn_new=4
else:
drctn_new=5
return drctn_new
def define_direction2(drctn):
a1=random.randint(1,6)
if drctn==1 :
if a1<=5:
drctn_new=1
else:
drctn_new=2
elif drctn==2:
if a1==1:
drctn_new=1
elif a1 <=5:
drctn_new=2
else:
drctn_new=3
elif drctn==3:
if a1==1:
drctn_new=2
elif a1 <=5:
drctn_new=3
else:
drctn_new=4
elif drctn==4:
if a1==1:
drctn_new=3
elif a1 <=5:
drctn_new=4
else:
drctn_new=5
else:
if a1<=1:
drctn_new=4
else:
drctn_new=5
return drctn_new
def define_point (x1,y1,drctn_new):
branch_len=round(scl1.get())
if drctn_new==1:
i1,j1=x1-branch_len,y1
elif drctn_new==2:
i1,j1=x1-branch_len,y1-branch_len
elif drctn_new==3:
i1,j1=x1,y1-branch_len
elif drctn_new==4:
i1,j1=x1+branch_len,y1-branch_len
else :
i1,j1=x1+branch_len,y1
return (i1,j1)
def fruit_grow(event):
for key in point.keys():
if point[key][1]==1:
continue
spread2=((h-key[1])**2+(w/2-key[0])**2)**(1/2)
if random.randint(1,1000)<spread2:
canvas.create_oval(key[0]-fruit_rad,key[1]-fruit_rad,key[0]+fruit_rad,key[1]+fruit_rad, fill=colour4)
bttn1=Button(frm1,text="Generate",)
bttn1.pack(side="left")
bttn1.bind("<Button-1>",generate_main)
lbl1=Label (frm1,text="branch length=")
lbl1.pack(side="left")
scl1 = Scale(frm1 ,from_=5, to=50, orient="horizontal")
scl1.pack(side="left")
scl1.set(10)
lbl2=Label (frm1,text=" uniformity=")
lbl2.pack(side="left")
scl2 = Scale(frm1 ,from_=1, to=5, orient="horizontal")
scl2.pack(side="left")
scl2.set(1)
chk = Checkbutton(frm1, text="fruits")
chk.pack(side="left")
window.mainloop()