def zoom(self, x, y, s): """Zoom Canvas with center x,y and scale s.""" cx,cy = self._o2c(x,y) self._xformz = la.translate(cx,cy) self._xformz = la.mul(self._xformz,la.scale(s,s)) self._xformz = la.mul(self._xformz,la.translate(-cx,-cy)) sr = self["scrollregion"] if sr: srd = [self.tk.getdouble(x) for x in sr.split()] c1 = la.vapply(self._xformz,(srd[0],srd[1],0,1)) c2 = la.vapply(self._xformz,(srd[2],srd[3],0,1)) self.config(scrollregion=(c1[0],c1[1],c2[0],c2[1])) super().scale("fixed-to-window",cx,cy,1/s,1/s) self.scale(tk.ALL,x,y,s,s) self._xform = la.mul(self._xform,la.translate(x,y)) self._xform = la.mul(self._xform,la.scale(s,s)) self._xform = la.mul(self._xform,la.translate(-x,-y))
def apply_xform(self,cids,xform): # 'arc', 'bitmap', 'image', 'line', 'oval', 'polygon', 'rectangle', 'text', or 'window' for cid in cids: t = self.type(cid) if t == "polygon" or t == "line" or t == "text": #print("poly style",t) crds = [la.coords(x,y,0,1) for x,y in group_coords(self.coords(cid),2,0)] #print("pre ",crds) tcrds = [la.vapply(xform,c) for c in crds] #print("post",tcrds) tkcrds = [(c[0],c[1]) for c in tcrds] self.coords(cid,tkcrds) elif t == 'arc' or t == 'oval' or t == 'rectangle': #print("arc style",t) # transform only center crds = self.coords(cid) center = la.coords((crds[0]+crds[2])/2,(crds[1]+crds[3])/2,0,1) w,h = crds[2]-crds[0],crds[3]-crds[1] tc = la.vapply(xform,center) #tw = vapply(xform,la.coords(w,0,0,0)) #th = vapply(xform,la.coords(0,h,0,0)) self.coords(cid,tc[0]-w/2,tc[1]-h/2,tc[0]+h/2,tc[1]+h/2) else: print("unknown type",t,cid)
def _c2o(self,cx,cy): xformi = la.inverse(self._xform) o = la.vapply(xformi,(cx,cy,0,1)) return o[0],o[1]
def _o2cv(self,ox,oy): c = la.vapply(self._xform,la.point((ox,oy,0,0))) return c[0],c[1]
def transform_vector(v, xform): tv = la.vapply(xform, la.coords(v[0], v[1], 0, 0)) return la.coords(tv[0], tv[1])
def transform_point(p, xform): tp = la.vapply(xform, la.coords(p[0], p[1], 0, 1)) return la.coords(tp[0], tp[1])
def transform_bezier_circle(hs, xform): for i, h in enumerate(hs): th = la.vapply(xform, la.coords(h[0], h[1], 0, h[2])) hs[i] = la.coords(th[0], th[1], th[3]) return hs