--DCubicsSub.mesa --m.stone April 1, 1981 9:53 PM -- Last Edited by: Stone, March 15, 1983 3:26 pm DIRECTORY Real: FROM "Real", Inline: FROM "Inline", SplineDefs: FROM "SplineDefs"; DCubicsSub: PROGRAM IMPORTS Real,Inline EXPORTS SplineDefs = BEGIN OPEN SplineDefs; Vals: TYPE= RECORD[Fx: LONG INTEGER, Cx: LONG INTEGER, Fy: LONG INTEGER, Cy: LONG INTEGER]; PutPt: PROCEDURE[SplineDefs.ScrPt]; scaler: LONG INTEGER _ 200000B; tol: LONG INTEGER _ scaler/2; DisplayCubic: PUBLIC PROCEDURE [coeffs: Coeffs, MoveTo: PROCEDURE[SplineDefs.ScrPt], DrawTo: PROCEDURE[SplineDefs.ScrPt]] = BEGIN ONE: REAL _ 1; E2: REAL _ 100; pt: ScrPt; val0,val1: Vals; --set initial values. assume t0=0, t1=1 deltaT**2=1 --F[0], F[1], C _ deltaT^2*(6at+2b)/2 val0 _ Vals[Real.RoundLI[scaler*coeffs.t0[X]], Real.RoundLI[scaler*coeffs.t2[X]], Real.RoundLI[scaler*coeffs.t0[Y]], Real.RoundLI[scaler*coeffs.t2[Y]]]; val1 _ Vals[Real.RoundLI[scaler*(coeffs.t3[X]+coeffs.t2[X]+coeffs.t1[X]+coeffs.t0[X])], Real.RoundLI[scaler*(3*coeffs.t3[X]+coeffs.t2[X])], Real.RoundLI[scaler*(coeffs.t3[Y]+coeffs.t2[Y]+coeffs.t1[Y]+coeffs.t0[Y])], Real.RoundLI[scaler*(3*coeffs.t3[Y]+coeffs.t2[Y])] ]; --do first MoveTo pt[X] _ DoubleToInt[val0.Fx]; pt[Y] _ DoubleToInt[val0.Fy]; MoveTo[pt]; PutPt _ DrawTo; DrawCurve[val0, val1]; pt[X] _ DoubleToInt[val1.Fx]; --seems to be necessary pt[Y] _ DoubleToInt[val1.Fy]; DrawTo[pt]; END; --recursive subdivision DrawCurve: PROCEDURE[val1: Vals, val2: Vals ]= BEGIN x1,x2,y1,y2: INTEGER; pt: ScrPt; DO x1 _ DoubleToInt[val1.Fx]; x2 _ DoubleToInt[val2.Fx]; y1 _ DoubleToInt[val1.Fy]; y2 _ DoubleToInt[val2.Fy]; SELECT TRUE FROM (ABS[val1.Cx] < tol AND ABS[val1.Cy] < tol AND ABS[val2.Cx] < tol AND ABS[val2.Cy] < tol) => BEGIN pt _ [x2,y2]; --compiler error if use constuctor in arg list PutPt[pt]; RETURN; END; (ABS[x1-x2] <=1 AND ABS[y1-y2] <=1) => BEGIN pt _ [x2,y2]; --compiler error if use constuctor in arg list PutPt[pt]; RETURN; END; ENDCASE => BEGIN valc: Vals; val1.Cx _DoubleHalve[DoubleHalve[ val1.Cx]]; val2.Cx _ DoubleHalve[DoubleHalve[val2.Cx]]; valc.Cx _ DoubleHalve[(val1.Cx+val2.Cx)]; valc.Fx _ DoubleHalve[val1.Fx+val2.Fx] - valc.Cx; val1.Cy _DoubleHalve[DoubleHalve[ val1.Cy]]; val2.Cy _ DoubleHalve[DoubleHalve[val2.Cy]]; valc.Cy _ DoubleHalve[(val1.Cy+val2.Cy)]; valc.Fy _ DoubleHalve[val1.Fy+val2.Fy] - valc.Cy; DrawCurve[val1,valc]; val1 _valc; --instead of a second call to DrawCurve END; ENDLOOP; END; --round a Double to an INTEGER DoubleToInt: PROCEDURE[double: LONG INTEGER] RETURNS[i: INTEGER] = INLINE BEGIN OPEN Inline; i _ HighHalf[double]+(IF CARDINAL[LowHalf[double]] > 77777B THEN 1 ELSE 0); END; DoubleHalve: PROCEDURE [dint: LONG INTEGER] RETURNS [dintover2: LONG INTEGER] = INLINE BEGIN OPEN Inline; ln: LongNumber; ln.li _ dint; ln.lowbits _ BITSHIFT[ln.lowbits,-1] + (IF ln.highbits MOD 2 = 1 THEN 100000B ELSE 0); ln.highbits _ BITSHIFT[ln.highbits,-1] + (IF ln.highbits > 77777B THEN 100000B ELSE 0); dintover2 _ ln.li; END; END. (635)\1111i18I1481b1B343b1B