PotentialKnotsJaM.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Maureen Stone May 31, 1985 2:46:45 pm PDT
Doug Wyatt, September 5, 1985 3:36:28 pm PDT
JaM interfaces for PotentialKnots
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];
}.