Advertisement
here2share

### Tk_Polygon_Editor.py

Oct 18th, 2016
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.53 KB | None | 0 0
  1. ### Tk_Polygon_Editor.py
  2.  
  3. from __future__ import division
  4. from Tkinter import *
  5.  
  6. class AB(tuple):
  7.     """ groups values by two, access is by property a or b"""
  8.     def __new__(cls, *args):
  9.         return tuple.__new__(cls, args)
  10.     def geta(self): return self[0]
  11.     def getb(self): return self[1]
  12.     a,b = map(property,[geta,getb])
  13.  
  14. class Scaler(AB):
  15.     """ maps values from one coordinate system to another"""
  16.    
  17.     def __init__(self, *args):
  18.         a,b = self.a,self.b
  19.         fx = (b.b.a-b.a.a)/(a.b.a-a.a.a)
  20.         fy = (b.b.b-b.a.b)/(a.b.b-a.a.b)
  21.         f = min(fx,fy)
  22.         wxc = (a.a.a+a.b.a)/2
  23.         wyc = (a.a.b+a.b.b)/2
  24.         vxc = (b.a.a+b.b.a)/2
  25.         vyc = (b.a.b+b.b.b)/2
  26.         xc = vxc-f*wxc
  27.         yc = vyc-f*wyc
  28.         self.f,self.xc,self.yc = f,xc,yc
  29.  
  30.     def scalepoint(self, P):
  31.         f,xc,yc = self.f,self.xc,self.yc
  32.         return AB(f*P.a+xc, f*P.b+yc)
  33.  
  34.     def scalerect(self, R):
  35.         f,xc,yc = self.f,self.xc,self.yc
  36.         p1 = AB(f*R.a.a+xc, f*R.a.b+yc)
  37.         p2 = AB(f*R.b.a+xc, f*R.b.b+yc)
  38.         return AB(p1,p2)
  39.        
  40. class PolyEdit:
  41.     """ tkinter application to edit polygons"""
  42.  
  43.     def __init__(self, master,n):
  44.         self.n=n
  45.         self.canvas = Canvas(master,width=500,height=500)
  46.         self.canvas.pack(fill= BOTH, expand=YES)
  47.         master.bind("<Escape>", lambda event='ignored',
  48.             m=master: m.destroy())
  49.         master.bind("<Configure>", self.configure)
  50.         master.bind("<Key-p>", self.output)
  51.         master.bind("<Key-c>", self.clear)
  52.         self.canvas.bind("<Button-1>", self.toggleselect)
  53.         self.canvas.bind("<Button-3>", self.togglepoly)
  54.         self.rects = [self.canvas.create_rectangle(0,0,0,0)
  55.             for i in range(n) for j in range(n)]
  56.         self.polypoints = []
  57.         self.polygons = []
  58.         self.polyshown = False
  59.    
  60.     def output(self,event=None):
  61.         print self.n,self.polypoints
  62.  
  63.     def togglepoly(self,event=None):
  64.         if self.polyshown: self.hidepoly()
  65.         else: self.showpoly()
  66.    
  67.     def hidepoly(self,event=None):
  68.         for x in self.polygons:
  69.             self.canvas.delete(x)
  70.         self.polyshown = False
  71.  
  72.     def clear(self,event=None):
  73.         c = self.canvas
  74.         self.hidepoly()
  75.         self.polypoints = []
  76.         self.polygons = []
  77.         rects = c.find_withtag("selected")
  78.         for r in rects:
  79.                 c.dtag(r,"selected")
  80.                 c.itemconfig(r,fill = "yellow")
  81.  
  82.     def toggleselect(self,event):
  83.         c,x,y = self.canvas,event.x, event.y
  84.         cvid = c.find_closest(x,y)
  85.         if cvid[0] in self.rects:
  86.             i,j = divmod(cvid[0]-1,self.n)
  87.             if "selected" in c.gettags(cvid):
  88.                 c.dtag(cvid,"selected")
  89.                 c.itemconfig(cvid,fill = "yellow")
  90.                 self.polypoints.remove((i,j))
  91.             else:
  92.                 c.itemconfig(cvid,tags = ("selected"),
  93.                     fill = "red")
  94.                 self.polypoints.append((i,j))
  95.             if self.polyshown:
  96.                 self.hidepoly()
  97.                 self.showpoly()
  98.  
  99.     def configure(self, event):
  100.         self.draw()
  101.  
  102.     def draw(self):
  103.         polyshown =  self.polyshown
  104.         self.hidepoly()
  105.         c = self.canvas
  106.         scale = Scaler(self.b,self.a)
  107.         for rect in self.rects:
  108.             i,j = divmod(rect-1,self.n)
  109.             r = scale.scalerect(AB(AB(i,j),AB(i+1,j+1)))
  110.             c.coords(rect,r.a.a,r.a.b,r.b.a,r.b.b)
  111.             if "selected" in c.gettags(rect):
  112.                 c.itemconfig(rect,fill = "red")
  113.             else:
  114.                 c.itemconfig(rect,fill = "yellow")
  115.         if polyshown:  self.showpoly()
  116.  
  117.     def showpoly(self,event=None):
  118.         c = self.canvas
  119.         scale = Scaler(self.b,self.a)
  120.         pts = []
  121.         if len(self.polypoints)>2:
  122.             for i,j in self.polypoints:
  123.                 pts.append(scale.scalepoint(AB(i+.5,j+.5)))
  124.             self.polygons.append(c.create_polygon(pts,
  125.                                             fill="black"))
  126.         self.polyshown = True
  127.            
  128.     def geta(self):
  129.         c = self.canvas
  130.         p1 = AB(0,0)
  131.         p2 = AB(c.winfo_width(), c.winfo_height())
  132.         return AB(p1,p2)
  133.    
  134.     def getb(self):
  135.         p1 = AB(0,0)
  136.         p2 = AB(self.n,self.n)
  137.         return AB(p1,p2)
  138.  
  139.     a,b = map(property,[geta,getb])
  140.  
  141. def main():
  142.     root = Tk()
  143.     root.title('Polygon Editor')
  144.     a = PolyEdit(root,10)
  145.     root.mainloop()
  146.    
  147. if __name__=='__main__':
  148.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement