2. Implementation
LSPieceImpl implements the iterative fitting algorithm for a single parametric cubic piece. Most clients will not call LSPieceImpl directly, but will use PiecewiseFit.
PiecewiseFitImpl implements a number of algorithms for selecting joints from a list of potential joints. Most clients are satisfied with
GrowSpline. Use
DynSpline if the data is noisy. your choice of potential joints is poor, or your are looking for the minimum number of cubic pieces for your curve.
Cubic2Proc:
TYPE =
PROC[bezier: Cubic2.Bezier, sumErr, maxDev:
REAL, iterations:
INT]
RETURNS[quit:
BOOLEAN ←
FALSE];
The output curve and the metrics for its fit. The sum of the squares of the distances from the points to the curve are returned in sumErr, and the largest deviation is returned in maxDev.
FitSpline:
PROC [data: Data, metrics: Metrics, outputCubic2: Cubic2Proc];
Makes every node a joint.
GrowSpline:
PROC [data: Data, metrics: Metrics, outputCubic2: Cubic2Proc, hilight: Cubic2Proc ←
NIL];
Finds joints by "growing" a cubic curve until the maximum deviation exceeds metrics.maxDev. Guarantees a fit within the maximum deviation Cheaper than DynSpline, but not as good results on noisy data.
DynSpline:
PROC [data: Data, metrics: Metrics, penalty:
REAL, trim:
BOOLEAN ← TRUE, outputCubic2: Cubic2Proc, hilight: Cubic2Proc ←
NIL];
Finds joints by dynamic programming. Penalty is the "cost" for making a joint. A larger penaltly will give you fewer joints. Trim turns on a heuristic to prune the dynamic programming tree. Use highlight if you want to display the intermediate cubics as the dynamic programming proceeds.
FitPiece:
PROC [data: Data, from, thru:
NAT, initFree, finalFree:
BOOLEAN ←
TRUE, metrics: Metrics, outputCubic2: Cubic2Proc];
Fits a single cubic piece in the range samples[from]..samples[thru]. If the curve is closed, thru can be smaller than from and the piece will "wrap around". initFree, finalFree ← TRUE force the curve through the end samples (default for all the above fitting procedures). Tangents should be set in the nodes and tangents sequences as above. This is here principally for client experimentation. Serious clients should use LSPiece.FitPiece for efficiency.
There is one algorithm that doesn't expect a preliminary selection of joints. This algorithm is under developement. Check with Maureen Stone before using it.
AdaptiveFit:
PROC [data: Data, from, thru:
NAT, initFree, finalFree:
BOOLEAN ←
TRUE, metrics: Metrics, outputCubic2: Cubic2Proc, tangent: TangentProc];
Ignores joint information and adaptively subdivides the samples, placing joints at the points of maximum deviation. The callback proc "tangent" will be called to get a tangent for the initial points and for each joint. Return [0,0] if tangent continuity is not desired.