-- LSCurve.mesa
-- Michael Plass November 29, 1982 9:52 am

DIRECTORY
  Cubic,
  Complex,
  Seq,
  LSFit,
  PiecewiseCubic;

LSCurve: DEFINITIONS IMPORTS Complex =
BEGIN OPEN Seq;

Patch: TYPE = LSFit.Patch;
PatchSequence: TYPE = LSFit.PatchSequence;
PatchSequenceRec: TYPE = LSFit.PatchSequenceRec;

Handle: TYPE = REF StateRec;
StateRec: TYPE = RECORD
   [z: ComplexSequence, -- the points to fit
    weight: RealSequence, -- weights for each point
    t: RealSequence, -- the current best guess of parameter values. Always between 0 and 1.
    oldt,oldoldt: RealSequence, -- for convergence acceleration
    l,n: NAT, -- use just the points in the range [l..n]
    splineBasis: SplineBasis, -- the current basis functions
    a: RealSequence, -- the coefficients on the basis funtions for the current fit
    free: BooleanSequence, -- tells which coefficients may be varied
    closedCurve: BOOLEAN,
    initialEndFree, finalEndFree: BOOLEAN, -- tells how to rescale
    -- implementor private stuff follows
    patchCacheValid: BOOLEAN ← FALSE,
    patchCache: SplineFunction
    ];

SplineBasis: TYPE = REF SplineBasisRec;
SplineBasisRec: TYPE =
    RECORD[SEQUENCE nBasis: NAT OF SplineFunction];

SplineFunction: TYPE = RECORD [x, y: PiecewiseCubic.Handle];

Create: PROCEDURE [sa: Seq.ComplexSequence] RETURNS [Handle];

XYat: PROCEDURE [h: Handle, t: REAL] RETURNS [Complex.Vec];

PatchesOf: PROCEDURE [h: Handle] RETURNS [x, y: PatchSequence, knots: RealSequence];

ArcLengthInitialTValues: PUBLIC PROCEDURE [h: Handle]; -- sets t values on the basis of arc length

UnitInitialTValues: PUBLIC PROCEDURE [h: Handle]; -- sets t values on equal steps

AngleInitialTValues: PUBLIC PROCEDURE [h: Handle];

AdjustTValues: PUBLIC PROCEDURE [h: Handle] RETURNS [maxChange: REAL]; -- uses 1 step of Newton's method

AccelTValues: PUBLIC PROCEDURE [h: Handle] RETURNS [r, maxChange: REAL]; -- applies convergence acceleration - assume SolveCurve has just been done

SolveTValues: PUBLIC PROCEDURE [h: Handle]; -- really sets the t values, assuming no old ones are known, but that the curve is known

SolveCurve: PUBLIC PROCEDURE [h: Handle]; -- finds the best fit, assuming the t values are known.  Only the free coefficients are altered.

PointSlopeBasis: PUBLIC PROCEDURE [h: Handle, b: Cubic.Bezier];

SmoothBasis: PUBLIC PROCEDURE [h: Handle, nKnots: NAT];

BSplineBasis: PUBLIC PROCEDURE [h: Handle, nKnots: NAT];

CubicBasis: PUBLIC PROCEDURE [h: Handle];

CubicPieceBasis: PUBLIC PROCEDURE [h: Handle];

ParabolaBasis: PUBLIC PROCEDURE [h: Handle];

CircleBasis: PUBLIC PROCEDURE [h: Handle];

EllipseBasis: PUBLIC PROCEDURE [h: Handle];

END.