DIRECTORY Seq, Cubic USING [Bezier], Complex USING [Vec], LSPiece USING [Metrics, MetricsRec], Nodes, Filters, FitState USING [StartSamples, AddSample, CurrentSamples, SetClosed, GetClosed, CurrentNodes, CurrentCorners, AddCorner, AddNode, ResetData], FitJaM USING [RegisterInit, InitProc, defaultFitState, defaultHighlight], Highlight USING [ShowBezier, CleanUp], JaM; NodesAndFiltersJaM: CEDAR PROGRAM IMPORTS JaM, FitState, Filters, FitJaM, Nodes, Highlight = { GetSamples: PROC RETURNS [samples: Seq.ComplexSequence, closed: BOOLEAN] = { samples _ FitState.CurrentSamples[FitJaM.defaultFitState]; closed _ FitState.GetClosed[FitJaM.defaultFitState]; RETURN[samples, closed]; }; SetSamples: PROC [samples: Seq.ComplexSequence, closed: BOOLEAN] = { tangents, ctangents: Seq.ComplexSequence; nodes, corners: Seq.NatSequence; [corners, ctangents] _ GetCorners[]; [nodes, tangents] _ GetNodes[]; FitState.StartSamples[FitJaM.defaultFitState, samples[0].x,samples[0].y]; FOR i: NAT IN [1..samples.length) DO FitState.AddSample[FitJaM.defaultFitState, samples[i].x,samples[i].y]; ENDLOOP; FitState.SetClosed[FitJaM.defaultFitState, closed]; SetNodes[nodes, tangents]; SetCorners[corners, ctangents]; }; GetCorners: PROC RETURNS[corners: Seq.NatSequence, tangents: Seq.ComplexSequence] = { [corners, tangents] _ FitState.CurrentCorners[FitJaM.defaultFitState]; }; SetCorners: PROC[corners: Seq.NatSequence, tangents: Seq.ComplexSequence] = { FitState.ResetData[FitJaM.defaultFitState, corners]; FOR i: NAT IN [0..corners.length) DO FitState.AddCorner[FitJaM.defaultFitState, corners[i], [tangents[i].x, tangents[i].y], [tangents[i+1].x, tangents[i+1].y]]; ENDLOOP; }; GetNodes: PROC RETURNS[nodes: Seq.NatSequence, tangents: Seq.ComplexSequence] = { [nodes, tangents] _ FitState.CurrentNodes[FitJaM.defaultFitState]; }; SetNodes: PROC [nodes: Seq.NatSequence, tangents: Seq.ComplexSequence] = { FitState.ResetData[FitJaM.defaultFitState, nodes]; FitState.AddNode[FitJaM.defaultFitState, 0]; IF tangents#NIL THEN FOR i:NAT IN [0..nodes.length) DO FitState.AddNode[FitJaM.defaultFitState, nodes[i], tangents[i]]; IF tangents[i]=[0,0] THEN FitState.AddCorner[FitJaM.defaultFitState, nodes[i], [0,0], [0,0]]; ENDLOOP ELSE FOR i:NAT IN [0..nodes.length) DO FitState.AddNode[FitJaM.defaultFitState, nodes[i], [0,0]]; ENDLOOP; }; Dynfilter: PROC [state: JaM.State] = { samples: Seq.ComplexSequence; closed: BOOLEAN; tolerance: REAL _ JaM.PopReal[state]; badness: REAL; [samples,closed] _ GetSamples[]; IF samples=NIL THEN RETURN; [samples, badness] _ Filters.Dynfilter[samples, closed, tolerance]; SetSamples[samples, closed]; JaM.PushReal[state, badness]; }; AveFilter: PROC [state: JaM.State] = { samples: Seq.ComplexSequence; closed: BOOLEAN; [samples,closed] _ GetSamples[]; IF samples=NIL THEN RETURN; samples _ Filters.AveFilter[samples, closed]; SetSamples[samples, closed]; }; AveFilterLeavingCorners: PROC [state: JaM.State] = { samples: Seq.ComplexSequence; corners: Seq.NatSequence; closed: BOOLEAN; [samples,closed] _ GetSamples[]; IF samples=NIL THEN RETURN; [corners, ] _ GetCorners[]; samples _ Filters.AveFilterLeavingCorners[samples: samples, closed: closed, corners: corners]; SetSamples[samples, closed]; }; DynNodes: PROC [state: JaM.State] = {-- penalty => . Finds nodes using DynFit nodes: Seq.NatSequence; closed: BOOLEAN; samples: Seq.ComplexSequence; [samples,closed] _ GetSamples[]; nodes _ Nodes.DynNodes[samples: samples, closed: closed, penalty: JaM.PopReal[state]]; SetNodes[nodes, NIL]; }; metrics: LSPiece.Metrics _ NEW[LSPiece.MetricsRec]; CubicTangents: PROC[state: JaM.State] = {-- range err maxit => . Sets tangents at nodes by locally fitting a cubic between neighboring nodes nodes: Seq.NatSequence; samples, tangents: Seq.ComplexSequence; closed: BOOLEAN; nodeIndex: NAT _ 0; newTangent: Nodes.Progress = { Highlight.ShowBezier[FitJaM.defaultHighlight, cubic]; FitState.AddNode[FitJaM.defaultFitState, nodes[nodeIndex], tangent]; nodeIndex _ nodeIndex+1; RETURN[JaM.GetAbort[state]]; }; metrics.maxItr _ JaM.PopInt[state]; metrics.sumErr _ JaM.PopReal[state]; [samples,closed] _ GetSamples[]; [nodes,] _ FitState.CurrentNodes[FitJaM.defaultFitState]; nodeIndex _ 0; tangents _ NEW[Seq.ComplexSequenceRec[nodes.length]]; Nodes.ICubicTangents[newTangent, samples, closed, metrics, nodes]; --calls newTangent in a loop Highlight.CleanUp[FitJaM.defaultHighlight]; SetNodes[nodes,tangents]; }; QuickTangents: PROC[state: JaM.State] = {-- maxAngle => . computes tangents by differencing neighbors maxAngle: REAL _ JaM.PopReal[state]; nodes: Seq.NatSequence; samples, tangents: Seq.ComplexSequence; closed: BOOLEAN; [samples,closed] _ GetSamples[]; [nodes,] _ FitState.CurrentNodes[FitJaM.defaultFitState]; tangents _ Nodes.QuickTangents[samples, closed, maxAngle, nodes]; SetNodes[nodes,tangents]; }; SquareTangents: PROC[state: JaM.State] = {-- maxAngle => . computes tangents, weighting the longer edges more maxAngle: REAL _ JaM.PopReal[state]; nodes: Seq.NatSequence; samples, tangents: Seq.ComplexSequence; closed: BOOLEAN; [samples,closed] _ GetSamples[]; [nodes,] _ FitState.CurrentNodes[FitJaM.defaultFitState]; tangents _ Nodes.SquareTangents[samples, closed, maxAngle, nodes]; SetNodes[nodes,tangents]; }; Init: FitJaM.InitProc = { JaM.Register[state, ".dfsa",Dynfilter]; JaM.Register[state, ".afsa",AveFilter]; JaM.Register[state, ".filterbetweencorners",AveFilterLeavingCorners]; JaM.Register[state, ".dynnodes",DynNodes]; -- penalty => . Finds nodes using DynFit JaM.Register[state, ".cubictangents",CubicTangents]; -- err maxit => . Sets tangents at nodes by fitting between neighboring nodes. JaM.Register[state, ".quicktangents",QuickTangents]; -- maxangle => . computes tangents by differencing neighbors. JaM.Register[state, ".squaretangents",SquareTangents]; -- maxangle => . computes tangents, weighting the longer edges more. }; FitJaM.RegisterInit[id: $NodesAndFiltersJaM, proc: Init]; }. ~NodesAndFiltersJaM.mesa JaM interfaces for Filters, Nodes and Tangents Maureen Stone October 30, 1984 7:10:11 pm PST ʘJšœ™Jšœ.™.Jšœ/™/šÏk ˜ Jšœ˜Jšœœ ˜Jšœœ˜Jšœœ˜$J˜J˜Jšœ œ~˜ŒJšœœ=˜IJšœ œ˜&J˜—šœœ˜!Jšœ5˜˜VJšœF˜FJ˜J˜—šž œœ=˜MJšœ4˜4šœœœ˜$Jšœ{˜{Jšœ˜—J˜J˜—šžœœœ<˜RJšœB˜BJ˜J˜—šžœœ<˜JJšœ2˜2Jšœ,˜,š œ œœœœœ˜6Jšœ@˜@JšœœD˜]Jš˜—š œœœœ˜&Jšœ:˜:Jšœ˜—J˜J˜—šž œœ˜&Jšœ˜Jšœœ˜Jšœ œ˜%Jšœ œ˜Jšœ ˜ Jšœ œœœ˜JšœC˜CJ˜J˜J˜J˜—šž œœ˜&Jšœ˜Jšœœ˜Jšœ ˜ Jšœ œœœ˜J˜-J˜J˜J˜—šžœœ˜4Jšœ˜J˜Jšœœ˜Jšœ ˜ Jšœ œœœ˜J˜Jšœ^˜^J˜J˜J˜—šžœœÏc(˜MJšœ˜Jšœœ˜Jšœ˜Jšœ ˜ JšœV˜VJšœœ˜J˜J˜—Jšœœ˜3šž œœŸc˜ŒJ˜J˜'Jšœœ˜Jšœ œ˜šœ˜J˜5JšœD˜DJ˜Jšœ˜J˜—Jšœ#˜#Jšœ$˜$Jšœ ˜ Jšœ9˜9J˜Jšœ œ'˜5JšœDŸ˜`J˜+Jšœ˜J˜J˜—šž œœŸ<˜eJšœ œ˜$J˜J˜'Jšœœ˜Jšœ ˜ Jšœ9˜9JšœA˜AJšœ˜J˜—šžœœŸC˜mJšœ œ˜$J˜J˜'Jšœœ˜Jšœ ˜ Jšœ9˜9JšœB˜BJšœ˜J˜J˜J˜—šžœ˜J˜'J˜'J˜EJšœ+Ÿ(˜SJšœ5ŸN˜ƒJšœ5Ÿ=˜rJšœ7ŸD˜{J˜J˜—J˜9J˜—…—@À