DIRECTORY
Cubic USING [Bezier],
Complex USING [Vec],
LSPiece USING [Metrics, MetricsRec],
PotentialKnots,
FitJaM USING [RegisterInit, InitProc, defaultFitState],
Highlight USING [ShowBezier, CleanUp, Context],
JaM;
PotentialKnotsJaM: CEDAR PROGRAM
IMPORTS JaM, FitJaM, PotentialKnots, Highlight = {

highlight: Highlight.Context _ NIL;	--set this to FitJaM.defaultHighlight for debugging
-- penalty lineLength maxAngle   => . Finds nodes using DynFit
DynPoly: PROC [state: JaM.State] = {
maxAngle: REAL _ JaM.PopReal[state];
lineLength: REAL _ JaM.PopReal[state];
penalty: REAL _ JaM.PopReal[state];
PotentialKnots.DynPoly[state: FitJaM.defaultFitState, lineLength: lineLength, penalty: penalty, maxAngle: maxAngle];
};

QuickPoly: PROC [state: JaM.State] = {  --finds "lines" in a bitmap
PotentialKnots.QuickPoly[state: FitJaM.defaultFitState, highlight: highlight];
};

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
newTangent: PotentialKnots.Progress = {
Highlight.ShowBezier[highlight, cubic];
RETURN[JaM.GetAbort[state]];
};
metrics.maxItr _ JaM.PopInt[state];
metrics.sumErr _ JaM.PopReal[state];
PotentialKnots.CubicTangents[FitJaM.defaultFitState, metrics, newTangent];  --calls newTangent in a loop
Highlight.CleanUp[highlight];
};

QuickTangents: PROC[state: JaM.State] = {-- maxAngle setcorners => . computes tangents by differencing neighbors.  sets one-sided corners if setcorners=true
setCorners: BOOL _ JaM.PopBool[state];
maxAngle: REAL _ JaM.PopReal[state];
PotentialKnots.QuickTangents[FitJaM.defaultFitState, maxAngle, setCorners];
};
SquareTangents: PROC[state: JaM.State] = {-- maxAngle setcorners => . computes tangents, weighting the longer edges more.  sets one-sided corners if setcorners=true
setCorners: BOOL _ JaM.PopBool[state];
maxAngle: REAL _ JaM.PopReal[state];
PotentialKnots.SquareTangents[FitJaM.defaultFitState, maxAngle, setCorners];
};
CircleTangents: PROC[state: JaM.State] = {-- maxAngle setcorners => . computes tangents, weighting the longer edges more.  sets one-sided corners if setcorners=true
maxAngle: REAL _ JaM.PopReal[state];
PotentialKnots.CircleTangents[FitJaM.defaultFitState, maxAngle];
};
HVExtremes: PROC[state: JaM.State] = {  --forceKnot => puts nodes on extremes
PotentialKnots.HVExtremes[FitJaM.defaultFitState, JaM.PopBool[state]];
};
Find90: PROC[state: JaM.State] = {  --long maxangle forceknots => puts nodes on extremes
forceKnots: BOOL _ JaM.PopBool[state];
minFlat: REAL _ JaM.PopReal[state];
long: REAL _ JaM.PopReal[state];
PotentialKnots.Find90[FitJaM.defaultFitState, long, minFlat, forceKnots, highlight];
};

HVLines: PROC[state: JaM.State] = {  --long maxangle forceknots => puts nodes on extremes
forceKnots: BOOL _ JaM.PopBool[state];
maxAngle: REAL _ JaM.PopReal[state];
long: REAL _ JaM.PopReal[state];
PotentialKnots.HVLines[FitJaM.defaultFitState, long, maxAngle, forceKnots, highlight];
};

HVTangents: PROC[state: JaM.State] = {  --maxangle forceknots  => puts nodes on extremes
forceKnots: BOOL _ JaM.PopBool[state];
maxAngle: REAL _ JaM.PopReal[state];
PotentialKnots.HVTangents[FitJaM.defaultFitState, maxAngle, forceKnots];
};

NearlyEqual: PROC[state: JaM.State] = {  --maxangle  => sets nearly equal left and right tangents the same.
maxAngle: REAL _ JaM.PopReal[state];
PotentialKnots.NearlyEqual[FitJaM.defaultFitState, maxAngle];
};

ForceCorners: PROC[state: JaM.State] = {  --minangle  => forces corners if internal angle is < minangle.
angle: REAL _ JaM.PopReal[state];
PotentialKnots.ForceCorners[FitJaM.defaultFitState, angle];
};

FindCorners: PROC[state: JaM.State] = {  --minK, forceKnots => corners using curvature.
force: BOOLEAN _ JaM.PopBool[state];
minK: REAL _ JaM.PopReal[state];
PotentialKnots.FindCorners[FitJaM.defaultFitState, minK, force];
};

FindInflections: PROC[state: JaM.State] = {  --flat, forceKnots => inflections within flat using curvature.
force: BOOLEAN _ JaM.PopBool[state];
flat: REAL _ JaM.PopReal[state];
PotentialKnots.FindInflections[FitJaM.defaultFitState, flat, force];
};

FindDeltaKs: PROC[state: JaM.State] = {  --minDK, forceKnots => joints at points of high curvature
force: BOOLEAN _ JaM.PopBool[state];
minDK: REAL _ JaM.PopReal[state];
PotentialKnots.FindDeltaKs[FitJaM.defaultFitState, minDK, force];
};

Init: FitJaM.InitProc = {
JaM.Register[state, "PK.find90",Find90];	-- minL, minFlat, forceKnots => IF two flat lines of minL meet at a corner, mark it.  Assume flat lines are horizontal or vertical (only cases that will in practice pass the flatness test for small values of minFlat)
JaM.Register[state, "PK.findCorners",FindCorners];	-- minK, forceKnots => corners using curvature
JaM.Register[state, "PK.findInflections",FindInflections];	-- flat, forceKnots => inflections within flat using curvature
JaM.Register[state, "PK.findDeltaKs",FindDeltaKs];	-- minDK, forceKnots => joints at points of high curvature
JaM.Register[state, "PK.dynpoly",DynPoly];	-- penalty lineLength maxAngle => . Finds nodes using DynFit.  IF two adjacent lines are each longer than lineLength AND the turning angle is >= maxAngle THEN force a corner at the intersection
JaM.Register[state, "PK.quickpoly",QuickPoly];	-- finds a polygon fit
JaM.Register[state, "PK.cubictangents",CubicTangents];	-- err maxit => . Sets tangents at nodes by fitting between neighboring nodes.
JaM.Register[state, "PK.quicktangents",QuickTangents];	-- maxangle setCorners => . computes tangents by differencing neighbors. setCorners=TRUE sets one-sided tangents on corners
JaM.Register[state, "PK.squaretangents",SquareTangents];	-- maxangle setCorners => . computes tangents, weighting the longer edges more.  setCorners=TRUE sets one-sided tangents on corners
JaM.Register[state, "PK.circletangents",CircleTangents];	-- maxangle => . computes tangents, using circle through three adjacent joints. if angle > maxangle then leave tangents free
JaM.Register[state, "PK.hvextremes",HVExtremes];	-- forceknots => Puts potential knots on xy extremes
JaM.Register[state, "PK.hvlines",HVLines];	-- long maxangle forceknots => Puts potential knots around long horizontal and vertical lines.  maxangle is the tolerance for the decision
JaM.Register[state, "PK.hvtangents",HVTangents];	-- maxangle forceknots => sets nearly horizontal and vertical tangents to horizontal and vertical.
JaM.Register[state, "PK.nearlyequal",NearlyEqual];	-- maxangle => sets nearly equal left and right tangents the same.
JaM.Register[state, "PK.forcecorners",ForceCorners];	-- minangle => forces corners if internal angle between two tangents is < minangle
};

FitJaM.RegisterInit[id: $PotentialKnotsJaM, proc: Init];
}.
���l��PotentialKnotsJaM.mesa
JaM interfaces for PotentialKnots
Maureen Stone May 31, 1985 2:46:45 pm PDT  
�ÊI��˜�Jšœ™Jšœ!™!Jšœ+™+šÏk	˜	Jšœœ
˜Jšœœ˜Jšœœ˜$J˜Jšœœ+˜7Jšœ
œ ˜/J˜—šœœ˜ Jšœ+˜2J˜�—JšœœÏcÏiž˜WJšž>˜>šÏnœœ˜$Jšœ
œ˜$Jšœœ˜&Jšœ	œ˜#Jšœjžœ˜tJ˜J˜�—š 	œœž˜CJšœN˜NJ˜J˜�—Jšœœ˜3š 
œœžc˜Œšœ'˜'Jšœ'˜'Jšœ˜J˜—Jšœ#˜#Jšœ$˜$JšœLž˜hJšœ˜J˜J˜�—š 
œœžs˜œJšœœ˜&Jšœ
œ˜$JšœK˜KJ˜—š œœžz˜¤Jšœœ˜&Jšœ
œ˜$JšœL˜LJ˜—š œœžz˜¤Jšœ
œ˜$Jšœ@˜@J˜—š 
œœž%˜MJšœF˜FJ˜—š œœž4˜XJšœœ˜&Jšœ	œ˜#Jšœœ˜ JšœT˜TJ˜J˜�—š œœž4˜YJšœœ˜&Jšœ
œ˜$Jšœœ˜ JšœV˜VJ˜J˜�—š 
œœž0˜XJšœœ˜&Jšœ
œ˜$JšœH˜HJ˜J˜�—š œœžB˜kJšœ
œ˜$Jšœ=˜=J˜J˜�—š œœž>˜hJšœœ˜!Jšœ;˜;J˜J˜�—š œœž.˜WJšœœ˜$Jšœœ˜ Jšœ@˜@J˜J˜�—š œœž>˜kJšœœ˜$Jšœœ˜ JšœD˜DJ˜J˜�—š œœž9˜bJšœœ˜$Jšœœ˜!JšœA˜AJ˜J˜�—š œ˜Jšœ)žØ˜Jšœ3ž.˜aJšœ;ž>˜yJšœ3ž:˜mJšœ+ž‘œž(˜ìJšœ/ž˜EJšœ7žN˜…Jšœ7ž{˜²Jšœ9žƒ˜¼Jšœ9ž|˜µJšœ1ž4˜eJšœ+žŠ˜µJšœ1žb˜“Jšœ3žB˜uJšœ5žR˜‡J˜J˜�—J˜8J˜—�…—����^����