# L-7 MCS 275 Wed 30 Jan 2008 : cantor.py

from Tkinter import *
import math

class CantorSet():
   """
   GUI to draw a Cantor set on canvas.
   """
   def __init__(self,wdw,N):
      "a Cantor set with N levels"
      wdw.title('a cantor set')
      self.d = 3**N+20
      self.n = IntVar()
      self.sn = Scale(wdw,orient='horizontal',\
        from_=0,to=N,tickinterval=1,\
        length=self.d,variable=self.n,\
        command=self.DrawSet)
      self.sn.grid(row=0,column=0)
      self.sn.set(0)
      self.c = Canvas(wdw,width=self.d,\
        height=self.d/3,bg ='white')
      self.c.grid(row=1,column=0)
      self.b = Button(wdw,text="clear canvas",\
        command=self.ClearCanvas)
      self.b.grid(row=2,column=0)

   def cantor(self,A,B,z,t,k):
      """
      draws a line from A to B, at height z
      t is a string, int(t) equals the number
      of times the middle third must be removed
      k is level of recursion, start at k = int(t)
      """
      if(k==0):           # draw line segment
         self.c.create_line(A,z,B,z,width=2)
      else:
         L = (2*A+B)/3
         R = (A+2*B)/3
         self.cantor(A,L,z+30,t,k-1)
         self.cantor(R,B,z+30,t,k-1)
      if(k==int(t)):      # put text string
         cx = self.d/2;
         if(t == '0'):
            self.c.create_text(cx,z-10,text=t)
         else:
            self.c.create_text(cx,z+k*30,text=t)

   def DrawSet(self,v):
      "Draws a Cantor set"
      n = int(v)
      self.cantor(10,self.d-10,30,v,n)

   def ClearCanvas(self):
      "Clears the entire canvas"
      self.c.delete(ALL)

def main():
   top = Tk()
   show = CantorSet(top,6)
   top.mainloop()

if __name__ == "__main__": main()
