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