FitPointEditJaM.mesa
The point editing part of the old FitStateImpl
Last Edited by Stone June 4, 1984 10:00:28 am PDT
Last Edited by Michael Plass December 7, 1982 10:25 am
Last Edited by: Stone, November 21, 1983 11:33 am
DIRECTORY
Cubic,
Complex,
FitState USING [defaultHandle],
JaM,
FitJaM,
FitBasic,
Real,
Rope,
Seq,
Vector;
FitPointEditJaM: CEDAR PROGRAM
IMPORTS Complex, JaM, Real, Rope, Vector, FitState, FitJaM = {
GetVec: PROC [state: JaM.State] RETURNS [z:Complex.Vec] = {
z.y ← JaM.PopReal[state];
z.x ← JaM.PopReal[state];
};
SelectSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
closest: FitBasic.SampleHandle;
z: Complex.Vec;
z.y ← JaM.PopReal[state];
z.x ← JaM.PopReal[state];
[closest,] ← FindSa[z];
IF closest#NIL THEN slist.selectedSample ← closest;
};
TheSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
JaM.PushReal[state,slist.selectedSample.xy.x];
JaM.PushReal[state,slist.selectedSample.xy.y];
};
FindSa: PROC [z: Complex.Vec] RETURNS[found: FitBasic.SampleHandle, index: NAT] = {OPEN FitState.defaultHandle^;
closest,d: REAL ← 10.0E+30;
i: NAT ← 0;
found ← NIL;
FOR s: FitBasic.SampleHandle ← slist.header.next, s.next UNTIL s=slist.header DO
p: Complex.Vec ← XForm[s.xy];
IF ABS[p.x-z.x]<closest AND ABS[p.y-z.y]<closest
AND (d ← Vector.Mag[Vector.Sub[z,p]]) < closest THEN
{closest ← d; found ← s; index ← i};
i ← i+1;
ENDLOOP;
};
TheTan: PROC [state: JaM.State] = {OPEN FitState.defaultHandle.slist.selectedSample;
JaM.PushReal[state,tangent.x];
JaM.PushReal[state,tangent.y];
JaM.PushBool[state,isNode]};
DeleteSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
IF slist.selectedSample # slist.header THEN {
p,q: FitBasic.SampleHandle;
p ← slist.selectedSample.prev;
q ← slist.selectedSample.next;
p.next ← q;
q.prev ← p;
slist.selectedSample ← q
};
};
InsertSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
x,y: REAL;
samp: FitBasic.SampleHandle ← slist.selectedSample;
y ← JaM.PopReal[state];
x ← JaM.PopReal[state];
InsertBefore[FitState.defaultHandle, x,y, slist.selectedSample];
};
InsertBetween: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
z: Complex.Vec;
insertBefore: BOOLEAN;
samp: FitBasic.SampleHandle ← slist.selectedSample;
z.y ← JaM.PopReal[state];
z.x ← JaM.PopReal[state];
insertBefore ←
(Vector.Mag[Vector.Sub[z, samp.prev.xy]] < Vector.Mag[Vector.Sub[z, samp.next.xy]]);
IF insertBefore THEN FitState.InsertBefore[FitState.defaultHandle, z.x, z.y, samp]
ELSE FitState.InsertBefore[FitState.defaultHandle, z.x, z.y, samp.next];
};
NodeSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
slist.selectedSample.isNode ← JaM.PopBool[state];
IF ~slist.selectedSample.isNode THEN slist.selectedSample.isCusp ← FALSE;
};
TanSa: PROC [state: JaM.State] = {
FitState.defaultHandle.slist.selectedSample.tangent ← GetVec[state]};
CuspSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
slist.selectedSample.isCusp ← slist.selectedSample.isNode ← JaM.PopBool[state];};
CuspNode: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
IF slist.selectedSample.isNode THEN slist.selectedSample.isCusp ← JaM.PopBool[state]};
TanOutSa: PROC [state: JaM.State] = {
FitState.defaultHandle.slist.selectedSample.tanOut ← GetVec[state]};
HomeSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
slist.selectedSample ← slist.header};
MakeFirstSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
IF slist.selectedSample # NIL AND slist.selectedSample # slist.header AND slist.selectedSample # slist.header.next THEN {
slist.header.next.prev ← slist.header.prev;
slist.header.prev.next ← slist.header.next;
slist.header.next ← slist.selectedSample;
slist.header.prev ← slist.selectedSample.prev;
slist.header.next.prev ← slist.header;
slist.header.prev.next ← slist.header}
};
NextSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
slist.selectedSample ← slist.selectedSample.next;
IF slist.selectedSample = slist.header THEN
slist.selectedSample ← slist.selectedSample.next
};
PrevSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
slist.selectedSample ← slist.selectedSample.prev;
IF slist.selectedSample = slist.header THEN
slist.selectedSample ← slist.selectedSample.prev
};
ScaleSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
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;
};
TranSa: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
z: Complex.Vec ← GetVec[state];
FOR s: FitBasic.SampleHandle ← slist.header.next, s.next UNTIL s=slist.header DO
s.xy ← Complex.Add[s.xy,z];
ENDLOOP;
};
Subrange: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^;
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<i1 THEN {slist.first ← first; slist.last ← last} ELSE {slist.first ← last; slist.last ← first};
};
NoSubrange: PROC [state: JaM.State] = {OPEN FitState.defaultHandle^; slist.first ← slist.last ← NIL};
ResetDefaultNodes: PROC [state: JaM.State] = {FitState.ResetNodes[FitState.defaultHandle]};
ResetDefaultCusps: PROC [state: JaM.State] = {FitState.ResetCusps[FitState.defaultHandle]};
Init: FitJaM.InitProc = {
Sample Editing Commands
JaM.Register[state,".selectsa", SelectSa]; -- x y => . Selects a sample point for editing
JaM.Register[state,".thesa", TheSa]; -- => x y . Returns the current sample
JaM.Register[state,".thetan", TheTan]; -- => x y boolean . Returns the tangent 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,".nodesa", NodeSa]; -- boolean => . Makes or unmakes a node
JaM.Register[state,".tansa", TanSa]; -- deltax deltay => . Sets the tangent at a sample
JaM.Register[state,".cuspsa", CuspSa]; -- boolean => . Makes or unmakes a cusp
JaM.Register[state,".cuspnode", CuspNode]; -- boolean => . Makes or unmakes a cusp ONLY on a node
JaM.Register[state,".tanoutsa", TanOutSa]; -- deltax deltay => . Sets the outgoing tangent
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,".resetnodes", ResetDefaultNodes]; -- remove the nodes
JaM.Register[state,".resetcusps", ResetDefaultCusps]; -- remove the cusps
};
FitJaM.RegisterInit[$FitPointEditJaM, Init];
}.