def drawControlCurve(self): self.app.canvas.delete("obj") if (self.mode): p0, p1 = point(self.cps[1]), point(self.cps[2]) t0 = vector(self.cps[1], self.cps[0]) t1 = vector(self.cps[3], self.cps[2]) r = 1 #for v in range(5): #r = 0.2*(1-v/5)+1.8*(v/5) c1, c2, c3, a, b = biarc_h(p0, t0, p1, t1, r) cx, rx = circparam(p0, proj(c1), proj(c2)) cy, ry = circparam(proj(c2), proj(c3), p1) cid = self.app.canvas.create_oval(cx[0] - 15, cx[1] - 15, cx[0] + 15, cx[1] + 15, outline="black", fill="green", tags="obj") cid = self.app.canvas.create_oval(cy[0] - 15, cy[1] - 15, cy[0] + 15, cy[1] + 15, outline="black", fill="green", tags="obj") if (c1 == None): return cl = [p0, c1, c2, c3, p1] cas = [] for j in range(0, 11): cas.append((circarc_h(j / 10, [hom(p0, 1), c1, c2]))) for j in range(0, 11): cas.append((circarc_h(j / 10, [c2, c3, hom(p1, 1)]))) #clc = [*x for x in cl] carc = [(x[0], x[1]) for x in cas] #self.app.canvas.create_line(clc,fill="lightblue",tag="obj") self.app.canvas.create_line(carc, fill="darkgreen", tag="obj") else: for i in range(2, len(self.cps)): cas = [] for j in range(0, 11): cas.append((circarc(j / 10, self.cls[i - 2], self.cps[i - 2:i + 1]))) #print(cas) cl = [(x[0], x[1]) for x in self.cps[i - 2:i + 1]] carc = [(x[0], x[1]) for x in cas] self.app.canvas.create_line(cl, fill="lightblue", tag="obj") self.app.canvas.create_line(carc, fill="darkgreen", tag="obj") sys.stdout.flush()
def circarc(t, v, ps): n1, l1 = unit_length(vector(ps[1], ps[0])) n2, l2 = unit_length(vector(ps[1], ps[2])) l = min(l1, l2) p0 = hom(point(ps[1]) - l * v * n1, 1) p2 = hom(point(ps[1]) - l * v * n2, 1) w = dot(n1, unit((p2[0] - p0[0], p2[1] - p0[1]))) p1 = hom(point(ps[1]), w) x = bezier2(t, [p0, p1, p2]) return proj(x)
def drawControlCurve(self): self.app.canvas.delete("obj") if (self.mode): p0, p1 = point(self.cps[1]), point(self.cps[2]) t0 = vector(self.cps[1], self.cps[0]) t1 = vector(self.cps[3], self.cps[2]) r = 1 #for v in range(5): #r = 0.2*(1-v/5)+1.8*(v/5) c1, c2, c3, a, b = biarc_h(p0, t0, p1, t1, r) if (c1 == None): return cl = [p0, c1, c2, c3, p1] cas = [] for j in range(0, 11): cas.append((circarc_h(j / 10, [hom(p0, 1), c1, c2]))) for j in range(0, 11): cas.append((circarc_h(j / 10, [c2, c3, hom(p1, 1)]))) #clc = [self.app.o2c(*x) for x in cl] carc = [self.app.o2c(*x) for x in cas] #self.app.canvas.create_line(clc,fill="lightblue",tag="obj") self.app.canvas.create_line(carc, fill="darkgreen", tag="obj") else: for i in range(2, len(self.cps)): cas = [] for j in range(0, 11): cas.append((circarc(j / 10, self.cls[i - 2], self.cps[i - 2:i + 1]))) #print(cas) cl = [self.app.o2c(*x) for x in self.cps[i - 2:i + 1]] carc = [self.app.o2c(*x) for x in cas] self.app.canvas.create_line(cl, fill="lightblue", tag="obj") self.app.canvas.create_line(carc, fill="darkgreen", tag="obj") sys.stdout.flush()
def __init__(self, app): super().__init__() self.app = app self.cps = [] self.cls = [] self.cidmap = {} self._ori = {"cx": 0, "cy": 0, "ox": 0, "oy": 0, "item": None} self.cps = [ point((100, 100)), point((100, 300)), point((400, 300)), point((400, 600)) ] self.cls = [0.5, 0.5, 0.5] self.mode = 1 self.mode = 0 self.manip = Manip.Idle self.inserter = MouseManipulator(self, self.app, 1, None, Manip.Insert)
def onHandleMotion(self, event): if (self.manip is not Manip.Move): return print("HandleMotion") sys.stdout.flush() cx, cy = self.app.w2c(event.x, event.y) ox, oy = self.app.w2o(event.x, event.y) delta_cx = cx - self._ori["cx"] delta_cy = cy - self._ori["cy"] delta_ox = ox - self._ori["ox"] delta_oy = oy - self._ori["oy"] self._ori["cx"] = cx self._ori["cy"] = cy self._ori["ox"] = ox self._ori["oy"] = oy # 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] = point(self.cps[i]) + point((delta_ox, delta_oy)) self.drawControlCurve()
def biarc_h(p0, t0, p1, t1, r): t0 = unit(t0) t1 = unit(t1) chord = point(p0) - point(p1) f = dot(t0, t1) g = dot(chord, r * t0 + t1) r = (1 / 3) * (f + 1) / 2 + 1 * (1 - (f + 1) / 2) r = 1 c = dot(chord, chord) b = 2 * dot(chord, r * t0 + t1) a = 2 * r * (dot(t0, t1) - 1) if a == 0: c2 = lerp(0.5, p0, p1) c1 = lerp(0.5, p0, c2) c3 = lerp(0.5, c2, p1) w1 = 1 #dot( t0,unit(c2 - p0)) w2 = 1 #dot( t1,unit(p1 - c2)) return hom(c1, w1), hom(c2, 1), hom(c3, w2), 1, 1 D = b * b - 4 * a * c if D < 0: print(D, "<0") beta = norm2(chord) / 4 * dot(chord, t0) else: sqD = D**.5 beta1 = (-b - sqD) / 2 / a beta2 = (-b + sqD) / 2 / a if beta1 > 0 and beta2 > 0: print(beta1, beta2, ">0") return None, None, None, 0, 0 beta = max(beta1, beta2) if beta < 0: print(beta, "<0") return None, None, None, 0, 0 alpha = beta * r ab = alpha + beta c1 = point(p0) + alpha * t0 c3 = point(p1) - beta * t1 c2 = (beta / ab) * point(c1) + (alpha / ab) * point(c3) #print(alpha,beta) w1 = dot(t0, unit(c2 - p0)) w2 = dot(t1, unit(p1 - c2)) return hom(c1, w1), hom(c2, 1), hom(c3, w2), alpha, beta
def biarc(p0, t0, p1, t1, r): t0 = unit(t0) t1 = unit(t1) chord = point(p0) - point(p1) f = dot(t0, t1) g = dot(chord, r * t0 + t1) r = (1 / 3) * (f + 1) / 2 + 1 * (1 - (f + 1) / 2) c = dot(chord, chord) b = 2 * dot(chord, r * t0 + t1) a = 2 * r * (dot(t0, t1) - 1) if a == 0: return None, None, None, 0, 0 D = b * b - 4 * a * c if D < 0: print(D, "<0") beta = norm2(chord) / 4 * dot(chord, t0) else: sqD = D**.5 beta1 = (-b - sqD) / 2 / a beta2 = (-b + sqD) / 2 / a if beta1 > 0 and beta2 > 0: print(beta1, beta2, ">0") return None, None, None, 0, 0 beta = max(beta1, beta2) if beta < 0: print(beta, "<0") return None, None, None, 0, 0 alpha = beta * r ab = alpha + beta c1 = point(p0) + alpha * t0 c3 = point(p1) - beta * t1 c2 = (beta / ab) * point(c1) + (alpha / ab) * point(c3) #print(alpha,beta) return c1, c2, c3, alpha, beta
def lerp(t, a, b): return (1 - t) * point(a) + t * point(b)