jumpmove.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 

class JUMP_MOVE

class JUMP_MOVE is -- Knot type is not change. -- 1998/4 Linux version K.Kodama -- -- 1991 MS-DOS version Kouji KODAMA shared SW0:BOOL:=true; -- SW0:default mode. TRUE:over jump, FALSE:under jump shared SW:BOOL; -- true:over jump, false:under jump. Use SW0 as default mode ----------------state variables-------------------- shared phase:CARD:=0; -- 0: needed setup -- 1: set start pt -- left: set start pt. "p1" & goto phase 2 -- right: none -- 2: set end pt -- left: set end pt. "p2" & goto phase 3 -- right: cancel start pt. goto phase 1 -- 3: set new bridge -- left: set new vertex & move vertex -- right: do jump move & goto phase 1 shared knotPtr,knotPtr1:INT; shared press3:BOOL; shared x0,y0:INT; shared pressL:BOOL; shared i0:INT; shared p1, p2, stp, enp:INT; shared KnotP0, KnotP1: KNOT; lMouse(inout Knot:KNOT, inout p, inout ps:INT, sw:INT) is -- p: stump of the segment (set by left button), -- ps: if point is inserted and p<ps then ps must be shifted. if sw=1.int then if (stp<p)and(p<enp) then Knot.PointInEdge(p); end; p:=p+1; if p<=ps then ps:=ps+1; end; enp:=enp+1; end; end; chOv(Knot:KNOT, inout seg1:BOOL, inout seg2:BOOL) is -- Check if over bridge seg1:=true; loop i::=p1.upto!(p2); seg1:=seg1 and (~VERTEXC::under.in(Knot[i].sep)); end; if (VERTEXC::ks.in(Knot[stp].sep))and(Knot.Match(stp+1,enp-1)) then seg2:=true; loop i::=(stp+1).upto!(p1); seg2:=seg2 and (~VERTEXC::under.in(Knot[i].sep)); end; loop i::=p2.upto!(enp-1); seg2:=seg2 and (~VERTEXC::under.in(Knot[i].sep)); end; else seg2:=false; end; end; CheckSegment(inout Knot:KNOT):BOOL is -- Check if the segment p1--p2 be over/under bridge. -- and rotate kFlg1o, kFlg2o, kFlg1u, kFlg2u:BOOL; c:INT; chOv(Knot,inout kFlg1o, inout kFlg2o); Knot.mirrorZ; chOv(Knot,inout kFlg1u,inout kFlg2u); Knot.mirrorZ; if ~(kFlg1o or kFlg2o or kFlg1u or kFlg2u) then return false; end; if (kFlg1o or kFlg2o)and(kFlg1u or kFlg2u) then SW:=SW0; -- Use default mode else SW:= (kFlg1o or kFlg2o); end; if (kFlg1o and SW) or (kFlg1u and (~ SW)) then return ~Knot.has_band(p1+1,p2-1); elsif (kFlg2o and SW) or (kFlg2u and (~ SW)) then --loop while!((stp+1)<p1); -- Knot.rotBack1(stp, enp); p1:=p1-1; p2:=p2-1; --end; --p1:=p2; p2:=enp-1; Knot.rotComponent(stp,enp,p1); p1:=stp+1+p2-p1; p2:=enp-1; -- return ~Knot.has_band(p1+1,p2-1); end; end; trimCrosses(inout Knot:KNOT) is -- delete bands on the bridge i0:=p1+1; loop while!(i0<p2); if VERTEXC::band.in(Knot[i0].sep) then Knot.BandDel(i0); end; i0:=i0+1; end; -- delete crossings on the bridge i0:=p1+1; loop while!(i0<p2); if VERTEXC::crossing.in(Knot[i0].sep) then -- i:=cmpOf(i0); -- if 0<=i then CodeDel(i); if i<i0 then DEC(i0); end; -- if (i<p2) then DEC(p2); end; if (i<p1) then DEC(p1); end; -- end; Knot.CodeDel(i0.card); if (i0<p2) then p2:=p2-1; end; if (i0<p1) then p1:=p1-1; end; else i0:=i0+1; end; end; i0:=0.int; loop until!( VERTEXC::code_e=Knot[i0].sep ); -- Del crossings if not exist cmp. if VERTEXC::crossing.in(Knot[i0].sep) and (Knot.cmpOf(i0).is_neg) then Knot.CodeDel(i0.card); if (i0<p2) then p2:=p2-1; end; if (i0<p1) then p1:=p1-1; end; else i0:=i0+1; end; end; end; LenMatch(inout Knot:KNOT, inout q0, inout q1:INT) is -- match q1 to q0 i0:INT:=q1-1; loop while!( q0>q1 ); if (stp<i0)and(i0<enp) then Knot.PointInEdge(i0); end; i0:=i0-1; q1:=q1+1; if i0<p1 then i0:=q1-1; end; end; end; Animate(p20,p21:INT) is --Move from KontP0 to KnotP1(=KnotP2). t, t1, sl, i, j, s, d:INT; KnotW:KNOT; -- DRAWKNOT_ALG::ResetPage(KnotP1); LenMatch(inout KnotP1,inout p20,inout p21); if ~ SW then KnotP1.mirrorZ; end; DRAWKNOT_ALG::ResetPage(KnotP0); LenMatch(inout KnotP0,inout p21,inout p20); if ~ SW then KnotP0.mirrorZ; end; s:=0; loop j:=(p1+1).upto!(p20-1); d:=KnotP1[j].distance1(KnotP0[j]); if s<d then s:=d; end; end; s:=(s/8)+1; sl:=s; loop i:=1.int.upto!(s-1); KnotW:=KnotP0.clone; t:=i; t1:=sl-t; -- 0<=t<=1, scaled s loop j:=(p1+1).upto!(p20-1); KnotW[j]:=(KnotP0[j]*t1+KnotP1[j]*t).div(sl); end; KnotW.CrossSet(p1, p20); if ~ SW then KnotW.mirrorZ; end; DRAWKNOT_ALG::ResetPage(KnotW); end; end; SetPhase1(Knot:KNOT) is if phase.is_zero then KnotP0:=#; KnotP1:=#; end; HISTORY::put(Knot); stp:=0.int; enp:=Knot.length.int; p1:=-1; p2:=-1; phase:=1; DRAWKNOT_ALG::ResetPage(Knot); end; SetPhase0(inout Knot:KNOT) is if phase.is_zero.not then HISTORY::back(inout Knot); KnotP0:=#; KnotP1:=#; end; phase:=0; DRAWKNOT_ALG::ResetPage(Knot); end; IfNear(inout Knot:KNOT, i0:INT) is -- check if i0 have near points, and shrink/splice it. c.f. MoveVertex d,j:INT; if (i0.is_neg) or (Knot.length.int<i0) then return; end; Knot.nearVertexV(i0,i0,out j,out d); if d>=DRAW_ALG::near then return; end; -- shrink knot if j=(i0+1) then Knot.DelV(i0); p2:=p2-1; elsif j=(i0-1) then Knot.DelV(i0); p2:=p2-1; end; end; shared p20,p21:INT; JumpMove(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is d,sw,pt:INT; if event=-1 then SetPhase1(Knot); return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); SetPhase0(inout Knot); return; end; if phase=0 then SetPhase1(Knot); end; case phase when 1 then -- Set p1 of segment p1--p2 case event when KNOTX::knotMotionNotify then Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); DRAW_ALG::nearMark(Knot,pt,d,sw); when KNOTX::knotButtonPress then ; when KNOTX::knotButtonRelease then Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); DRAW_ALG::nearMark(Knot,pt,DRAW_ALG::far,sw); if (button=KNOTX::knotButtonL)and(d<DRAW_ALG::near) then p1:=pt; p2:=-1; lMouse(inout Knot,inout p1,inout p2,sw); stp:=Knot.endOfString(p1,-1);enp:=Knot.endOfString(p1,1.int); DRAWKNOT_ALG::ResetPage(Knot); KNOTXW::DrawCircle(Knot[p1].x, -Knot[p1].y, 7.int, KNOTX::kStr,false); phase:=2; else SetPhase0(inout Knot); SetPhase1(Knot); end; end; when 2 then -- Set p2 of segment p1--p2 case event when KNOTX::knotMotionNotify then Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); if ~((stp<pt)and(pt<enp))then d:=DRAW_ALG::far; end; DRAW_ALG::nearMark(Knot,pt,d,sw); KNOTXW::DrawCircle(Knot[p1].x,-Knot[p1].y,7.int,KNOTX::kStr,false); when KNOTX::knotButtonPress then ; when KNOTX::knotButtonRelease then Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); DRAW_ALG::nearMark(Knot,pt,DRAW_ALG::far,sw); if (button=KNOTX::knotButtonL)and(d<DRAW_ALG::near) then p2:=pt; lMouse(inout Knot,inout p2,inout p1,sw); if p1=p2 then SetPhase0(inout Knot); SetPhase1(Knot); return; end; if p1>p2 then i0:=p1; p1:=p2; p2:=i0; end; if CheckSegment(inout Knot) then phase:=3; else SetPhase0(inout Knot); SetPhase1(Knot); return; end; -- Delete crossings on the segment trimCrosses(inout Knot); KnotP0:=Knot.clone; -- save original p20:=p2; -- KnotP0 with segment p1--p20 is origin work. -- del old segment i0:=p1+1; loop while!(i0<p2); Knot.CodeDel(i0.card); p2:=p2-1; end; DRAWKNOT_ALG::ResetPage(Knot); -- OpenMessage("Jump move"); KNOTXW::DrawCircle( Knot[p1].x,-Knot[p1].y, 7.int, KNOTX::kMark, false); KNOTXW::DrawCircle(Knot[p2].x, -Knot[p2].y, 7.int, KNOTX::kMark, false); phase:=3; pressL:=false; elsif button=KNOTX::knotButtonR then SetPhase0(inout Knot); SetPhase1(Knot); end; end; when 3 then --move segment p1--p2 case event when KNOTX::knotMotionNotify then if pressL then Knot[knotPtr].x:=mouseX; Knot[knotPtr].y:=-mouseY; KNOTXW::WindowSw(0.int); DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; f_sw::=KNOTXW::FlushPixel; KNOTXW::WindowSw(1.int); KNOTXW::DrawCircle(Knot[p1].x, -Knot[p1].y, 7.int, KNOTX::kMark,false); KNOTXW::DrawCircle(Knot[p2].x, -Knot[p2].y, 7.int, KNOTX::kMark, false); else i:INT; Knot.miniPt(mouseX,mouseY,out i,out d,out sw); if (i<p1)or(p2<=i)or((i=p1)and(sw.is_zero))then d:=DRAW_ALG::far; end; DRAW_ALG::nearMark(Knot,i,d,sw); end; when KNOTX::knotButtonPress then if button=KNOTX::knotButtonL then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); Knot.miniPt(mouseX,mouseY,out i0,out d,out sw); if (i0<p1)or(p2<=i0)or((i0=p1)and(sw.is_zero))then return; end; if d>=DRAW_ALG::near then return; end; if sw=1.int then i0:=i0+1; Knot.CodeIn(mouseX,-mouseY,i0.card); p2:=p2+1; end; knotPtr:=i0; pressL:=true; Knot[knotPtr].x:=mouseX; Knot[knotPtr].y:=-mouseY; end; DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; KNOTXW::DrawCircle(Knot[p1].x, -Knot[p1].y, 7.int, KNOTX::kMark,false); KNOTXW::DrawCircle(Knot[p2].x, -Knot[p2].y, 7.int, KNOTX::kMark, false); when KNOTX::knotButtonRelease then if button=KNOTX::knotButtonL then pressL:=false; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if DRAW_ALG::latticeFlg then Knot[knotPtr].x:= DRAW_ALG::trimL(Knot[knotPtr].x); Knot[knotPtr].y:= -DRAW_ALG::trimL(-Knot[knotPtr].y); end; IfNear(inout Knot,knotPtr); knotPtr:=-1; DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; KNOTXW::DrawCircle(Knot[p1].x, -Knot[p1].y, 7.int, KNOTX::kMark,false); KNOTXW::DrawCircle(Knot[p2].x, -Knot[p2].y, 7.int, KNOTX::kMark, false); elsif button=KNOTX::knotButtonR then -- KnotP0 is original. -- KnotP1 with segment p1--p21 is new KnotP1:=Knot.clone; p21:=p2; Animate(p20,p21); if ~ SW then Knot.mirrorZ; end; Knot.CrossSet(p1, p2); if ~ SW then Knot.mirrorZ; end; DRAWKNOT_ALG::ResetPage(Knot); SetPhase1(Knot); end; end; end; end; end;