# demonstrate dimensions 0 to 4 # 6/2004 Wolfgang.Urban@schule.at IN_IDLE = 0 from Tkinter import * CC = [0,1] CORNERS = [[x,y,z,t] for t in CC for z in CC for y in CC for x in CC] EDGES = [(0,1), (0,2),(1,3), (2,3), (0,4),(1,5),(3,7),(2,6), (4,5), (4,6),(5,7), (6,7), (0,8),(1,9),(2,10),(3,11),(4,12),(5,13),(6,14),(7,15), (8,9), (8,10),(9,11), (10,11), (8,12),(9,13),(11,15),(10,14), (12,13), (12,14),(13,15), (14,15)] class Animator(Frame): def __init__(self,parent,size): self.parent = parent self.size = size Frame.__init__(self,parent,border=2,relief=RIDGE) self.cv = Canvas(self,width=self.size,height=self.size,bg="#ffffff") self.cv.pack() self.pack() self.update() self.lines = [] self.colors = [None,"#ff0000","#0000ff","#00e000"] self.mid = self.size/2+10 self.midy = self.mid+100 self.scale = self.size/2.0/1.2 self.lines = [0]*len(EDGES) for i in range(len(self.lines)): self.lines[i] = self.cv.create_line(0,0,0,0,width=3) self.BUSY = 0 def kill_lines(self): for l in self.lines: self.cv.coords(l,0,0,0,0) def move_line(self,l,(x1,y1),(x2,y2),c): self.cv.coords(self.lines[l],self.mid+x1,self.midy-y1, self.mid+x2,self.midy-y2) self.cv.itemconfigure(self.lines[l],fill=self.colors[c]) def project(self,(x,y,z,t)): xp = x-z/3.0-t*0.75 yp = y-z/3.0+t*0.5 return xp*self.scale,yp*self.scale def dim0(self): self.kill_lines() self.move_line(0,(0,0),(4,0),1) self.move_line(0,(0,1),(4,1),1) self.cv.update() def dim1(self): self.dim_n(1) def dim2(self): self.dim_n(2) def dim3(self): self.dim_n(3) def dim4(self): self.dim_n(4) def dim1a(self): self.dim_n_animate(1); self.dim_n(1) def dim2a(self): self.dim_n_animate(2); self.dim_n(2) def dim3a(self): self.dim_n_animate(3); self.dim_n(3) def dim4a(self): self.dim_n_animate(4); self.dim_n(4) def dim_n(self,n): if self.BUSY: return self.BUSY = 1 self.kill_lines() n_corners = 2**n n_edges = (n_corners*n)/2 edgelist = EDGES[:n_edges] l=0 for p1,p2 in edgelist: c1,c2 = CORNERS[p1],CORNERS[p2] self.move_line(l,self.project(c1), self.project(c2),1) l += 1 self.parent.update() self.BUSY = 0 def dim_n_animate(self,n): if self.BUSY: return self.BUSY = 1 self.kill_lines() n_corners = 2**n n_edges = (n_corners*n)/2 n1e = 2**(n-1)*(n-1)/2 n2e = n_edges-n1e edgelist = EDGES[:n_edges] middle = range(n1e,n2e) lines = [0]*n_edges for f in range(0,81): l = 0 for p1,p2 in edgelist: c1,c2 = CORNERS[p1],CORNERS[p2] c1,c2 = self.dimscale(c1[:],n,f/80.0),self.dimscale(c2[:],n,f/80.0) if l in middle: col1 = 2 elif l>=n2e: col1 = 3 else: col1 = 1 self.move_line(l,self.project(c1),self.project(c2),col1) l += 1 self.parent.after(20+20*(n==4)) self.parent.update() self.parent.after(1000) self.parent.update() self.BUSY = 0 def dimscale(self,corner,n,fact): corner[n-1] = corner[n-1]*fact return corner class FrameCmd(Frame): def __init__(self,actor): self.actor = actor Frame.__init__(self) buttons = [("0",self.actor.dim0),("->",self.actor.dim1a), ("1",self.actor.dim1),("->",self.actor.dim2a), ("2",self.actor.dim2),("->",self.actor.dim3a), ("3",self.actor.dim3),("->",self.actor.dim4a), ("4",self.actor.dim4)] for t,f in buttons: Button(self,text=t,font=("Courier",14,"bold"), command=f).pack(fill=X,expand=1,side=LEFT) class Dimensions: def __init__(self): self.root = Tk() self.root.title("Dimension transformer") self.animator = Animator(self.root,470) self.animator.pack(side=TOP) cmd = FrameCmd(self.animator) cmd.pack(side=TOP) if not IN_IDLE: self.root.mainloop() d = Dimensions()