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]; }. lPotentialKnotsJaM.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˜—…—^