-- SplineImpl.mesa -- Last changed by Doug Wyatt, September 1, 1982 12:07 pm DIRECTORY Graphics USING [Path, MoveTo, CurveTo], CGCubic USING [Bezier, Coeffs, CoeffsToBezier], CGSpline USING [Coeffs, Coords, KnotsRep, MakeSpline, New, Ref], Spline USING [], CGStorage USING [pZone, qZone]; SplineImpl: CEDAR PROGRAM IMPORTS Graphics, CGCubic, CGSpline, CGStorage EXPORTS Spline = { knotZone: ZONE = CGStorage.pZone; repZone: ZONE = CGStorage.qZone; Knots: TYPE = REF KnotsRep; KnotsRep: TYPE = CGSpline.KnotsRep; Ref: TYPE = REF Rep; Rep: PUBLIC TYPE = RECORD[knots: Knots, spline: CGSpline.Ref]; New: PUBLIC PROC RETURNS[Ref] = { knots: Knots _ knotZone.NEW[KnotsRep[20] _ [length: 0, array: ]]; spline: CGSpline.Ref _ CGSpline.New[]; RETURN[repZone.NEW[Rep _ [knots,spline]]]; }; Reset: PUBLIC PROC[self: Ref] = { self.knots.length _ 0; }; Knot: PUBLIC PROC[self: Ref, x,y: REAL] = { knots: Knots _ self.knots; i: NAT _ knots.length; size: NAT _ i + 1; space: NAT _ knots.space; IF size>space THEN { new: Knots _ knotZone.NEW[KnotsRep[space+space/2] _ [length: 0, array: ]]; FOR j: NAT IN[0..i) DO new[j] _ knots[j] ENDLOOP; knots _ self.knots _ new; }; knots[i] _ [x,y]; knots.length _ size; }; Enter: PUBLIC PROC[self: Ref, path: Graphics.Path, cyclic: BOOLEAN, flush: BOOLEAN] = { first: BOOLEAN _ TRUE; Proc: PROC[coeffs: CGSpline.Coeffs] = { OPEN coeffs; c: CGCubic.Coeffs _ [c0: [t0[X],t0[Y]], c1: [t1[X],t1[Y]], c2: [t2[X],t2[Y]], c3: [t3[X],t3[Y]]]; b: CGCubic.Bezier _ CGCubic.CoeffsToBezier[c]; IF first THEN { Graphics.MoveTo[path,b.b0.x,b.b0.y,flush]; first _ FALSE }; Graphics.CurveTo[path, b.b1.x,b.b1.y,b.b2.x,b.b2.y,b.b3.x,b.b3.y]; }; IF self.knots.length=0 THEN RETURN; IF cyclic THEN { k: CGSpline.Coords _ self.knots[0]; Knot[self,k[X],k[Y]] }; CGSpline.MakeSpline[self.spline,self.knots,(IF cyclic THEN cyclicAL ELSE naturalAL),Proc]; self.knots.length _ 0; }; }.