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 draw(self, canvas, **kw): #c1,c2,c3,a,b = biarc_h(self.p0,self.t0,self.p1,self.t1,self.r) cas = [] for j in range(0, 50): cas.append(self.eval(j / 49)) cl = [ self.p0, proj(self.bp[0]), proj(self.bp[1]), proj(self.bp[2]), self.p1 ] return canvas.create_line([(x[0], x[1]) for x in cas], **kw)
def offset(self, o): b = deepcopy(self) pt0 = perp2(b.t0) pt1 = perp2(b.t1) c1 = proj(b.bp[0]) c2 = proj(b.bp[1]) c3 = proj(b.bp[2]) t2 = unit(c3 - c1) pt2 = perp2(t2) cc1 = unit(c2 - b.p0) cc2 = unit(b.p1 - c2) dp1 = dot(b.t0, cc1) dp2 = dot(b.t1, cc2) #t2 = unit(pt0 + refl(pt0,cc1)) #t3 = unit(pt1 + refl(pt1,cc2)) t2 = perp2(cc1) t3 = perp2(cc2) b.p0 = b.p0 + o * pt0 b.p1 = b.p1 + o * pt1 c2 = c2 + o * pt2 c1 = c1 + o / dp1 * t2 c3 = c3 + o / dp2 * t3 w1 = b.bp[0][2] #dot( b.t0,unit(c2 - b.p0)) w2 = b.bp[2][2] #dot( b.t1,unit(b.p1 - c2)) w1 = dot(b.t0, cc1) w2 = dot(b.t1, cc2) alpha = norm(c1 - c2) beta = norm(c3 - c2) b.r = alpha / beta b.bp = (hom(c1, w1), hom(c2, 1), hom(c3, w2), alpha, beta) b.h1 = [hom(b.p0, 1), b.bp[0], b.bp[1]] b.h2 = [b.bp[1], b.bp[2], hom(b.p1, 1)] return b
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 biarc_r_from_arcs(a1, a2): alpha = norm(a1[0] - proj(a1[1])) beta = norm(a1[3] - proj(a1[4])) return alpha / beta
def circarc_h(t, hs): x = bezier2(t, hs) return proj(x)
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))