<<>> <> <> <> <> <> <> <> DIRECTORY Cubic2, Vector2, Imager; Cubic2Impl: CEDAR PROGRAM IMPORTS Vector2 EXPORTS Cubic2 = { OPEN Vector2, Cubic2; VEC: TYPE = Imager.VEC; CoeffsToBezier: PUBLIC PROC [coeffs: Coeffs] RETURNS [bezier: Bezier] = { <> <> <> <> <> <> <> bezier.b0 ¬ coeffs.c0; bezier.b1 ¬ Add[coeffs.c0,Div[coeffs.c1,3]]; bezier.b2 ¬ Add[bezier.b1,Div[Add[coeffs.c1,coeffs.c2],3]]; bezier.b3 ¬ Add[Add[Add[coeffs.c0,coeffs.c1],coeffs.c2],coeffs.c3]; RETURN[bezier]; }; BezierToCoeffs: PUBLIC PROC [bezier: Bezier] RETURNS [coeffs: Coeffs] = { <> <> <> <> <> t: VEC ¬ Mul[Sub[bezier.b2,bezier.b1],3]; coeffs.c0 ¬ bezier.b0; coeffs.c1 ¬ Mul[Sub[bezier.b1,bezier.b0],3]; coeffs.c2 ¬ Sub[t,coeffs.c1]; coeffs.c3 ¬ Sub[bezier.b3,Add[bezier.b0,t]]; RETURN[coeffs]; }; AlphaSplit: PUBLIC PROC [bezier: Bezier, alpha: REAL] RETURNS[Bezier,Bezier] = { <> Fraction: PROC[q,r: VEC, alpha: REAL, beta: REAL] RETURNS [VEC] = { RETURN[[q.x*beta+r.x*alpha, q.y*beta+r.y*alpha]] }; a,b,c,ab,bc,p: VEC; oneMinusAlpha: REAL; oneMinusAlpha ¬ 1.0-alpha; a ¬ Fraction[bezier.b0, bezier.b1, alpha, oneMinusAlpha]; b ¬ Fraction[bezier.b1, bezier.b2, alpha, oneMinusAlpha]; c ¬ Fraction[bezier.b2, bezier.b3, alpha, oneMinusAlpha]; ab ¬ Fraction[a, b, alpha, oneMinusAlpha]; bc ¬ Fraction[b, c, alpha, oneMinusAlpha]; p ¬ Fraction[ab, bc, alpha, oneMinusAlpha]; RETURN[[bezier.b0, a, ab, p],[p, bc, c, bezier.b3]]; }; Split: PUBLIC PROC [bezier: Bezier] RETURNS [Bezier,Bezier] = { a,b,c,ab,bc,p: VEC; Mid: PROC [u,v: VEC] RETURNS [VEC] = INLINE { RETURN[[(u.x+v.x)/2,(u.y+v.y)/2]] }; a ¬ Mid[bezier.b0,bezier.b1]; b ¬ Mid[bezier.b1,bezier.b2]; c ¬ Mid[bezier.b2,bezier.b3]; ab ¬ Mid[a,b]; bc ¬ Mid[b,c]; p ¬ Mid[ab,bc]; RETURN[[bezier.b0, a, ab, p],[p, bc, c, bezier.b3]]; }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<}>> <> <> <> <<};>> <<};>> << [Artwork node; type 'ArtworkInterpress on' to command tool] >> Flat: PUBLIC PROC [bezier: Bezier, epsilon: REAL] RETURNS [BOOL] = { <> <> <> dx,dy: REAL; d1,d2,d,bl,bh: VEC; oh: VEC=[epsilon, epsilon]; <> bh ¬ Vector2.Add[UpperRight[bezier.b0,bezier.b3],oh]; bl ¬ Vector2.Sub[LowerLeft[bezier.b0,bezier.b3],oh]; IF ~In[bezier.b1,bl,bh] OR ~In[bezier.b2,bl,bh] THEN RETURN[FALSE]; <> d ¬ Vector2.Sub[bezier.b3,bezier.b0]; dx ¬ ABS[d.x]; dy ¬ ABS[d.y]; IF dx+dy < epsilon THEN RETURN[TRUE]; <> d1 ¬ Vector2.Sub[bezier.b1,bezier.b0]; d2 ¬ Vector2.Sub[bezier.b2,bezier.b0]; IF dy < dx THEN { <> dydx: REAL ¬ d.y/d.x; RETURN[ABS[d2.y-d2.x*dydx]> dxdy: REAL ¬ d.x/d.y; RETURN[ABS[d2.x-d2.y*dxdy]