knotIO.sa


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

class KNOTIO_SAMPLE

class KNOTIO_SAMPLE is shared knotPtr,knotPtr1:INT; shared pressL:BOOL; shared x0,y0:INT; sample_skelton(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is if event=-1 then knotPtr:=-1; knotPtr1:=-1; pressL:=false; x0:=-1; y0:=-1; return; elsif event=-2 then knotPtr:=-1 ; pressL:=false; return; end; -- CHECK_KNOT_ALG::checkKnotD(Knot); case event when KNOTX::knotMotionNotify then ; -- "sample"; when KNOTX::knotButtonPress then ; when KNOTX::knotButtonRelease then ; end; end; end; -- class KNOTIO_SAMPLE

class KNOTIO

class KNOTIO is -- Copyright (C) 1983 1989 1996 Kouji KODAMA -- -- 1996/10 -- LINUX version -- -- 94/10/20 14:58:24 -- use smoothDraw. splice bug fix. -- -- 1992/11 -- change MoveVertexS to MoveVertex. -- -- 1992/5 -- Splice: Band surgery -- -- 1989/8 -- FTL-Modula2 version -- -- 1983 -- Basic -- Kouji KODAMA Cross(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is d:INT; i,j:INT; cod:VERTEXC; if event=-1 then Knot.CrossSet(0.int,Knot.length.int); return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); return; end; case event when KNOTX::knotMotionNotify then i:=Knot.miniCrossing(mouseX,mouseY,0.int,Knot.length.int,out d); DRAW_ALG::nearMark(Knot,i,d,0.int); when KNOTX::knotButtonPress then ; -- do nothing when KNOTX::knotButtonRelease then i:=Knot.miniCrossing(mouseX,mouseY,0.int,Knot.length.int,out d); if (button=KNOTX::knotButtonL)and(d<DRAW_ALG::near) then DRAW_ALG::nearMark(Knot,i,DRAW_ALG::far,0.int); -- SLength; j:=Knot.cmpOf(i); if j.is_pos then cod:=Knot[i].sep; Knot[i].sep:=Knot[j].sep; Knot[j].sep:=cod; end; DRAWKNOT_ALG::DrawKnot(Knot); end; end; end; DelString(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is pt,d,sw,i,j:INT; if event=-1 then return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); return; end; 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 if (sw=0.int)and VERTEXC::band.in(Knot[pt].sep) then pt:=Knot.cmpOf(pt); end; Knot.delStr(inout pt); Knot.ClCrossErr(inout pt); DRAWKNOT_ALG::DrawKnot(Knot); end; end; end; CutString(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is pt,d,sw,i,j,j1,stp,enp:INT; if event=-1 then return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); return; end; 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 if (sw=1.int) then pt:=pt+1; Knot.CodeIn(0.int,0.int,pt); end; Knot.ClCrossEdge(inout pt,1.int); Knot.ClCrossEdge(inout pt,-1); j:=pt; if VERTEXC::band.in(Knot[j].sep) then j1:=Knot.cmpOf(j); if Knot.tooShort(j1) then Knot.BandDel(j1); else Knot.ClCrossEdge(inout j1,1.int); Knot.CodeDel(j1); end; Knot[j].sep:=VERTEXC::normal; end; j:=Knot.nextPt(pt,1.int); if (j.is_non_neg)and(VERTEXC::band.in(Knot[j].sep)) then j1:=Knot.cmpOf(j); if Knot.tooShort(j1) then Knot.BandDel(j1); else Knot.ClCrossEdge(inout j1,1.int); Knot.CodeDel(j1); end; Knot[j].sep:=VERTEXC::normal; end; j:=Knot.nextPt(pt,-1); if (j.is_non_neg)and(VERTEXC::band.in(Knot[j].sep)) then j1:=Knot.cmpOf(j); if Knot.tooShort(j1) then Knot.BandDel(j1); else Knot.ClCrossEdge(inout j1,1.int); Knot.CodeDel(j1); end; Knot[j].sep:=VERTEXC::normal; end; stp:=Knot.endOfString(pt,-1)+1; enp:=Knot.endOfString(pt,1.int)-1; if Knot.cmpOf(stp)=enp then -- knot Knot.CodeDel(enp); enp:=enp-1; Knot.CodeSplice(pt,enp,stp,pt-1); Knot.CodeDel(stp); else -- string Knot.CodeDel(pt); Knot.CodeIn(0.int,0.int,pt); Knot.CodeIn(Knot[enp+1].sep,pt.card); enp:=enp+1; Knot[pt+1].sep:=Knot[stp-1].sep; stp:=pt+1; enp:=Knot.endOfString(stp,1.int); if stp+2>=enp then Knot.delStr(inout stp); end; enp:=pt; stp:=Knot.endOfString(enp,-1); if stp+2>=enp then Knot.delStr(inout stp); end; end; Knot.ClCrossErr(inout pt); DRAWKNOT_ALG::DrawKnot(Knot); end; end; end; InvertString(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is pt,d,sw,i,j:INT; if event=-1 then Knot.SLength; return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); return; end; 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 if (sw.is_zero)and VERTEXC::band.in( Knot[pt].sep) then pt:=Knot.cmpOf(pt); end; Knot.revK(pt); DRAWKNOT_ALG::DrawKnot(Knot); end; end; end; end; -- class KNOTIO

class ADD_COMPO

class ADD_COMPO is shared knotPtr:INT; shared pressL:BOOL; shared x0,y0:INT; shared modeAddCompo:INT:=0; EndOfCurrentSegment(inout Knot:KNOT) is --end of current segment DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if knotPtr.is_non_neg then if VERTEXC::ks.in(Knot[knotPtr].sep)or VERTEXC::ts.in(Knot[knotPtr].sep) then #OUT+"Bad code in knot data. \n"; KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); Knot.CodeDel(knotPtr.card); Knot.CodeDel(knotPtr.card); elsif VERTEXC::ks.in(Knot[knotPtr-1].sep) then --only 1-pt if false then -- convert knot to graph-vertex if knotPtr>2.int then Knot.CodeSplice(knotPtr-1,knotPtr+1,0.int,knotPtr-2); end; Knot[0].sep:=VERTEXC::graph_s; Knot[2].sep:=VERTEXC::graph_e; KNOTXW::DrawCircle(x0,y0,4.int,KNOTX::kMark,true); else -- delete it Knot.delStr(inout knotPtr); end; else KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y,x0,y0, KNOTX::kMark); end; knotPtr:=-1; end; DRAWKNOT_ALG::DrawKnot(Knot); end; AddCompo(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is i:INT; d,pt,p1,p2,p3,p4:INT; -- #OUT+" ptr"+knotPtr.str; -- #OUT+" ev"+event.str+" button"+button.str; -- #OUT+" mouseX"+mouseX.str+" mouseY"+mouseY.str+"\n"; if event=-1 then modeAddCompo:=1.int; knotPtr:=-1; pressL:=false; return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); modeAddCompo:=0.int; event:=KNOTX::knotButtonRelease; button:=KNOTX::knotButtonR; pressL:=false; EndOfCurrentSegment(inout Knot); x0:=mouseX; y0:=mouseY; return; end; if modeAddCompo.is_zero then modeAddCompo:=1.int; knotPtr:=-1; pressL:=false; end; if mouseX.is_neg then mouseX:=0.int; elsif mouseX>KNOTXW::GraphWidth then mouseX:=KNOTXW::GraphWidth; end; if mouseY.is_neg then mouseY:=0.int; elsif mouseY>KNOTXW::GraphHeight then mouseY:=KNOTXW::GraphHeight; end; case event when KNOTX::knotMotionNotify then if knotPtr.is_non_neg then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if VERTEXC::ks.in(Knot[knotPtr].sep)or VERTEXC::ts.in(Knot[knotPtr].sep) then KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); KNOTXW::DrawCircle(mouseX,mouseY,5.int,KNOTX::kMark,false); else KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, x0,y0, KNOTX::kMark); KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, mouseX, mouseY, KNOTX::kMark); end; x0:=mouseX; y0:=mouseY; else end; -- Show which end-point is nearest. Knot.nearStumpVertex(mouseX,mouseY,out pt,out d); if (pt=(knotPtr-1))or (pt=knotPtr) then d:=DRAW_ALG::far; end; DRAW_ALG::nearMark(Knot,pt,d,0.int); when KNOTX::knotButtonPress then case button when KNOTX::knotButtonR then if pressL then return; else ; end; when KNOTX::knotButtonC then if pressL then return; else ; end; when KNOTX::knotButtonL then if knotPtr.is_neg then -- start of segment Knot.SLength; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); Knot.nearStumpVertex(mouseX,mouseY,out pt,out d); if d<DRAW_ALG::near then if VERTEXC::ks.in(Knot[pt-1].sep) then Knot.revK(pt); end; knotPtr:=Knot.endOfString(pt,1.int)-1; x0:=Knot[knotPtr].x; y0:=-Knot[knotPtr].y; KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, x0,y0, KNOTX::kMark); else knotPtr:=0.int; loop if VERTEXC::ts.in(Knot[knotPtr].sep)or VERTEXC::endc.in( Knot[knotPtr].sep) then break!; end; knotPtr:=knotPtr+1; end; Knot.CodeIn(VERTEXC::knot_e,knotPtr.card); Knot.CodeIn(VERTEXC::knot_s,knotPtr.card); x0:=mouseX; y0:=mouseY; KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); end; pressL:=true; Knot.updateCross:=true; end; end; when KNOTX::knotButtonRelease then case button when KNOTX::knotButtonR then if pressL then return; else EndOfCurrentSegment(inout Knot); x0:=mouseX; y0:=mouseY; end; when KNOTX::knotButtonC then if pressL then return; end; when KNOTX::knotButtonL then pressL:=false; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if knotPtr.is_non_neg then -- set vertex Knot.nearStumpVertex(mouseX,mouseY,out pt,out d); if (d<DRAW_ALG::near)and ((pt=knotPtr)or((pt+1)=knotPtr)) then -- Do nothing. elsif (d<DRAW_ALG::near) then -- splice mouseX:=Knot[pt].x; mouseY:=-Knot[pt].y; if VERTEXC::ks.in(Knot[knotPtr].sep)or VERTEXC::ts.in( Knot[knotPtr].sep) then KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); Knot.CodeDel(knotPtr); Knot.CodeDel(knotPtr); else KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0, KNOTX::kMark); KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y, mouseX,mouseY,KNOTX::kStr); p1:=Knot.endOfString(knotPtr,-1); if (p1+1)=pt then -- close loop Knot.CodeIn(mouseX,-mouseY,knotPtr+1); -- safe even if failed here else -- splice strings if VERTEXC::ke.in(Knot[pt+1].sep) then Knot.revK(pt); end; Knot.StringSplice(knotPtr,pt); end; end; knotPtr:=-1; DRAWKNOT_ALG::DrawKnot(Knot); else if VERTEXC::ks.in(Knot[knotPtr].sep)or VERTEXC::ts.in(Knot[knotPtr].sep) then KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); x0:=mouseX; y0:=mouseY; Knot.CodeIn(x0,-y0,knotPtr+1); knotPtr:=knotPtr+1; -- DrawCircle(mouseX,mouseY,5,kStr,false); else KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0, KNOTX::kMark); x0:=mouseX; y0:=mouseY; Knot.CodeIn(x0,-y0,knotPtr+1); KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0,KNOTX::kStr); knotPtr:=knotPtr+1; end; -- KnotDraw; end; end; end; end; end; end; -- class ADD_COMPO

class MAKE_SADDLE

class MAKE_SADDLE is shared knotPtr,knotPtr1:INT; shared pressL:BOOL; shared x0,y0:INT; shared modeMakeSaddle:INT:=0; EndOfCurrentSegment(inout Knot:KNOT) is -- end of current segment pt,p1:INT; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if knotPtr.is_non_neg then if VERTEXC::ks.in( Knot[knotPtr].sep)or VERTEXC::ts.in( Knot[knotPtr].sep) then #OUT+"Bad code while MakeSaddle.\n"; KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); Knot.CodeDel(knotPtr); Knot.CodeDel(knotPtr); elsif VERTEXC::ts.in( Knot[knotPtr-1].sep) then --only 1-pt pt:=Knot.cmpOf(knotPtr-1); if (pt.is_pos)and(Knot.cmpOf(pt)=(knotPtr)) then Knot[pt].sep:=VERTEXC::normal; end; p1:=knotPtr+1; loop while!( p1>=knotPtr-1 ); Knot.CodeDel(p1); p1:=p1-1; end; else KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y,x0,y0, KNOTX::kMark); end; knotPtr:=-1; end; --SLength; -- loop i:=0 .upto!( length ); -- if band .in( Knot[i].sep then -- if cmpOf(i)<0 then Knot[i].sep:=VERTEXC{normal}; end; -- end; -- end; DRAWKNOT_ALG::DrawKnot(Knot); end; SetMode1(Knot:KNOT) is -- begin modeMakeSaddle:=1.int; knotPtr:=-1; knotPtr1:=-1; pressL:=false; knotPtr1:=0.int; loop if (knotPtr1>=Knot.length.int) or VERTEXC::ts.in(Knot[knotPtr1].sep) then break!; end; knotPtr1:=knotPtr1+1; end; -- knotPtr1: end of ks..ke segments. So it points ts or endc. end; MakeSaddle(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is i,sw:INT; d,pt,p1,p2,p3,p4:INT; if event=-1 then SetMode1(Knot); return; elsif event=-2 then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); modeMakeSaddle:=0.int; event:=KNOTX::knotButtonRelease; button:=KNOTX::knotButtonR; pressL:=false; EndOfCurrentSegment(inout Knot); x0:=mouseX; y0:=mouseY; return; end; if modeMakeSaddle.is_zero then SetMode1(Knot); end; if mouseX.is_neg then mouseX:=0.int; elsif mouseX>KNOTXW::GraphWidth then mouseX:=KNOTXW::GraphWidth; end; if mouseY.is_neg then mouseY:=0.int; elsif mouseY>KNOTXW::GraphHeight then mouseY:=KNOTXW::GraphHeight; end; case event when KNOTX::knotMotionNotify then if knotPtr.is_non_neg then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if VERTEXC::ks.in( Knot[knotPtr].sep) or VERTEXC::ts.in( Knot[knotPtr].sep) then KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); KNOTXW::DrawCircle(mouseX,mouseY,5.int,KNOTX::kMark,false); else KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, x0,y0, KNOTX::kMark); KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, mouseX, mouseY, KNOTX::kMark); end; x0:=mouseX; y0:=mouseY; else end; -- Show which end-point is nearest. Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); if pt.is_pos then if (pt<knotPtr1) then if (sw=0.int)and( (VERTEXC::normal/=Knot[pt].sep) or(VERTEXC::ks.in( Knot[pt-1].sep)) or(VERTEXC::ke.in( Knot[pt+1].sep))) then d:=DRAW_ALG::far; end; elsif (sw.is_zero)and((VERTEXC::ts.in(Knot[pt-1].sep))or (VERTEXC::te.in(Knot[pt+1].sep))) then if (knotPtr.is_pos)and (Knot.endOfString(pt,1.int)=Knot.endOfString(knotPtr,1.int)) then d:=DRAW_ALG::far; end; else d:=DRAW_ALG::far; end; end; DRAW_ALG::nearMark(Knot,pt,d,sw); when KNOTX::knotButtonPress then case button when KNOTX::knotButtonR then ; when KNOTX::knotButtonC then ; when KNOTX::knotButtonL then if knotPtr.is_neg then -- start of segment DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); Knot.updateCross:=true; if (d<DRAW_ALG::near)and(pt>=knotPtr1) then if sw/=0.int then return; end; if VERTEXC::ts.in(Knot[pt-1].sep) then Knot.revK(pt); end; knotPtr:=Knot.endOfString(pt,1.int)-1; x0:=Knot[knotPtr].x; y0:=-Knot[knotPtr].y; KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, x0,y0, KNOTX::kMark); pressL:=true; elsif (d<DRAW_ALG::near)and(pt<knotPtr1) then -- band attach to knot if (sw=0.int) then if (VERTEXC::normal/=Knot[pt].sep)or (VERTEXC::ks.in(Knot[pt-1].sep))or (VERTEXC::ke.in(Knot[pt+1].sep)) then return; end; elsif (sw=1.int) then Knot.CodeIn( (Knot[pt].x+Knot[pt+1].x).div(2), (Knot[pt].y+Knot[pt+1].y).div(2),pt+1); pt:=pt+1; knotPtr1:=knotPtr1+1; end; knotPtr:=Knot.length.int; Knot.CodeIn(VERTEXC::band_e,knotPtr.card); Knot.CodeIn(VERTEXC::band_s,knotPtr.card); knotPtr:=knotPtr+1; Knot.CodeIn(Knot[pt].x,Knot[pt].y,knotPtr); Knot[pt].sep:=VERTEXC::band_attach; x0:=mouseX; y0:=mouseY; KNOTXW::DrawLine(Knot[knotPtr].x, -Knot[knotPtr].y, x0,y0, KNOTX::kMark); pressL:=true; else knotPtr:=Knot.length.int; Knot.CodeIn(VERTEXC::band_e,knotPtr); Knot.CodeIn(VERTEXC::band_s,knotPtr); x0:=mouseX; y0:=mouseY; KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); pressL:=true; end; end; end; when KNOTX::knotButtonRelease then -- CHECK_KNOT_ALG::checkKnotD(K::Knot); case button when KNOTX::knotButtonC then ; when KNOTX::knotButtonR then if pressL then return; else EndOfCurrentSegment(inout Knot); x0:=mouseX; y0:=mouseY; end; when KNOTX::knotButtonL then pressL:=false; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); if knotPtr.is_non_neg then -- set vertex Knot.miniPt(mouseX,mouseY,out pt,out d,out sw); if (d<DRAW_ALG::near)and((pt=knotPtr)or((pt+1)=knotPtr)) then elsif (d<DRAW_ALG::near)and ( VERTEXC::ts.in(Knot[pt-1].sep)or VERTEXC::te.in(Knot[pt+1].sep)) then -- splice if (Knot.endOfString(knotPtr,1.int)=Knot.endOfString(pt,1.int)) then return; -- avoid making loop end; mouseX:=Knot[pt].x; mouseY:=-Knot[pt].y; if VERTEXC::ts.in(Knot[knotPtr].sep) then KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); Knot.CodeDel(knotPtr); Knot.CodeDel(knotPtr); else KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0, KNOTX::kMark); KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y, mouseX,mouseY,KNOTX::kStr); p1:=Knot.endOfString(knotPtr,-1); if (p1+1)=pt then -- close loop : cannot be #OUT+"Splice error.\n"; Knot.CodeIn(mouseX,-mouseY,knotPtr+1); -- safe even if failed here else -- splice strings if VERTEXC::te.in(Knot[pt+1].sep) then Knot.revK(pt); end; Knot.StringSplice(knotPtr,pt); end; end; knotPtr:=-1; DRAWKNOT_ALG::DrawKnot(Knot); elsif (d<DRAW_ALG::near)and(pt<knotPtr1) then -- attach to knot if VERTEXC::ts.in(Knot[knotPtr].sep) then -- band start from knot Knot.CodeDel(knotPtr); Knot.CodeDel(knotPtr); knotPtr:=-1; DRAWKNOT_ALG::DrawKnot(Knot); return; end; if (sw=0.int)and ((VERTEXC::normal/=Knot[pt].sep) or VERTEXC::ks.in(Knot[pt-1].sep) or VERTEXC::ke.in(Knot[pt+1].sep)) then return; end; if sw=1.int then Knot.CodeIn((Knot[pt].x+Knot[pt+1].x).div(2), (Knot[pt].y+Knot[pt+1].y).div(2),pt+1); pt:=pt+1; knotPtr1:=knotPtr1+1; knotPtr:=knotPtr+1; end; -- band attach to knot KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0, KNOTX::kMark); x0:=Knot[pt].x; y0:=-Knot[pt].y; Knot.CodeIn(x0,-y0,knotPtr+1); KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0,KNOTX::kStr); Knot[pt].sep:=VERTEXC::band_attach; knotPtr:=-1; DRAWKNOT_ALG::DrawKnot(Knot); else if VERTEXC::ks.in(Knot[knotPtr].sep) or VERTEXC::ts.in(Knot[knotPtr].sep) then KNOTXW::DrawCircle(x0,y0,5.int,KNOTX::kMark,false); x0:=mouseX; y0:=mouseY; Knot.CodeIn(x0,-y0,knotPtr+1); knotPtr:=knotPtr+1; -- DrawCircle(mouseX,mouseY,5,kStr,false); else KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0, KNOTX::kMark); x0:=mouseX; y0:=mouseY; Knot.CodeIn(x0,-y0,knotPtr+1); KNOTXW::DrawLine(Knot[knotPtr].x,-Knot[knotPtr].y,x0,y0,KNOTX::kStr); knotPtr:=knotPtr+1; end; DRAWKNOT_ALG::DrawKnot(Knot); end; end; end; end; end; end; -- class MAKE_SADDLE

class MOVE_VERTEX

class MOVE_VERTEX is shared knotPtr,knotPtr1:INT; shared pressL:BOOL; shared x0,y0:INT; shared knot0:KNOT; shared modeMoveVertex:INT; -- check if i0 have near points, and shrink/splice it. c.f. MoveVertex private IfNear(inout Knot:KNOT, i0:INT) is d,i1,j:INT; if (i0.is_neg) or (Knot.length.int<i0) then return; end; i1:=Knot.cmpOf(i0); if i1.is_neg then i1:=i0; end; -- band-ts/te or ks/ke if i1<i0 then j:=i0; i0:=i1; i1:=j; end; Knot.nearVertexV(i0,i1,out j,out d); if d>=DRAW_ALG::near then return; end; -- shrink knot if j=(i0+1) then if Knot.tooShort(i0) then Knot.delStr(inout i0); return; end; Knot.attach(i0,j); Knot.attach(i1,j); if VERTEXC::ks.in(Knot[i0-1].sep) or VERTEXC::ts.in(Knot[i0-1].sep) then Knot.DelV(j); elsif VERTEXC::ke.in(Knot[j+1].sep) or VERTEXC::te.in(Knot[j+1].sep) then Knot.DelV(i0); elsif VERTEXC::band.in(Knot[j].sep) then Knot[i0].x:=-1; Knot[i1].x:=-1; Knot.DelV(i0); else Knot.DelV(j); end; return; end; -- shrink knot if j=(i0-1) then if Knot.tooShort(i0) then Knot.delStr(inout i0); return; end; Knot.attach(i0,j); Knot.attach(i1,j); if VERTEXC::ke.in(Knot[i0+1].sep) or VERTEXC::te.in(Knot[i0+1].sep) then Knot.DelV(j); elsif VERTEXC::ks.in(Knot[j-1].sep) or VERTEXC::ts.in(Knot[j-1].sep) then Knot.DelV(i0); elsif VERTEXC::band.in(Knot[j].sep) then Knot[i0].x:=-1; Knot[i1].x:=-1; Knot.DelV(i0); else Knot.DelV(j); end; return; end; -- shrink knot at the end of component if VERTEXC::ks.in(Knot[j-1].sep) and (Knot.cmpOf(j)=(i0+1)) then Knot.attach(i0,j); Knot.DelV(i0); return; end; -- shrink at the end of band if VERTEXC::band.in(Knot[j].sep) and ((Knot.cmpOf(j)=(i0+1)) or (Knot.cmpOf(j)=(i0-1))) then if Knot.tooShort(i1) then Knot.delStr(inout i1); return; end; Knot.attach(i0,j); Knot.attach(i1,j); Knot.DelV(i1); return; end; -- shrink at the end of band if VERTEXC::band.in(Knot[i0].sep) and ((Knot.cmpOf(i0)=(j-1)) or (Knot.cmpOf(i0)=(j+1))) then if Knot.tooShort(j) then Knot.delStr(inout j); return; end; Knot.attach(i0,j); Knot.attach(i1,j); Knot.DelV(j); return; end; -- if i0/=i1 then return; end; if ~(VERTEXC::normal=Knot[i0].sep) then return; end; if ~(VERTEXC::normal=Knot[j].sep) then return; end; -- close knot if VERTEXC::ks.in(Knot[i0-1].sep) and (j=Knot.endOfString(i0,1.int)-1) then Knot.attach(i0,j); return; end; -- close knot if VERTEXC::ke.in(Knot[i0+1].sep) and(j=Knot.endOfString(i0,-1)+1) then Knot.attach(i0,j); return; end; -- splice knot if VERTEXC::ks.in(Knot[i0-1].sep) then if VERTEXC::ks.in(Knot[j-1].sep) then Knot.attach(i0,j); Knot.revK(i0); Knot.StringSplice(i0,j); return; elsif VERTEXC::ke.in(Knot[j+1].sep) then Knot.attach(i0,j); Knot.revK(i0); Knot.revK(j); Knot.StringSplice(i0,j); return; end; elsif VERTEXC::ke.in(Knot[i0+1].sep) then if VERTEXC::ks.in(Knot[j-1].sep) then Knot.attach(i0,j); Knot.StringSplice(i0,j); return; elsif VERTEXC::ke.in(Knot[j+1].sep) then Knot.attach(i0,j); Knot.revK(j); Knot.StringSplice(i0,j); return; end; end; -- splice band if VERTEXC::ts.in(Knot[i0-1].sep) then if VERTEXC::ts.in(Knot[j-1].sep) and (Knot.endOfString(i0,1.int)/=Knot.endOfString(j,1.int)) then Knot.attach(i0,j); Knot.revK(i0); Knot.StringSplice(i0,j); return; elsif VERTEXC::te.in(Knot[j+1].sep) and (Knot.endOfString(i0,1.int)/=Knot.endOfString(j,1.int)) then Knot.attach(i0,j); Knot.revK(i0); Knot.revK(j); Knot.StringSplice(i0,j); return; end; elsif VERTEXC::te.in(Knot[i0+1].sep) then if VERTEXC::ts.in(Knot[j-1].sep) and (Knot.endOfString(i0,1.int)/=Knot.endOfString(j,1.int)) then Knot.attach(i0,j); Knot.StringSplice(i0,j); return; elsif VERTEXC::te.in(Knot[j+1].sep) and (Knot.endOfString(i0,1.int)/=Knot.endOfString(j,1.int)) then Knot.attach(i0,j); Knot.revK(j); Knot.StringSplice(i0,j); return; end; end; -- attach band to knot if VERTEXC::ts.in(Knot[i0-1].sep) and VERTEXC::ks.in(Knot[Knot.endOfString(j,-1)].sep) then if (~(VERTEXC::ks.in(Knot[j-1].sep))) and (~(VERTEXC::ke.in(Knot[j+1].sep))) then Knot.attach(i0,j); Knot[j].sep:=VERTEXC::band_attach; end; return; end; if VERTEXC::te.in(Knot[i0+1].sep) and VERTEXC::ks.in(Knot[Knot.endOfString(j,-1)].sep) then if (~(VERTEXC::ks.in(Knot[j-1].sep))) and(~(VERTEXC::ke.in(Knot[j+1].sep))) then Knot.attach(i0,j); Knot[j].sep:=VERTEXC::band_attach; end; return; end; -- attach knot to band if VERTEXC::ts.in(Knot[j-1].sep) and VERTEXC::ks.in(Knot[Knot.endOfString(i0,-1)].sep) then if (~(VERTEXC::ks.in(Knot[i0-1].sep))) and(~(VERTEXC::ke.in(Knot[i0+1].sep))) then Knot.attach(i0,j); Knot[i0].sep:=VERTEXC::band_attach; end; return; end; if VERTEXC::te.in(Knot[j+1].sep) and VERTEXC::ks.in(Knot[Knot.endOfString(i0,-1)].sep) then if (~(VERTEXC::ks.in(Knot[i0-1].sep))) and(~(VERTEXC::ke.in(Knot[i0+1].sep))) then Knot.attach(i0,j); Knot[i0].sep:=VERTEXC::band_attach; end; return; end; end; MoveVertex(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is i0:INT; i:INT; sw:INT; d:INT; if event=-1 then modeMoveVertex:=1.int; knotPtr:=-1; pressL:=false; return; elsif event=-2 then modeMoveVertex:=0.int; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); knotPtr:=-1 ; pressL:=false; return; end; if modeMoveVertex.is_zero then #OUT+"MoveVertex: move mode error(1)\n"; modeMoveVertex:=1.int; knotPtr:=-1; pressL:=false; end; if mouseX.is_neg then mouseX:=0.int; elsif mouseX>KNOTXW::GraphWidth then mouseX:=KNOTXW::GraphWidth; end; if mouseY.is_neg then mouseY:=0.int; elsif mouseY>KNOTXW::GraphHeight then mouseY:=KNOTXW::GraphHeight; end; case event when KNOTX::knotMotionNotify then if pressL then if DRAW_ALG::smoothDraw then knot0[knotPtr].x:=mouseX; knot0[knotPtr].y:=-mouseY; knot0[knotPtr1].x:=mouseX; knot0[knotPtr1].y:=-mouseY; Knot:=knot0.clone; Knot.CrossSet(knotPtr-1,knotPtr1+1); else Knot[knotPtr].x:=mouseX; Knot[knotPtr].y:=-mouseY; Knot[knotPtr1].x:=mouseX; Knot[knotPtr1].y:=-mouseY; end; KNOTXW::WindowSw(0.int); DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; f_sw::=KNOTXW::FlushPixel; KNOTXW::WindowSw(1.int); else Knot.miniPt(mouseX,mouseY,out i,out d,out sw); 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 d<DRAW_ALG::near then Knot.updateCross:=true; if sw=1.int then i0:=i0+1; Knot.CodeIn(mouseX,-mouseY,i0); end; Knot.ClCrossEdge(inout i0,1.int); Knot.ClCrossEdge(inout i0,-1); if VERTEXC::band.in(Knot[i0].sep) then i0:=Knot.cmpOf(i0); Knot.ClCrossEdge(inout i0,1.int); i0:=Knot.cmpOf(i0); end; Knot.ClCrossErr(inout i0); i:=Knot.cmpOf(i0); if i.is_neg then i:=i0; end; knotPtr:=i0; knotPtr1:=i; pressL:=true; Knot[knotPtr].x:=mouseX; Knot[knotPtr].y:=-mouseY; Knot[knotPtr1].x:=mouseX; Knot[knotPtr1].y:=-mouseY; knot0:=Knot.clone; if DRAW_ALG::smoothDraw then Knot.CrossSet(knotPtr-1,knotPtr1+1); end; end; DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; end; 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::smoothDraw then -- Knot:=knot0.clone; end; if DRAW_ALG::latticeFlg then Knot[knotPtr].x:= DRAW_ALG::trimL(Knot[knotPtr].x); Knot[knotPtr].y:= -DRAW_ALG::trimL(-Knot[knotPtr].y); Knot[knotPtr1].x:=Knot[knotPtr].x; Knot[knotPtr1].y:=Knot[knotPtr].y; end; IfNear(inout Knot, knotPtr); Knot.ClCrossErr(inout knotPtr); knotPtr:=-1; knotPtr1:=-1; DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; end; end; end; end; -- class MOVE_VERTEX

class SHIFT_DIAGRAM

class SHIFT_DIAGRAM is shared knotPtr,knotPtr1:INT; shared pressL:BOOL; shared x0,y0:INT; shared maxX,minX,maxY,minY:INT; shared modeShiftDiagram:INT:=0; shiftD(inout Knot:KNOT, gx,gy:INT) is ofsX,ofsY:INT; ofsX:=gx-Knot[knotPtr].x; if (maxX+ofsX)>KNOTXW::GraphWidth then ofsX:=KNOTXW::GraphWidth-maxX; end; if (minX+ofsX).is_neg then ofsX:=-minX; end; ofsY:=-gy-Knot[knotPtr].y; if (minY+ofsY)<(-KNOTXW::GraphHeight) then ofsY:=-KNOTXW::GraphHeight-minY; end; if (maxY+ofsY).is_pos then ofsY:=-maxY; end; maxX:=maxX+ofsX; minX:=minX+ofsX; maxY:=maxY+ofsY; minY:=minY+ofsY; Knot.Shift(ofsX,ofsY); end; ShiftDiagram(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is i,d:INT; if event=-1 then modeShiftDiagram:=1.int; knotPtr:=-1; pressL:=false; return; elsif event=-2 then modeShiftDiagram:=0.int; knotPtr:=-1 ; pressL:=false; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); return; end; if modeShiftDiagram.is_zero then modeShiftDiagram:=1.int; knotPtr:=-1; pressL:=false; end; if mouseX.is_neg then mouseX:=0.int; elsif mouseX>KNOTXW::GraphWidth then mouseX:=KNOTXW::GraphWidth; end; if mouseY.is_neg then mouseY:=0.int; elsif mouseY>KNOTXW::GraphHeight then mouseY:=KNOTXW::GraphHeight; end; case event when KNOTX::knotMotionNotify then if pressL then shiftD(inout Knot, DRAW_ALG::trimL(mouseX),DRAW_ALG::trimL(mouseY)); KNOTXW::WindowSw(0.int); DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; f_sw::=KNOTXW::FlushPixel; KNOTXW::WindowSw(1.int); else -- miniPt(mouseX,mouseY,out i,out d,out sw); nearMark(Knot,i,d,sw); i:=Knot.miniVE(mouseX,mouseY,0.int,Knot.length.int,0.int,out d); DRAW_ALG::nearMark(Knot,i,d,0.int); end; when KNOTX::knotButtonPress then if button=KNOTX::knotButtonL then DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); -- miniPt(mouseX,mouseY,out i,out d,out sw); nearMark(i,d,sw); i:=Knot.miniVE(mouseX,mouseY,0.int,Knot.length.int,0.int,out d); DRAW_ALG::nearMark(Knot,i,d,0.int); if d<DRAW_ALG::near then knotPtr:=i; pressL:=true; maxX:=INT::minint; minX:=INT::maxint; maxY:=maxX; minY:=minX; loop j::=0.upto!( Knot.length ); if VERTEXC::normal.in(Knot[i].sep)or VERTEXC::crossing.in(Knot[i].sep) then if maxX<Knot[i].x then maxX:=Knot[i].x; end; if minX>Knot[i].x then minX:=Knot[i].x; end; if maxY<Knot[i].y then maxY:=Knot[i].y; end; if minY>Knot[i].y then minY:=Knot[i].y; end; end; end; shiftD(inout Knot,mouseX,mouseY); end; DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; end; when KNOTX::knotButtonRelease then if button=KNOTX::knotButtonL then pressL:=false; DRAW_ALG::nearMark(Knot,0.int,DRAW_ALG::far,0.int); knotPtr:=-1; knotPtr1:=-1; DRAWKNOT_ALG::DrawKnot(Knot); DRAW_ALG::DrawLattice; end; end; end; end; -- class SHIFT_DIAGRAM