# -*- coding: utf-8 -*- """ Created on Fri Oct 3 00:24:21 2014 @author: nikitakalinin """ from Tkinter import * from math import * import copy # left click add a grain of sand # right click throw a "wave" # clicks to right half os the screen: # left click on the top-right side rescale the picture in s times # left click on bottom-right side removes the last added point, # and it can not be applied to undo "waves" #--------------------- #we have a grid n\times n n=80 # t defines how big the picture on the screen t=500/n # relaxation is divided in steps. #drawback=1 means that we redraw the picture after each step #drawback=10000 basically means that we rarely redraw the picture drawback = 1 #draw1 =0 means that we have colors on the picture #draw1 =1 means that the picture is mostly black-white draw1 =1 #coefficient of rescaling, when we click on top half #of the right half of the screen s=1.5 #here you must have only one line, #for example, you can comment line with "polygon" and uncomment with "circle" #It defines #the boundary of our region. #functions circle, polygon, etc have values>0 inside the considered region # and <0 outside. You can create your own functions like that def boundary(i,j): #return circle(i,j) #return irrationaltriangle(i,j) return polygon(i,j) #gives the boundary of a circle def circle(i,j): return -(i-n/2)*(i-n/2)-(j-n/2)*(j-n/2)+n*n/4 #triangle with orrational side def irrationaltriangle(i,j): return (i+1)*(j+1)*(i-int(j*sqrt(2)))*(i-int(j*sqrt(2))+2)*(i-int(j*sqrt(2))+1) #some polygon def polygon(i,j): return (n-i-1)*(n-j-1)*(i-j/5)*(j-i/5)*(5*n/3-i-j)*(i-j-3*n/5)*(j-i-3*n/5) ######################################################## backphone=3 global oldx oldx =1 global oldy oldy =1 global history history = [] global old old = [] global field field = [] stack1 = [] stack2 = [] smallWave=0 def printcoords(event): print (int(event.x/t),int(event.y/t)) if int(event.x/t)>n and int(event.y/t)>n/2: redraw() if int(event.x/t)>n and int(event.y/t)0: [i,j]=history2.pop() print([s*i,s*j]) add(int(s*i),int(s*j)) stack1.append([int(s*i),int(s*j)]) relax() draw(field) for i in range(n): f = [] for j in range(n): f.append(backphone) field.append(f) def add(i,j): global field old.append(copy.deepcopy(field)) field[i][j]=field[i][j]+1 stack1.append([i,j]) global history history.append([i,j]) def printfield(): for i in range(n): print(field[i]) def draw(field): canvas.delete(ALL) for i in range(n): for j in range(n): if draw1==0: if field[i][j]==2: canvas.create_rectangle(t*i, t*j, t*(i+1), t*(j+1), fill="green") if field[i][j]==1: canvas.create_rectangle(t*i, t*j, t*(i+1), t*(j+1), fill="yellow") if field[i][j]==0: canvas.create_rectangle(t*i, t*j, t*(i+1), t*(j+1), fill="red") if field[i][j]>3: canvas.create_rectangle(t*i, t*j, t*(i+1), t*(j+1), fill="black") else: if field[i][j]==2: #squares canvas.create_rectangle(t*i, t*j, t*(i+1), t*(j+1), fill="black") if field[i][j]==0: #cross canvas.create_line(t*(i+0.5), t*j, t*(i+0.5), t*(j+1)) canvas.create_line(t*(i+1), t*(j+0.5), t*i, t*(j+0.5)) if field[i][j]==1: #oval canvas.create_oval(t*i, t*j, t*(i+1), t*(j+1)) if field[i][j]>3: canvas.create_rectangle(t*i, t*j, t*(i+1), t*(j+1), fill="red") for [i,j] in history: if draw1==0: canvas.create_oval(t*i+10,t*j+10,t*i-8,t*j-8,fill="blue") else: canvas.create_oval(t*i+9,t*j+9,t*i-5,t*j-5,fill="grey") canvas.update_idletasks() def redraw(): global field field = copy.deepcopy(old.pop()) history.pop() draw(field) def relax(): counter=0 while len(stack1)>0 or len(stack2)>0: while len(stack1)>0: [i,j] = stack1.pop() if field[i][j] > 3: field[i][j] = field[i][j]-4 for [k,l] in ([i-1,j],[i,j-1],[i+1,j],[i,j+1]): if boundary2(k,l)!=0: field[k][l]=field[k][l]+1 if boundary(k,l)>0: if field[k][l]>3: stack2.append([k,l]) counter=counter+1 while len(stack2)>0: [i,j] = stack2.pop() if field[i][j] > 3: field[i][j] = field[i][j]-4 for [k,l] in ([i-1,j],[i,j-1],[i+1,j],[i,j+1]): if boundary2(k,l)!=0: field[k][l]=field[k][l]+1 if boundary(k,l)>0: if field[k][l]>3: stack1.append([k,l]) if smallWave==1 and counter==1: global oldx global oldy field[oldx][oldy] = field[oldx][oldy]-1 if fmod(counter,drawback)==0: draw(field) def boundary2(i,j): return (i)*(j)*(n-i)*(n-j) root = Tk() frame = Frame(root, bd=1, relief=SUNKEN) frame.grid_rowconfigure(0, weight=1) frame.grid_columnconfigure(0, weight=1) xscroll = Scrollbar(frame, orient=HORIZONTAL) xscroll.grid(row=1, column=0, sticky=E+W) yscroll = Scrollbar(frame) yscroll.grid(row=0, column=1, sticky=N+S) canvas = Canvas(frame,bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) canvas.config(width=2*t*n, height=t*n) canvas.grid(row=0, column=0, sticky=N+S+E+W) xscroll.config(command=canvas.xview) yscroll.config(command=canvas.yview) frame.pack(fill=BOTH,expand=0) canvas.bind("