DIRECTORY Cubic, Complex, FitState, SafeStorage USING [ReclaimCollectibleObjects], JaM, FitJaM, FitBasic, FitStateUtils, FitIO, Real, Rope, Seq, Vector; FitEditJaM: CEDAR PROGRAM IMPORTS Complex, JaM, Real, Vector, FitState, FitJaM, FitIO, FitStateUtils, SafeStorage = { State: TYPE = JaM.State; GetVec: PROC [state: JaM.State] RETURNS [z:Complex.VEC] = { z.y _ JaM.PopReal[state]; z.x _ JaM.PopReal[state]; }; ResetSa: PROC[state: State] = {FitState.ResetData[FitJaM.defaultFitState, samples, FALSE]}; ResetAllSa: PROC[state: State] = {FitState.ResetData[FitJaM.defaultFitState, samples, TRUE]}; AddSa: PROC[state: State] = { y: REAL _ JaM.PopReal[state]; x: REAL _ JaM.PopReal[state]; FitState.AddSample[FitJaM.defaultFitState, x,y]; }; CountSa: PROC[state: State] = { n: INT _ 0; count: FitStateUtils.SampleProc = {n _ n+1}; FitStateUtils.ForAllSamples[FitJaM.defaultFitState.slist,count]; JaM.PushInt[state,n]; }; SelectSa: PROC [state: JaM.State] = { closest: FitBasic.SampleHandle; z: Complex.VEC; z.y _ JaM.PopReal[state]; z.x _ JaM.PopReal[state]; [closest,] _ FindSa[z]; IF closest#NIL THEN FitJaM.defaultFitState.slist.selectedSample _ closest; }; TheSa: PROC [state: JaM.State] = { JaM.PushReal[state,FitJaM.defaultFitState.slist.selectedSample.xy.x]; JaM.PushReal[state,FitJaM.defaultFitState.slist.selectedSample.xy.y]; }; FindSa: PROC [z: Complex.VEC] RETURNS[found: FitBasic.SampleHandle, index: NAT] = { closest,d: REAL _ 10.0E+30; i: NAT _ 0; do: FitStateUtils.SampleProc = { p: Complex.VEC _ FitIO.MagnifyPoint[FitJaM.defaultFitIO, s.xy]; IF ABS[p.x-z.x] none, 1 => potential, 2 => forced, ENDCASE => none; }; TanIn: PROC [state: JaM.State] = { FitJaM.defaultFitState.slist.selectedSample.tanIn _ GetVec[state]}; TanOut: PROC [state: JaM.State] = { FitJaM.defaultFitState.slist.selectedSample.tanOut _ GetVec[state]}; ForceJoint: PROC [state: JaM.State] = {OPEN FitJaM.defaultFitState; IF slist.selectedSample.jointType#none THEN slist.selectedSample.jointType _ IF JaM.PopBool[state] THEN forced ELSE potential; }; Closed: PROC [state: JaM.State] = { FitJaM.defaultFitState.closed _ JaM.PopBool[state]}; HomeSa: PROC [state: JaM.State] = {OPEN FitJaM.defaultFitState; slist.selectedSample _ slist.header; }; MakeFirstSa: PROC [state: JaM.State] = {OPEN FitJaM.defaultFitState; IF slist.selectedSample # NIL THEN { slist.first _ slist.selectedSample; slist.last _ slist.first.prev; IF slist.last=slist.header THEN slist.last _ slist.last.prev; }; }; NextSa: PROC [state: JaM.State] = {OPEN FitJaM.defaultFitState; slist.selectedSample _ slist.selectedSample.next; IF slist.selectedSample = slist.header THEN slist.selectedSample _ slist.selectedSample.next }; PrevSa: PROC [state: JaM.State] = {OPEN FitJaM.defaultFitState; slist.selectedSample _ slist.selectedSample.prev; IF slist.selectedSample = slist.header THEN slist.selectedSample _ slist.selectedSample.prev }; ScaleSa: PROC [state: JaM.State] = { FitState.ScaleData[FitJaM.defaultFitState,JaM.PopReal[state], samples]; }; TranSa: PROC [state: JaM.State] = { z: Complex.VEC _ GetVec[state]; FitState.TranslateData[FitJaM.defaultFitState, z, samples]; }; InterpolateSa: PROC[state: State] = { OPEN FitJaM.defaultFitState; mindelta: REAL _ MAX[JaM.PopReal[state], 0.00001]; selected: FitBasic.SampleHandle _ slist.selectedSample; first: BOOLEAN _ TRUE; from: FitBasic.SampleHandle _ slist.header.next; do: FitStateUtils.SampleProc = { IF first THEN {from _ s; first _ FALSE} ELSE { to: FitBasic.SampleHandle _ s; delta: Complex.VEC _ Complex.Sub[to.xy, from.xy]; k: REAL _ Real.RoundLI[Complex.Abs[delta]/mindelta]; slist.selectedSample _ to; FOR i: REAL _ 1, i+1 UNTIL i>k DO v: Complex.VEC _ Complex.Add[s.xy, Vector.Mul[delta, i/(k+1)]]; FitState.InsertBeforeSample[FitJaM.defaultFitState, v.x,v.y]; ENDLOOP; from _ to; }; }; FitStateUtils.ForAllSamples[slist, do]; IF closed THEN [] _ do[slist.header.next]; slist.selectedSample _ selected; }; Subrange: PROC [state: JaM.State] = {OPEN FitJaM.defaultFitState; first,last: FitBasic.SampleHandle; p0,p1: Complex.VEC; i0,i1: NAT; p1.y _ JaM.PopReal[state]; p1.x _ JaM.PopReal[state]; [last,i1] _ FindSa[p1]; p0.y _ JaM.PopReal[state]; p0.x _ JaM.PopReal[state]; [first,i0] _ FindSa[p0]; IF i0 IF type=1 THEN {s.tanIn _ s.tanOut _ [0,0]}; forced => IF type=2 THEN {s.tanIn _ s.tanOut _ [0,0]}; ENDCASE => IF type=0 THEN {s.tanIn _ s.tanOut _ [0,0]} }; FitStateUtils.ForAllSamples[FitJaM.defaultFitState.slist, reset]; }; ForAllLinks: PROC[state: State] = { body: JaM.Any _ JaM.Pop[state]; do: FitStateUtils.LinkProc = { JaM.PushReal[state,l.cubic.b0.x]; JaM.PushReal[state,l.cubic.b0.y]; JaM.PushReal[state,l.cubic.b1.x]; JaM.PushReal[state,l.cubic.b1.y]; JaM.PushReal[state,l.cubic.b2.x]; JaM.PushReal[state,l.cubic.b2.y]; JaM.PushReal[state,l.cubic.b3.x]; JaM.PushReal[state,l.cubic.b3.y]; JaM.Execute[state, body ! JaM.Stop => CONTINUE]; }; FitStateUtils.ForAllLinks[FitJaM.defaultFitState.traj,do]; }; ResetCon: PROC[state: State] = {FitState.ResetData[FitJaM.defaultFitState, contours, FALSE]}; ResetAllCon: PROC[state: State] = {FitState.ResetData[FitJaM.defaultFitState, contours, TRUE]}; CountCon: PROC[state: State] = { JaM.PushInt[state, FitState.CountContours[FitJaM.defaultFitState]]}; AddCon: PROC[state: State] = {FitState.NewContour[FitJaM.defaultFitState]}; NextCon: PROC[state: State] = {FitState.NextContour[FitJaM.defaultFitState]}; SetSLen: PROC[state: State] = {FitState.SetMinDist[FitJaM.defaultFitState,JaM.PopReal[state]]}; CollectGarbage: PROC[state: State] = { SafeStorage.ReclaimCollectibleObjects[suspendMe: TRUE, traceAndSweep: TRUE]; }; Init: FitJaM.InitProc = { JaM.Register[state,".resetsa", ResetSa]; JaM.Register[state,".resetallsa", ResetAllSa]; JaM.Register[state,".addsa", AddSa]; JaM.Register[state,".countsa", CountSa]; JaM.Register[state,".selectsa", SelectSa]; -- x y => . Selects a sample point for editing JaM.Register[state,".interpolatesa", InterpolateSa]; -- d => . Interpolates samples to make deltas no larger than about d JaM.Register[state,".thesa", TheSa]; -- => x y . Returns the current sample JaM.Register[state,".thetanin", TheTanIn]; -- => x y boolean . Returns the tanIn of the current sample, and whether it is a node JaM.Register[state,".thetanout", TheTanOut]; -- => x y boolean . Returns the tanOut of the current sample, and whether it is a node JaM.Register[state,".deletesa", DeleteSa]; -- => . Deletes the current sample JaM.Register[state,".insertsa", InsertSa]; -- x y => . Inserts before the current sample JaM.Register[state,".insertbetween", InsertBetween]; -- x y => . Inserts between the current sample and the neighbor nearest the new point JaM.Register[state,".jointsa", JointSa]; -- type => . sets joint type: 0 (.false) = none, 1 (.true) = potential, 2 = forced JaM.Register[state,".tanIn", TanIn]; -- deltax deltay => . Sets the tanIn at selected sample JaM.Register[state,".tanOut", TanOut]; -- deltax deltay => . Sets the tanIn at selected sample JaM.Register[state,".forcejoint", ForceJoint]; -- boolean => . flips between potential and forced JaM.Register[state,".closed", Closed]; -- boolean => . Sets the closed bit on the samples JaM.Register[state,".homesa", HomeSa]; -- => . Selects the header JaM.Register[state,".makefirstsa", MakeFirstSa]; -- => . Selects the header JaM.Register[state,".nextsa", NextSa]; -- => x y . Moves selection to the next sample JaM.Register[state,".prevsa", PrevSa]; -- => x y . Moves selection to the previous sample JaM.Register[state,".scalesa", ScaleSa]; -- x y => . Scales/rotates all samples by multiplying by x+iy JaM.Register[state,".transa", TranSa]; -- x y => . Translates all samples by adding x+iy JaM.Register[state,".subrange", Subrange]; -- change CurrentSamples so it returns a subrange JaM.Register[state,".allsa", NoSubrange]; -- remove the subrange JaM.Register[state,".resetjoints", ResetJoints]; -- remove the nodes JaM.Register[state,".resetforcedjoints", ResetForcedJoints]; -- remove the corners JaM.Register[state,".resettangents", ResetTangents]; -- type => remove the tangents type: 0 = all, 1 = potential only, 2 = forced only JaM.Register[state,".foralllinks", ForAllLinks]; JaM.Register[state,".nextcon", NextCon]; JaM.Register[state,".resetcon", ResetCon]; JaM.Register[state,".resetallcon", ResetAllCon]; JaM.Register[state,".addcon", AddCon]; JaM.Register[state,".countcon", CountCon]; JaM.Register[state,".setslen", SetSLen]; JaM.Register[state,".collectgarbage", CollectGarbage]; }; FitJaM.RegisterInit[$FitEditJaM, Init]; }. `FitEditJaM.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by Maureen Stone July 3, 1984 11:33:19 am PDT Last Edited by Michael Plass December 7, 1982 10:25 am Last Edited by: Stone, December 13, 1984 3:40:14 pm PST Doug Wyatt, September 5, 1985 3:34:55 pm PDT The point and link editing JaM commands Display commands are in FitIOJaM Sample Editing Commands ScaleSa: PROC [state: JaM.State] = { z: Complex.VEC _ GetVec[state]; FOR s: FitBasic.SampleHandle _ slist.header.next, s.next UNTIL s=slist.header DO p:Complex.VEC _ s.xy; s.xy _ Complex.Mul[p,z]; p _ s.tangent; s.tangent _ Complex.Mul[p,z]; ENDLOOP; }; JaM.Register[state,".cornersa", CornerSa]; -- => . moves the selected sample so it is colinear with its two left neightbors and with its two right neighbors CornerSa: PROC = {OPEN Vector; samp: SampleHandle _ IF FitJaM.defaultFitState.slist.selectedSample = IF FitJaM.defaultFitState.slist.header THEN FitJaM.defaultFitState.slist.selectedSample.next ELSE FitJaM.defaultFitState.slist.selectedSample; p: SampleHandle _ IF samp.prev = FitJaM.defaultFitState.slist.header THEN samp.prev.prev ELSE samp.prev; pp: SampleHandle _ IF p.prev = FitJaM.defaultFitState.slist.header THEN p.prev.prev ELSE p.prev; n: SampleHandle _ IF samp.next = FitJaM.defaultFitState.slist.header THEN samp.next.next ELSE samp.next; nn: SampleHandle _ IF n.next = FitJaM.defaultFitState.slist.header THEN n.next.next ELSE n.next; a: VEC _ pp.xy; b: VEC _ p.xy; c: VEC _ nn.xy; d: VEC _ n.xy; coeffMat: Matrix _ [a.y-b.y, b.x-a.x, c.y-d.y, d.x-c.x]; r: VEC _ [Det[[b.x, b.y, a.x, a.y]], Det[[d.x, d.y, c.x, c.y]]]; denom: REAL _ Det[coeffMat]; xTimesDenom: REAL _ Det[[r.x, coeffMat.a12, r.y, coeffMat.a22]]; yTimesDenom: REAL _ Det[[coeffMat.a11, r.x, coeffMat.a21, r.y]]; IF denom=0 THEN RETURN; samp.xy.x _ xTimesDenom/denom; samp.xy.y _ yTimesDenom/denom; }; Κ ˜codešœ™Kšœ Οmœ1™˜Ršžœ˜K˜_Kšœ>˜>K˜3K˜—K˜K˜—š œžœžœ˜@Kšœ!žœžœ)žœ ˜wK˜K˜—š œžœ˜"KšœC˜C—K˜š œžœ˜#KšœD˜D—K˜š  œžœžœ˜Cšžœ%ž˜+Kšœ!žœžœžœ ˜RKšœ˜——š œžœ˜#Kšœ4˜4—š œžœžœ˜?Kšœ$˜$Kšœ˜—š  œžœžœ˜Dšžœžœžœ˜$Kšœ#˜#Kšœ˜Kšžœžœ˜=K˜—K˜K˜—š œžœžœ˜?K˜1Kšžœ%žœ1˜\K˜K˜—š œžœžœ˜?K˜1Kšžœ%žœ1˜\K˜K˜—š œžœ˜$K˜GK˜—š œžœ˜#Kšœ žœ˜K˜;K˜K˜—š  œžœžœ˜BKšœ žœžœ˜2K˜7Kšœžœžœ˜K˜0˜ Kšžœžœžœ˜'šžœ˜K˜Kšœžœ˜1Kšœžœ-˜4K˜šžœžœ žœž˜!Kšœ žœ1˜?K˜=Kšžœ˜ —K˜ Kšœ˜—K˜—K˜'Kšžœžœ˜*K˜ K˜K˜—K˜š œžœžœ˜AK˜"Kšœžœ˜Kšœžœ˜ K˜K˜K˜K˜K˜K˜Kšžœžœ*žœ*˜eK˜—Kš  œžœžœ4žœ˜dKš  œžœK˜\š œžœ˜.Kšœ#žœžœ˜WKšœA˜AKšœ˜—K˜š  œžœ˜*Kšœžœ˜šœ#˜#šžœ ž˜Kšœ žœžœ˜9Kšœ žœžœ˜6Kšžœžœžœ˜6—Kšœ˜—KšœA˜AKšœ˜—š  œžœ˜#K˜šœ˜K˜!K˜!K˜!K˜!K˜!K˜!K˜!K˜!Kšœ&žœ˜0Kšœ˜—K˜:K˜K˜—Kš œžœGžœ˜]Kš  œžœGžœ˜_š œžœ˜ KšœD˜D—Kš œžœ?˜KKš œžœ@˜MK˜Kš œžœR˜_š œžœ˜&Kšœ1žœžœ˜LK˜K˜—K˜˜Kšœ™Kšœ(˜(Kšœ.˜.Kšœ$˜$Kšœ(˜(Kšœ+Οc.˜YKšœ5‘D˜yKšœ%‘&˜KKšœ+‘U˜€Kšœ-‘V˜ƒKšœ+‘#˜NKšœ+‘-˜XKšœ5‘U˜ŠKšœ)‘T˜}Kšœ%‘7˜\Kšœ'‘7˜^Kšœ/‘2˜aKšœ'‘2˜YKšœ'‘˜AKšœ1‘˜KKšœ'‘.˜UKšœ'‘2˜YKšœ)‘>˜gKšœ'‘2˜YKšœ+‘1˜\Kšœ*‘˜@Kšœ1‘˜DKšœ=‘˜RKšœ5‘S˜ˆK˜0K˜(K˜*K˜0K˜&K˜*K˜(Kšœ6˜6K˜—K˜'K˜š œžœ™$Kšœ žœ™šžœ6žœž™PKšœ žœ™K™K™K™Kšžœ™—K™—Kšœ+‘q™œš œžœžœ™šœžœ.™EKšžœ%žœ1™\Kšžœ-™1—Kšœžœ1žœžœ ™hKšœžœ.žœ žœ™`Kšœžœ1žœžœ ™hKšœžœ.žœ žœ™`Kšœžœ ™Kšœžœ™Kšœžœ ™Kšœžœ™K™8Kšœžœ:™@Kšœžœ™Kšœ žœ/™@Kšœ žœ/™@Kšžœ žœžœ™K™K™K™K™—K˜—…—* ;s