def onSegmentInsert(self, ev): print("onInsert", ev) self.historySave() cx, cy = self.canvas.canvasxy(ev.x, ev.y) self.info.item = self.canvas.find_closest(cx, cy)[0] self.info.prev = coords(cx, cy) seg = self.seg_cidmap[self.info.item] si = self.cc.segmentIndex(seg) cp, seg2 = self.cc.insertPoint(si, coords(cx, cy), SegType.Biarc) self.redrawSegments() cid1 = self.addMoveHandle(cp) cid2 = self.addRotHandle(cp) self.cp_cidmap[cid1] = cp self.cp_cidmap[cid2] = cp self.imap[cp] = [cid1, cid2] self.info.item = cid1 self.canvas.tag_raise(cid1) self.canvas.tag_raise(cid2) self.canvas.focus(cid1) sys.stdout.flush() pass
def onMoveUpdate(self, ev): print("onMoveUpdate", ev.x, ev.y) cx, cy = self.canvas.canvasxy(ev.x, ev.y) dx, dy = cx - self.info.prev[0], cy - self.info.prev[1] self.info.prev = coords(cx, cy) sel = self.selection cp = self.cp_cidmap[self.info.item] if not self.selection or cp not in sel: sel = [cp] for cp in sel: self.cc.movePoint(cp, coords(dx, dy)) cids = self.imap[cp] for cid in cids: hc = self.canvas.coords(cid) print(hc) hct = [] for c in group_coords(hc, 2, 0): hct.append(c[0] + dx) hct.append(c[1] + dy) print(hct) self.canvas.coords(cid, *hct) self.redrawSegments() sys.stdout.flush() pass
def onRotUpdate(self, ev): print("onRotUpdate", ev.x, ev.y) cx, cy = self.canvas.canvasxy(ev.x, ev.y) cp = self.cp_cidmap[self.info.item] p = cp.point ot = cp.tangent t, l = unit_length(coords(cx, cy) - p) d = 35 * t - 35 * ot cp.tangent = t #for s in self.cc.segment: # if cp is s.ps: # print(1/l) # s.biarc_r = 1/l # if cp is s.pe: # print(l) # s.biarc_r = 1/l self.canvas.move(self.info.item, d[0], d[1]) self.redrawSegments() sys.stdout.flush()
def onInsert(self, ev): print("onInsert", ev) self.historySave() cx, cy = self.canvas.canvasxy(ev.x, ev.y) self.info["item"] = self.canvas.find_closest(cx, cy)[0] self.info["cx"] = cx self.info["cy"] = cy i = self.cidmap[self.info["item"]] self.cc.insertPoint(i, coords(cx, cy), self.cc.SegType.Biarc, None, 30, 1) self.cc.draw(self.canvas) cid1 = self.addMoveHandle(i) cid2 = self.addRotHandle(i) self.imap.insert(i, [cid1, cid2]) for j, cids in enumerate(self.imap): for cid in cids: self.cidmap[cid] = j self.info["item"] = cid1 self.canvas.tag_raise(self.info["item"], "move") self.canvas.focus(self.info["item"]) sys.stdout.flush() pass
def onRotStart(self, ev): print("onRotStart", ev) sys.stdout.flush() self.historySave() cx, cy = self.canvas.canvasxy(ev.x, ev.y) self.info.item = self.canvas.find_closest(cx, cy)[0] self.info.prev = coords(cx, cy)
def onSelRotStart(self, ev): print("onSelRotStart", ev) sys.stdout.flush() self.historySave() cx, cy = self.canvas.canvasxy(ev.x, ev.y) self.info.prev = coords(cx, cy) self.info.preva = None
def onSelectionStart(self, ev): print("onSelStart", ev) self.createHandles() self.selection = set() cx, cy = self.canvas.canvasxy(ev.x, ev.y) self.info.selstart = coords(cx, cy) self.info.selcid = None sys.stdout.flush() pass
def onSelRotUpdate(self, ev): print("onSelRotUpdate", ev.x, ev.y) if not self.selection: return cx, cy = self.canvas.canvasxy(ev.x, ev.y) dx, dy = cx - self.info.prev[0], cy - self.info.prev[1] t, l = unit_length(coords(dx, dy)) cura = m.atan2(t[1], t[0]) if self.info.preva is None: a = 0 else: a = cura - self.info.preva if a > 360: a -= 360 print("rotate:", a) xform = identity() xform = mul(xform, translate(self.info.prev[0], self.info.prev[1])) xform = mul(xform, rotate(a, 0, 0, 1)) xform = mul(xform, translate(-self.info.prev[0], -self.info.prev[1])) for cp in self.selection: rcp = vapply(xform, coords(cp.point[0], cp.point[1], 0, 1)) rct = vapply(xform, coords(cp.tangent[0], cp.tangent[1], 0, 0)) cp.point = coords(rcp[0], rcp[1]) cp.tangent = coords(rct[0], rct[1]) self.redrawSegments() #self.createHandles() self.redrawSelection() self.info.preva = cura sys.stdout.flush()
def __init__(self, app): super().__init__() self.app = app self.cps = [] self.cls = [] self.cidmap = {} self._ori = {"cx": 0, "cy": 0, "item": None} self.cps = [ coords(100, 100), coords(100, 300), coords(400, 300), coords(400, 600) ] self.cls = [0.5, 0.5, 0.5] self.mode = 1 self.mode = 0 self.manip = Manip.Idle self.inserter = FSMTest(self.app.canvas)
def onMoveUpdate(self, ev): print("onMoveUpdate", ev.x, ev.y) cx, cy = self.canvas.canvasxy(ev.x, ev.y) dx, dy = cx - self.info["cx"], cy - self.info["cy"] self.info["cx"], self.info["cy"] = cx, cy i = self.cidmap[self.info["item"]] cids = self.imap[i] for cid in cids: self.canvas.move(cid, dx, dy) self.cc.movePoint(i, coords(dx, dy)) self.cc.draw(self.canvas) print(i, "->", self.info["item"]) sys.stdout.flush() pass
def onHandleMotion(self, event): if (self.manip is not Manip.Move): return print("HandleMotion") sys.stdout.flush() cx, cy = self.app.canvas.canvasxy(event.x, event.y) delta_cx = cx - self._ori["cx"] delta_cy = cy - self._ori["cy"] self._ori["cx"] = cx self._ori["cy"] = cy # move the control point handle self.app.canvas.move(self._ori["item"], delta_cx, delta_cy) # move the control point in object coordinates i = self.cidmap[self._ori["item"]] self.cps[i] = self.cps[i] + coords(delta_cx, delta_cy) print("delta=", (delta_cx, delta_cy)) self.drawControlCurve()
def onRotUpdate(self, ev): print("onRotUpdate", ev.x, ev.y) cx, cy = self.canvas.canvasxy(ev.x, ev.y) i = self.cidmap[self.info["item"]] p = self.cc.point[i] ot = self.cc.tangent[i] t = unit(coords(cx, cy) - p) d = 35 * t - 35 * ot self.cc.tangent[i] = t self.canvas.move(self.info["item"], d[0], d[1]) self.cc.draw(self.canvas) sys.stdout.flush() pass
def onSelectionUpdate(self, ev): print("onSelUpdate", ev) cx, cy = self.canvas.canvasxy(ev.x, ev.y) self.info.selend = coords(cx, cy) cids = self.canvas.find_overlapping(self.info.selstart[0], self.info.selstart[1], self.info.selend[0], self.info.selend[1]) for cid in cids: if cid not in self.cp_cidmap: continue cp = self.cp_cidmap[cid] self.selection.add(cp) self.redrawSelection() sys.stdout.flush() pass
def __init__(self, canvas): self.isOpen = False self.SegType = Enum("SegType", "Straight Biarc End") self.point = [coords(0, 0)] self.tangent = [None] self.biarc_r = [] self.segwidth = [] self.segtype = [] self.cidmap = {} self.color = "gray" self.tag = "segment" self.movePoint(0, coords(100, 100)) self.appendPoint(coords(200, 110), self.SegType.Straight, None, 30) #self.appendPoint(coords(320,310),self.SegType.Biarc,30,1) self.appendPoint(coords(520, 400), self.SegType.Biarc, None, 30, 1) self.insertPoint(2, coords(320, 310), self.SegType.Biarc, None, 30, 1) self.insertPoint(2, coords(620, 610), self.SegType.Straight, None, 30, 1) self.removePoint(2)
def setup(self): # create a toplevel menu self.menubar = tk.Menu(self) filemenu = tk.Menu(self.menubar, tearoff=0) filemenu.add_command(label="Load Track", command=self.loadCP) filemenu.add_command(label="Save Track", command=self.saveCP) filemenu.add_command(label="Import TED", command=self.importTed) filemenu.add_command(label="Export TED", command=self.exportTed) filemenu.add_separator() filemenu.add_command(label="Import Image", command=self.importImg) filemenu.add_command(label="Discard Image", command=self.discardImg) filemenu.add_separator() filemenu.add_command(label="Quit", command=self.quit) self.menubar.add_cascade(label="File", menu=filemenu) self.master.config(menu=self.menubar) self.canvas = CX.CanvasX(self, width=800, height=600) self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL) self.hbar.pack(side=tk.BOTTOM, fill=tk.X) self.hbar.config(command=self.canvas.xview) self.vbar = tk.Scrollbar(self, orient=tk.VERTICAL) self.vbar.pack(side=tk.RIGHT, fill=tk.Y) self.vbar.config(command=self.canvas.yview) self.canvas.config(scrollregion=(-1000, -1000, 1000, 1000), confine=True) self.canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set) self.canvas.pack(side=tk.LEFT, expand=True, fill=tk.BOTH) self.canvas.bind("<ButtonPress-3>", self.onButton3Press) self.canvas.bind("<ButtonRelease-3>", self.onButton3Release) self.canvas.bind("<MouseWheel>", self.onWheel) self.canvas.bind("<Motion>", self.onMouseMotion) self.canvas.bind("<Configure>", self.onConfigure) self.canvas.focus_set() self.img = None #Image.open("pau.png") self.simg = None #self.img self.pimg = None #ImageTk.PhotoImage(self.img) self.imgcid = None #self.canvas.create_image(0, 0, image=self.pimg, anchor=tk.NW) #self.canvas.tag_lower(self.imgcid) self.dragging = False self.drawCoordGrid() self.cc = ControlCurve() # self.cc.movePoint(self.cc.point[0],coords(100,100)) # self.cc.appendPoint(coords(200,110)) # self.cc.appendPoint(coords(520,400), SegType.Biarc) # self.cc.insertPoint(1,coords(320,310),SegType.Biarc) # cp,s = self.cc.insertPoint(1,coords(220,210),SegType.Biarc) # self.cc.removePoint(cp) self.cc.movePoint(self.cc.point[0], coords(100, 100)) self.cc.appendPoint(coords(100, 200)) self.cc.appendPoint(coords(300, 200), SegType.Biarc) self.cc.appendPoint(coords(500, 200), SegType.Biarc) self.cc.appendPoint(coords(700, 200), SegType.Biarc) self.cc.toggleOpen() self.ccmanip = CCManip(self.cc, self.canvas)
def importTed(self): path = self.askOpenFileName() tedfile = "" try: with open(path, mode='rb') as file: tedfile = file.read() except FileNotFoundError: print("file not found!") return hdr = ted.ted_data_to_tuple("header", ted.header, tedfile, 0) cps = ted.ted_data_to_tuple_list("cp", ted.cp, tedfile, hdr.cp_offset, hdr.cp_count) banks = ted.ted_data_to_tuple_list("bank", ted.segment, tedfile, hdr.bank_offset, hdr.bank_count) heights = ted.ted_data_to_tuple_list("height", ted.height, tedfile, hdr.height_offset, hdr.height_count) checkps = ted.ted_data_to_tuple_list("checkpoints", ted.checkpoint, tedfile, hdr.checkpoint_offset, hdr.checkpoint_count) road = ted.ted_data_to_tuple_list("road", ted.road, tedfile, hdr.road_offset, hdr.road_count) deco = ted.ted_data_to_tuple_list("decoration", ted.decoration, tedfile, hdr.decoration_offset, hdr.decoration_count) self.cc = ControlCurve() #skip = -1 for i, cp in enumerate(cps): lx = (cps[i - 1].x - cp.x) ly = (cps[i - 1].y - cp.y) l = m.sqrt(lx * lx + ly * ly) print(i, ted.SegType(cp.segtype), cp.x, cp.y, cp.center_x, cp.center_y, l) sys.stdout.flush() if (ted.SegType(cp.segtype) == ted.SegType.Straight): if i == 0: self.cc.movePoint(self.cc.point[0], coords(500 + cp.x, cp.y - 1500)) else: self.cc.appendPoint(coords(500 + cp.x, cp.y - 1500), SegType.Straight) if (ted.SegType(cp.segtype) == ted.SegType.Arc2CCW or ted.SegType(cp.segtype) == ted.SegType.Arc2CW): self.cc.appendPoint(coords(500 + cp.x, cp.y - 1500), SegType.Biarc) dx = (cp.x - cp.center_x) dy = (cp.y - cp.center_y) r = m.sqrt(dx * dx + dy * dy) ast = m.atan2(dy, dx) if ted.SegType(cp.segtype) == ted.SegType.Arc2CCW: t = unit(coords(dy, -dx)) if ted.SegType(cp.segtype) == ted.SegType.Arc2CW: t = unit(coords(-dy, dx)) self.cc.point[-1].tangent = t self.ccmanip = CCManip(self.cc, self.canvas) pass
def __init__(self, point=coords(0, 0), tangent=None): self.point = point self.tangent = tangent
return umt * umt * ps[0] + 2 * umt * t * ps[1] + t * t * ps[2] def bezier2_d(t, ps): umt = 1 - t return 2 * umt * (ps[1] - ps[0]) + 2 * t * (ps[2] - ps[1]) def bezier2_dr(t, ps): # use quotient rule cut = [la.cut(ps[0]), la.cut(ps[1]), la.cut(ps[2])] xt = bezier2(t, cut) dxt = bezier2_d(t, cut) w = [ps[0][2], ps[1][2], ps[2][2]] wt = bezier2(t, w) dwt = bezier2_d(t, w) return (dxt * wt - dwt * xt) / (wt * wt) def arc(p0, p1, p2): w = la.dot(la.unit(p1 - p0), la.unit(p2 - p0)) return [la.hom(p0, 1), la.hom(p1, w), la.hom(p2, 1)] #A = arc(la.coords(0,0),la.coords(1,1),la.coords(0,2)) A = [la.coords(1, 0, 1), la.coords(0, 4, 0), la.coords(5, 0, 1)] p = bezier2(0.5, A) t = bezier2_dr(0.5, A) print(p, t) print(la.proj(p))