Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ### Tk_Polygon_Editor.py
- from __future__ import division
- from Tkinter import *
- class AB(tuple):
- """ groups values by two, access is by property a or b"""
- def __new__(cls, *args):
- return tuple.__new__(cls, args)
- def geta(self): return self[0]
- def getb(self): return self[1]
- a,b = map(property,[geta,getb])
- class Scaler(AB):
- """ maps values from one coordinate system to another"""
- def __init__(self, *args):
- a,b = self.a,self.b
- fx = (b.b.a-b.a.a)/(a.b.a-a.a.a)
- fy = (b.b.b-b.a.b)/(a.b.b-a.a.b)
- f = min(fx,fy)
- wxc = (a.a.a+a.b.a)/2
- wyc = (a.a.b+a.b.b)/2
- vxc = (b.a.a+b.b.a)/2
- vyc = (b.a.b+b.b.b)/2
- xc = vxc-f*wxc
- yc = vyc-f*wyc
- self.f,self.xc,self.yc = f,xc,yc
- def scalepoint(self, P):
- f,xc,yc = self.f,self.xc,self.yc
- return AB(f*P.a+xc, f*P.b+yc)
- def scalerect(self, R):
- f,xc,yc = self.f,self.xc,self.yc
- p1 = AB(f*R.a.a+xc, f*R.a.b+yc)
- p2 = AB(f*R.b.a+xc, f*R.b.b+yc)
- return AB(p1,p2)
- class PolyEdit:
- """ tkinter application to edit polygons"""
- def __init__(self, master,n):
- self.n=n
- self.canvas = Canvas(master,width=500,height=500)
- self.canvas.pack(fill= BOTH, expand=YES)
- master.bind("<Escape>", lambda event='ignored',
- m=master: m.destroy())
- master.bind("<Configure>", self.configure)
- master.bind("<Key-p>", self.output)
- master.bind("<Key-c>", self.clear)
- self.canvas.bind("<Button-1>", self.toggleselect)
- self.canvas.bind("<Button-3>", self.togglepoly)
- self.rects = [self.canvas.create_rectangle(0,0,0,0)
- for i in range(n) for j in range(n)]
- self.polypoints = []
- self.polygons = []
- self.polyshown = False
- def output(self,event=None):
- print self.n,self.polypoints
- def togglepoly(self,event=None):
- if self.polyshown: self.hidepoly()
- else: self.showpoly()
- def hidepoly(self,event=None):
- for x in self.polygons:
- self.canvas.delete(x)
- self.polyshown = False
- def clear(self,event=None):
- c = self.canvas
- self.hidepoly()
- self.polypoints = []
- self.polygons = []
- rects = c.find_withtag("selected")
- for r in rects:
- c.dtag(r,"selected")
- c.itemconfig(r,fill = "yellow")
- def toggleselect(self,event):
- c,x,y = self.canvas,event.x, event.y
- cvid = c.find_closest(x,y)
- if cvid[0] in self.rects:
- i,j = divmod(cvid[0]-1,self.n)
- if "selected" in c.gettags(cvid):
- c.dtag(cvid,"selected")
- c.itemconfig(cvid,fill = "yellow")
- self.polypoints.remove((i,j))
- else:
- c.itemconfig(cvid,tags = ("selected"),
- fill = "red")
- self.polypoints.append((i,j))
- if self.polyshown:
- self.hidepoly()
- self.showpoly()
- def configure(self, event):
- self.draw()
- def draw(self):
- polyshown = self.polyshown
- self.hidepoly()
- c = self.canvas
- scale = Scaler(self.b,self.a)
- for rect in self.rects:
- i,j = divmod(rect-1,self.n)
- r = scale.scalerect(AB(AB(i,j),AB(i+1,j+1)))
- c.coords(rect,r.a.a,r.a.b,r.b.a,r.b.b)
- if "selected" in c.gettags(rect):
- c.itemconfig(rect,fill = "red")
- else:
- c.itemconfig(rect,fill = "yellow")
- if polyshown: self.showpoly()
- def showpoly(self,event=None):
- c = self.canvas
- scale = Scaler(self.b,self.a)
- pts = []
- if len(self.polypoints)>2:
- for i,j in self.polypoints:
- pts.append(scale.scalepoint(AB(i+.5,j+.5)))
- self.polygons.append(c.create_polygon(pts,
- fill="black"))
- self.polyshown = True
- def geta(self):
- c = self.canvas
- p1 = AB(0,0)
- p2 = AB(c.winfo_width(), c.winfo_height())
- return AB(p1,p2)
- def getb(self):
- p1 = AB(0,0)
- p2 = AB(self.n,self.n)
- return AB(p1,p2)
- a,b = map(property,[geta,getb])
- def main():
- root = Tk()
- root.title('Polygon Editor')
- a = PolyEdit(root,10)
- root.mainloop()
- if __name__=='__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement