splice.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
class SPLICE_ALG
class SPLICE_ALG is
-- Copyright (C) 1992 1996 Kouji KODAMA
-- 1996/10
-- LINUX version
--
-- 94/10/20 14:58:24 KDM
-- splice bug fix.
-- 1992/5
-- Splice: Band surgery
--------------state variables--------------------
shared KnotP0:KNOT; -- work
shared KnotCT:KNOT;
--KnotCT[] is a table of crossing condition
-- on the band in original picture.
shared numberOfCrossing:INT;
-- In setCrossingTbl, count number of crossings
-- max size of new Knot can be
-- (Knot.length+(s01-s00)+8*numberOfCrossing)
----------- work ------------
shared s00, s01, s10, s11, b0, b1:INT; -- band
shared rot0, rot1:INT; -- rotation around band attaching pts
shared vx, vx0,vy, vy0:INT; -- vextor
-- See 'setBoundaryPt'
const bdInn:INT:=1; -- inner of band core
const bdStp:INT:=2; -- start
const bdEnd:INT:=3; -- end
shared DTblV, DTblE:ARRAY{INT}; -- table of distance on the band. See setDTblV and setDTblE.
const maxhw0:INT:=16; -- max of half width of the band
const divL:INT:=3;
const maxD:INT:=maxhw0*divL; -- max distance in DTblV and DTblE
-- side
const left:INT:= 1;
const right:INT:=-1;
checkSw(knot:KNOT) is
knot.printD;
tmpStr::=#IN.get_line;
#OUT+
-- " k00 "+k00.str+" k01 "+k01.str+
" b0 "+b0.str+" b1 "+b1.str+
" s00 "+s00.str+" s01 "+s01.str+
" s10 "+s10.str+" s11 "+s11.str+"\n";
end;
checkS(knot:KNOT,s:STR) is
if (VERTEXC::band_s=knot[s00].sep) and
(VERTEXC::band_e=knot[s01].sep) and
(VERTEXC::band_s=knot[s10].sep) and
(VERTEXC::band_e=knot[s11].sep) then ;
else
#OUT+"checkS:"+s+"\n";
end;
end;
exg(inout Knot:KNOT, w,w1,cn:INT):BOOL is
if ~ VERTEXC::crossing.in(KnotCT[cn].sep) then return false; end;
if Knot[w].sep/=KnotCT[cn].sep then
Knot[w1].sep:=Knot[w].sep.clone;
Knot[w].sep:=KnotCT[cn].sep.clone;
end;
return true;
end;
setCr(inout Knot:KNOT, k0, k1:INT, dir:INT):BOOL is
w, w1, cn:INT;
cn:=1; w:=k0;
loop while!( ((dir.is_pos)and(w<k1))or((dir.is_neg)and(k1<w)) ) ;
if VERTEXC::crossing.in(Knot[w].sep) then
w1:=Knot.cmpOf(w);
if ~ exg(inout Knot, w,w1,cn) then return false; end;
if ((s00<w1)/=(s01<w1))or((s10<w1)/=(s11<w1)) then
w:=w+dir; w1:=Knot.cmpOf(w);
if ~ exg(inout Knot, w,w1,cn) then return false; end;
end;
cn:=cn+1;
end;
w:=w+dir;
end;
return (VERTEXC::te.in(KnotCT[cn].sep));
end;
setCrossingTbl(inout Knot:KNOT) is
ki, kic, cn:INT;
KnotCT.CodeIn(Knot[s00].clone,0); cn:=1;
loop ki:=s00.upto!(s01) ;
if VERTEXC::crossing.in(Knot[ki].sep) then
KnotCT.CodeIn(Knot[ki].clone,cn.card); cn:=cn+1;
end;
end;
KnotCT.CodeIn(Knot[s01].clone,cn.card); numberOfCrossing:=cn-1;
-- delete crossings on the band
ki:=s00;
loop while!( ~VERTEXC::te.in(Knot[ki].sep)) ;
if VERTEXC::crossing.in(Knot[ki].sep) then
kic:=Knot.cmpOf(ki);
if kic<ki then ki:=ki-1; end;
Knot.CodeDel(kic.card); Knot.CodeDel(ki.card);
else ki:=ki+1;
end;
end;
-- update band s00..s01
s01:=Knot.length.int-1; s00:=Knot.endOfString(s01,-1);
end;
set(Knot:KNOT, si:INT, x,y,l:INT) is
VEC_ALG::sLength(inout x, inout y, l);
KnotP0.CodeIn(Knot[si].x+x,Knot[si].y+y,KnotP0.length);
end;
copyK(inout Knot:KNOT, i1, i2, dir:INT) is
count:INT:=(i2-i1)*dir+1; if count.is_non_pos then return; end;
w:INT:=i1;
loop count.times!;
Knot.CodeIn(KnotP0[w].clone,Knot.length); w:=w+dir;
end;
end;
setBoundaryPt(Knot:KNOT, side,btype:INT,inout d0:INT, d,si:INT) is
-- Before use this, Set d,vx,vy, d0,vx0,vy0
-- See last of this procedure.
x, y, x0, x1, y0, y1, l:INT;
inn, outS, outS2:INT;
t0x,t0y,t1x,t1y:INT;
if d<d0 then l:=d; else l:=d0; end;
l:=l / divL;
x0:=vx0; y0:=vy0;
VEC_ALG::sLength(inout x0, inout y0, 1024.int);
x1:=vx; y1:=vy;
VEC_ALG::sLength(inout x1,inout y1, 1024.int);
inn:=x0*x1+y0*y1; -- v0 * v1
outS:=(x0*y1-y0*x1)*side; -- (v0 x v1) *side
outS2:=(outS+outS).abs;
t0x:=-y0*side; t0y:=x0*side;
VEC_ALG::sLength(inout t0x,inout t0y,1024.int);
t1x:=-y1*side; t1y:=x1*side;
VEC_ALG::sLength(inout t1x,inout t1y,1024.int);
case btype
when bdInn then
-- inner points of the band
if (inn*2<=outS)and(outS.is_neg) then
set(Knot,si,t0x*2+t1x ,t0y*2+t1y,l);
set(Knot,si,t0x+t1x*2 ,t0y+t1y*2,l);
else
set(Knot,si,t0x+t1x ,t0y+t1y,l);
end;
when bdStp then
-- start point of the band
if (outS.is_pos) and (inn<outS2 ) then -- 1
set(Knot,si,-x0,-y0,l);
elsif inn>outS2 then -- 2
set(Knot,si,-x0,-y0,l);
set(Knot,si,t0x+t1x*2,t0y+t1y*2,l);
elsif outS2>inn.abs then -- 3
set(Knot,si,x0,y0,l);
else -- 4
set(Knot,si,0.int,0.int,l);
set(Knot,si,t0x+t1x*2,t0y+t1y*2,l);
end;
when bdEnd then
-- end point of the band
if (outS.is_pos) and (inn<outS2 ) then -- 1
set(Knot,si,x1,y1,l);
elsif inn>outS2 then -- 2
set(Knot,si,t0x*2+t1x ,t0y*2+t1y,l);
set(Knot,si,x1,y1,l);
elsif outS2>inn.abs then -- 3
set(Knot,si,-x1,-y1,l);
else -- 4
set(Knot,si,t0x*2+t1x*2 ,t0y*2+t1y,l);
set(Knot,si,0.int,0.int,l);
end;
end;
vx0:=vx; vy0:=vy; d0:=d; -- prepare for next point
end;
setdV(Knot:KNOT, ki:INT) is
i, j, px, py, mx, Mx, my, My:INT;
x1, x2, y1, y2, kl:INT;
d:INT; -- distance
d20, d21:INT; -- square of distance
px:=Knot[ki].x; py:=Knot[ki].y;
d20:=maxD*maxD;
d:=maxD; mx:=px-d; Mx:=px+d; my:=py-d; My:=py+d;
i:=1.int; kl:=Knot.length.int-3;
loop while!(i<= kl);
j:=i;
loop j:=j+1; until!(VERTEXC::normal.in(Knot[j].sep)); end;
if ( VERTEXC::normal.in(Knot[i].sep) and
~ VERTEXC::separator.in( Knot[i+1].sep)) then
-- edge i..j
x1:=Knot[i].x; x2:=Knot[j].x;
if ~(((x1<mx)and(x2<mx)) or((Mx<x1)and(Mx<x2)) )then
y1:=Knot[i].y; y2:=Knot[j].y;
if ~( ((y1<my)and(y2<my)) or ((My<y1)and(My<y2)) )then
d21:=Knot.distanceL2(i, px, py, 0.int);
if (d21.is_pos)and(d21<d20) then
d20:=d21;
d:=d20.flt.sqrt.round.int;
mx:=px-d; Mx:=px+d; my:=py-d; My:=py+d;
end;
end;
end;
end;
i:=j;
end;
DTblV[ki.card]:=d;
end;
setDTblV(Knot:KNOT) is
-- DTblV[ki] be the table of
-- min( disttance(vertex Knot[ki], edge Knot[i]-Knot[i+1]))
-- at the start of the band
DTblV[b0.card-1]:=maxD; setdV(Knot,b0); DTblV[b0.card+1]:=maxD;
loop ki::=(s00+1).upto!(s01-1); setdV(Knot,ki); end; -- on the band
-- at the end of the band
DTblV[b1.card-1]:=maxD; setdV(Knot,b1); DTblV[b1.card+1]:=maxD;
end;
setdE(Knot:KNOT,side:INT, ki:INT) is
d:INT; -- distance
d20, d21:INT; -- square of distance
i, ki1:INT;
minX, maxX, minY, maxY, MinX, MaxX, MinY, MaxY:INT;
ki1:=ki+1;
d20:=maxD;
d21:=DTblV[ki.card]; if (d21.is_pos)and(d21<d20) then d20:=d21; end;
d21:=DTblV[ki1.card]; if (21.is_pos)and(d21<d20) then d20:=d21; end;
d:=d20;
d20:=d20*d20;
if Knot[ki].x<Knot[ki1].x then minX:=Knot[ki].x; maxX:=Knot[ki1].x;
else minX:=Knot[ki1].x; maxX:=Knot[ki].x;
end;
if Knot[ki].y<Knot[ki1].y then minY:=Knot[ki].y; maxY:=Knot[ki1].y;
else minY:=Knot[ki1].y; maxY:=Knot[ki].y;
end;
MinX:=minX-d; MaxX:=maxX+d; MinY:=minY-d; MaxY:=maxY+d;
loop i:=1.int.upto!(Knot.length.int-3);
if ~( VERTEXC::separator.in(Knot[i].sep)) then
if (MinX<Knot[i].x)and(Knot[i].x<MaxX)and
(MinY<Knot[i].y)and(Knot[i].y<MaxY) then
d21:=Knot.distanceL2(ki, Knot[i].x, Knot[i].y, side);
if (d21.is_pos)and(d21<d20) then
d20:=d21;
d:=d20.flt.sqrt.round.int;
MinX:=minX-d; MaxX:=maxX+d; MinY:=minY-d; MaxY:=maxY+d;
end;
end;
end;
end;
DTblE[ki.card]:=d;
end;
setDTblE(Knot:KNOT,side:INT) is
-- DTblE[ki] be the table of
-- min( distance(edge Knot[ki]-Knot[ki+1], vertex Knot[i]))
-- near the start of the band
setdE(Knot,right,b0-1); setdE(Knot,right,b0); DTblV[b0.card+1]:=maxD;
loop ki::=(s00+1).upto!(s01-2); setdE(Knot,side,ki); end;
-- near the end of the band
setdE(Knot,-rot1,b1-1); setdE(Knot,-rot1,b1); DTblV[b1.card+1]:=maxD;
end;
setbds(Knot:KNOT,side:INT) is
-- set boundaries
btype,d0:INT;
setDTblE(Knot,side);
KnotP0.CodeIn(Knot[s00].clone, KnotP0.length);
vx0:=Knot[b0].x-Knot[b0-side].x;
vy0:=Knot[b0].y-Knot[b0-side].y;
if side=left then d0:=DTblE[(b0-side).card]; else d0:=DTblE[b0.card]; end;
-- d0::=DTblE[b0-side];
btype:=bdStp;
loop si::=(s00+1).upto!(s01-2);
vx:=Knot[si+1].x-Knot[si].x;
vy:=Knot[si+1].y-Knot[si].y;
setBoundaryPt(Knot,side, btype,inout d0,DTblE[si.card],si);
btype:=bdInn;
end;
--
btype:=bdEnd;
vx:=Knot[b1+rot1*side].x-Knot[b1].x;
vy:=Knot[b1+rot1*side].y-Knot[b1].y;
-- d:=DTblE[b1+rot1*side];
-- if rot1=1 then
-- if side=left(*1*) then d:=DTblE[b1-1]; else d:=DTblE[b1]; end;
-- else
-- if side=left(*1*) then d:=DTblE[b1]; else d:=DTblE[b1-1]; end;
-- end;
setBoundaryPt(Knot,side, btype,inout d0,DTblE[b1.card],s01-1);
KnotP0.CodeIn(Knot[s01].clone,KnotP0.length);
end;
setBoundary(Knot:KNOT) is
-- knot is modified to rot0(rot near the start point b0) be +1.
-- set boundary of the band s00..s01, s10..s11
si:INT; -- position on knot data
-- d0:INT; --distance
-- d:INT;
r0:INT; -- save rot0
r0:=rot0;
if r0=-1 then Knot.mirrorY; rot0:=-rot0; rot1:=-rot1; end;
-- Now, rot0 is +1.
-- start of set KnotP0
KnotP0:=#;
loop si:=0.int.upto!(s00-1); KnotP0.CodeIn(Knot[si].clone,KnotP0.length); end;
-- allocate DTblV and DTblE with apropriate size.
DTblV:=#(Knot.length+(s01-s00).card+8*numberOfCrossing.card);
DTblE:=#(Knot.length+(s01-s00).card+8*numberOfCrossing.card); -- allocate them
setDTblV(Knot);
setbds(Knot,left);
setbds(Knot,right);
DTblV:=#; DTblE:=#; -- deallocate them
loop si:=(s01+1).upto!(Knot.length.int-1);
KnotP0.CodeIn(Knot[si].clone,KnotP0.length);
end;
-- end of set KnotP0
s01:=KnotP0.endOfString(s00+1, 1.int);
s10:=s01+1; s11:=KnotP0.endOfString(s10+1, 1.int);
-- same as follows.
-- s11:=KnotP0.length-1; s10:=KnotP0.endOfString(s11,-1);
-- s01:=s10-1; s00:=KnotP0.endOfString(s01,-1);
if r0=-1 then Knot.mirrorY; rot0:=-rot0; rot1:=-rot1; end;
-- #OUT+"setBoundary check knot/1\n";
-- KNotP0.printD;
-- dummy_str::=#IN.get_line; #OUT+dummy_str;
-- #OUT+"setBoundary check knot/2\n";
end;
SpliceK1(inout Knot:KNOT, i:INT) is
#OUT+" splice along the band ( "+i.str+" )"; #OUT.flush;
k00, k01, k10, k11:INT; -- index for knot
u0x, u1x, u0y, u1y :INT; -- work, vector
d:INT; -- work
KnotORG:KNOT:=Knot.clone; -- save original
Knot.SLength;
-- check if band
u0x:=Knot[i].x; u0y:=Knot[i].y;
Knot.CrossSet(0.int,Knot.length.int);
i:=Knot.miniVE(u0x, -u0y, 0.int, Knot.length.int, 0.int, out d);
if VERTEXC::band.in(Knot[i].sep) then i:=Knot.cmpOf(i); end;
s00:=Knot.endOfString(i, -1);
if VERTEXC::ts.in(Knot[s00].sep) then ;
elsif VERTEXC::ks.in(Knot[s00].sep) then return; -- Not a band
else return; -- Error. Cannot be this.
end;
-- #OUT+"the band attaching to b0,b1 on components k00..k01, k10..k11\n"; #OUT.flush;
s01:=Knot.endOfString(s00,1.int);
-- #OUT+"s00="+s00.str+", s01="+s01.str+"\n";
b0:=Knot.cmpOf(s00); b1:=Knot.cmpOf(s01);
if b0.is_neg or b1.is_neg then
#OUT+"The band is not attached to knot/link.\n";
return;
end;
-- #OUT+"b0="+b0.str+", b1="+b1.str+"\n";
-- #OUT+"-- rot0, rot1: condition near b0,b1 ends of the band\n"; #OUT.flush;
vx:=Knot[s00+2].x-Knot[s00+1].x; vy:=Knot[s00+2].y-Knot[s00+1].y;
u0x:=Knot[b0-1].x-Knot[b0].x; u0y:=Knot[b0-1].y-Knot[b0].y;
u1x:=Knot[b0+1].x-Knot[b0].x; u1y:=Knot[b0+1].y-Knot[b0].y;
rot0:=VEC_ALG::rotation(u0x, u0y, vx, vy, u1x, u1y);
vx:=Knot[s01-2].x-Knot[s01-1].x; vy:=Knot[s01-2].y-Knot[s01-1].y;
u0x:=Knot[b1-1].x-Knot[b1].x; u0y:=Knot[b1-1].y-Knot[b1].y;
u1x:=Knot[b1+1].x-Knot[b1].x; u1y:=Knot[b1+1].y-Knot[b1].y;
rot1:=VEC_ALG::rotation(u0x, u0y, vx, vy, u1x, u1y);
-- DrawKnot; out('tp0'); wait;
-- #OUT+"the band is Knot[s00..s01]\n"; #OUT.flush;
s00:=Knot.endOfString(s00, -1); s01:=Knot.endOfString(s00, 1.int);
-- #OUT+"Move the band to the end of knot data\n"; #OUT.flush;
if Knot.length.int/=(s01+1) then
Knot.CodeSplice(s01+1,Knot.length.int-1,s00,s01);
end;
s01:=Knot.length.int-1; s00:=Knot.endOfString(s01, -1);
b0:=Knot.cmpOf(s00); b1:=Knot.cmpOf(s01);
k00:=Knot.endOfString(b0, -1); k01:=Knot.endOfString(b0, 1.int);
k10:=Knot.endOfString(b1, -1); k11:=Knot.endOfString(b1, 1.int);
if k00=k10 then -- Ends of band attached the same component.
if rot0=rot1 then
if rot0.is_neg then Knot.revK(k00); rot0:=-rot0; rot1:=-rot1; end;
b0:=Knot.cmpOf(s00); b1:=Knot.cmpOf(s01);
if b1<b0 then Knot.revK(s00); end;
else
if rot0.is_neg then Knot.revK(s00); rot0:=-rot0; rot1:=-rot1; end;
end;
else -- band connect other components.
if rot0.is_neg then Knot.revK(b0);b0:=Knot.cmpOf(s00); rot0:=-rot0; end;
if rot1.is_neg then Knot.revK(b1);b1:=Knot.cmpOf(s01); rot1:=-rot1; end;
-- if string is open, then the string must be 1-st string.
k10:=Knot.endOfString(b1,-1); k11:=Knot.endOfString(b1,1.int);
if ~ Knot.Match(k10+1,k11-1) then
-- the 2nd string is not closed,
-- so exchange start to end of band.
Knot.revK(s00);
end;
-- string k10..k11 be immediate after the segment k00..k01.
k00:=Knot.endOfString(Knot.cmpOf(s00),-1);
k01:=Knot.endOfString(k00,1.int);
k10:=Knot.endOfString(Knot.cmpOf(s01),-1);
k11:=Knot.endOfString(k10,1.int);
Knot.CodeSplice(k00,k01,k10,k11);
end;
s01:=Knot.length.int-1; s00:=Knot.endOfString(s01, -1);
b0:=Knot.cmpOf(s00); b1:=Knot.cmpOf(s01);
setCrossingTbl(inout Knot);
-- KnotCT be table of crossings on the band
-- max size of new Knot may be length+(s01-s00)+8*numberOfCrossing
s01:=Knot.length.int-1; s00:=Knot.endOfString(s01, -1);
b0:=Knot.cmpOf(s00); b1:=Knot.cmpOf(s01);
k00:=Knot.endOfString(b0,-1); k01:=Knot.endOfString(b0,1.int);
k10:=Knot.endOfString(b1,-1); k11:=Knot.endOfString(b1,1.int);
-- #OUT+"b0, b1 set before call setBoundary\n"; #OUT.flush;
setBoundary(Knot); -- boundary of the band to KnotP0
-- checkS(KnotP0, "spliceK");
Knot:=#; -- prepare for new diagram
if k10=k00 then -- band connect points on the same component
if rot0=rot1 then
--#OUT+"spliceK:1 splice the knot(rot0=rot1)\n";
copyK(inout Knot, 0.int, k00-1, 1.int);
copyK(inout Knot, k00, b0-1, 1.int);
copyK(inout Knot, s00+1, s01-1, 1.int);
copyK(inout Knot, b1+1, k01, 1.int);
copyK(inout Knot, k00, k00, 1.int);
copyK(inout Knot, s11-1, s10+1, -1);
copyK(inout Knot, b0+1, b1-1, 1.int);
copyK(inout Knot, s11-1, s11-1, 1.int);
copyK(inout Knot, k01, k01, 1.int);
copyK(inout Knot, k01+1, s00-1, 1.int);
copyK(inout Knot, s11+1,KnotP0.length.int-1, 1.int);
Knot.SLength;
Knot.CrossSet(0.int,Knot.length.int);
s00:=Knot.miniVE(KnotP0[s00+1].x,-KnotP0[s00+1].y,0.int, Knot.length.int,0.int,out d);
s01:=Knot.miniVE(KnotP0[s01-1].x,-KnotP0[s01-1].y,0.int, Knot.length.int,0.int,out d);
s10:=Knot.miniVE(KnotP0[s10+1].x,-KnotP0[s10+1].y,0.int, Knot.length.int,0.int,out d);
s11:=Knot.miniVE(KnotP0[s11-1].x,-KnotP0[s11-1].y,0.int, Knot.length.int,0.int,out d);
-- #OUT+"s00,s01,s10,s11:"+
-- s00.str+" "+s01.str+" "+s10.str+" "+s11.str+"\n";
if ~ (setCr(inout Knot,s00, s01, 1.int) and
setCr(inout Knot,s10, s11, -1)) then
Knot:=KnotORG; return;
end;
elsif b0<b1 then
--#OUT+"spliceK:2 splice the knot(rot0/=rot1,b0<b1)\n";
copyK(inout Knot, 0.int, k00-1, 1.int);
copyK(inout Knot, k00, b0-1, 1.int);
copyK(inout Knot, s00+1, s01-1, 1.int);
copyK(inout Knot, b1-1, b0+1, -1);
copyK(inout Knot, s10+1, s11-1, 1.int);
copyK(inout Knot, b1+1, k01, 1.int);
copyK(inout Knot, k01+1, s00-1, 1.int);
copyK(inout Knot, s11+1, KnotP0.length.int-1, 1.int);
Knot.SLength;
Knot.CrossSet(0.int,Knot.length.int);
s00:=Knot.miniVE(KnotP0[s00+1].x,-KnotP0[s00+1].y,0.int, Knot.length.int,0.int,out d);
s01:=Knot.miniVE(KnotP0[s01-1].x,-KnotP0[s01-1].y,0.int, Knot.length.int,0.int,out d);
s10:=Knot.miniVE(KnotP0[s10+1].x,-KnotP0[s10+1].y,0.int, Knot.length.int,0.int,out d);
s11:=Knot.miniVE(KnotP0[s11-1].x,-KnotP0[s11-1].y,0.int, Knot.length.int,0.int,out d);
if ~ (setCr(inout Knot,s00, s01, 1.int) and
setCr(inout Knot,s10, s11, 1.int)) then
Knot:=KnotORG; return;
end;
else -- b1<b0
--#OUT+"spliceK:3 splice the knot(rot0/=rot1,b1<b0)\n";
copyK(inout Knot,0.int,k00-1,1.int);
copyK(inout Knot,k00,b1-1,1.int);
copyK(inout Knot,s01-1,s00+1,-1);
copyK(inout Knot,b0-1,b1+1,-1);
copyK(inout Knot,s11-1,s10+1,-1);
copyK(inout Knot,b0+1,k01,1.int);
copyK(inout Knot,k01+1,s00-1,1.int);
copyK(inout Knot,s11+1,KnotP0.length.int-1,1.int);
Knot.SLength;
Knot.CrossSet(0.int,Knot.length.int);
s00:=Knot.miniVE(KnotP0[s00+1].x,-KnotP0[s00+1].y,0.int, Knot.length.int,0.int,out d);
s01:=Knot.miniVE(KnotP0[s01-1].x,-KnotP0[s01-1].y,0.int, Knot.length.int,0.int,out d);
s10:=Knot.miniVE(KnotP0[s10+1].x,-KnotP0[s10+1].y,0.int, Knot.length.int,0.int,out d);
s11:=Knot.miniVE(KnotP0[s11-1].x,-KnotP0[s11-1].y,0.int, Knot.length.int,0.int,out d);
if ~ (setCr(inout Knot,s00, s01, -1) and
setCr(inout Knot,s10, s11, -1)) then
Knot:=KnotORG; return;
end;
end;
else
-- band connects points on difference components.
if KnotP0.Match(k10+1,k11-1) then
--#OUT+"spliceK:4 splice link(2nd compo. is closed)\n";
copyK(inout Knot, 0.int, k00-1, 1.int);
copyK(inout Knot, k00, b0-1, 1.int);
copyK(inout Knot, s00+1, s01-1, 1.int);
copyK(inout Knot, b1+1, k11-1, 1.int);
copyK(inout Knot, k10+2, b1-1, 1.int);
copyK(inout Knot, s11-1, s10+1, -1);
copyK(inout Knot, b0+1, k01, 1.int);
copyK(inout Knot, k11+1, s00-1, 1.int);
copyK(inout Knot, s11+1, KnotP0.length.int-1, 1.int);
Knot.SLength;
-- Knot.checkCode;
Knot.CrossSet(0.int,Knot.length.int);
s00:=Knot.miniVE(KnotP0[s00+1].x,-KnotP0[s00+1].y,0.int, Knot.length.int,0.int,out d);
s01:=Knot.miniVE(KnotP0[s01-1].x,-KnotP0[s01-1].y,0.int, Knot.length.int,0.int,out d);
s10:=Knot.miniVE(KnotP0[s10+1].x,-KnotP0[s10+1].y,0.int, Knot.length.int,0.int,out d);
s11:=Knot.miniVE(KnotP0[s11-1].x,-KnotP0[s11-1].y,0.int, Knot.length.int,0.int,out d);
if ~ (setCr(inout Knot,s00, s01, 1.int) and
setCr(inout Knot,s10, s11, -1)) then
Knot:=KnotORG;
return;
end;
else
--#OUT+"spliceK:5 splice link(2nd compo. is _not_ closed)\n";
copyK(inout Knot, 0.int, k00-1, 1.int);
copyK(inout Knot, k00, b0-1, 1.int);
copyK(inout Knot, s00+1, s01-1, 1.int);
copyK(inout Knot, b1+1, k11, 1.int);
copyK(inout Knot, k10, b1-1, 1.int);
copyK(inout Knot, s11-1, s10+1, -1);
copyK(inout Knot, b0+1, k01, 1.int);
copyK(inout Knot, k11+1, s00-1, 1.int);
copyK(inout Knot, s11+1, KnotP0.length.int-1, 1.int);
Knot.SLength;
Knot.CrossSet(0.int,Knot.length.int);
s00:=Knot.miniVE(KnotP0[s00+1].x,-KnotP0[s00+1].y,0.int, Knot.length.int,0.int,out d);
s01:=Knot.miniVE(KnotP0[s01-1].x,-KnotP0[s01-1].y,0.int, Knot.length.int,0.int,out d);
s10:=Knot.miniVE(KnotP0[s10+1].x,-KnotP0[s10+1].y,0.int, Knot.length.int,0.int,out d);
s11:=Knot.miniVE(KnotP0[s11-1].x,-KnotP0[s11-1].y,0.int, Knot.length.int,0.int,out d);
if ~ (setCr(inout Knot,s00, s01, 1.int) and
setCr(inout Knot,s10, s11, -1)) then
Knot:=KnotORG; return;
end;
end;
end;
Knot.shiftToInside;
return;
end;
SpliceK(inout Knot:KNOT, i:INT) is
KnotP0:=#; KnotCT:=#;
SpliceK1(inout Knot,i);
KnotP0:=#; KnotCT:=#;
end;
end; -- class SPLICE_ALG
class SPLICE
class SPLICE is
shared bandStart:INT;
-- Splice the knot along a band
Splice(inout Knot:KNOT, event, button, mouseX,mouseY:INT) is
pt,d,sw,i,j:INT;
if event=-1 then Knot.SLength; bandStart:=Knot.bandStart;
return;
elsif event=-2 then
bandStart:=-1; 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);
if (pt<bandStart) then d:=DRAW_ALG::far; end;
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)and
((bandStart<=pt)or
((sw.is_zero)and(VERTEXC::band.in(Knot[pt].sep)))) then
if (pt<bandStart) then pt:=Knot.cmpOf(pt); end;
HISTORY::put(Knot);
SPLICE_ALG::SpliceK(inout Knot, pt);
bandStart:=Knot.bandStart;
DRAWKNOT_ALG::DrawKnot(Knot);
end;
end;
end;
end; -- class SPLICE
-- SpliceK1
-- setCrossingTbl(inout Knot:KNOT)
-- setBoundary(Knot:KNOT)
-- setDTblV(Knot:KNOT)
-- setdV(Knot:KNOT, ki:INT)
-- setbds(Knot:KNOT,side:INT,inout d0:INT)
-- setDTblE(Knot:KNOT,side:INT)
-- detdE(Knot:KNOT,side:INT, ki:INT)
-- setBoundaryPt(Knot:KNOT,side,btype,inout d0,d,si:INT)
-- set(Knot:KNOT, si:INT, x,y,l:INT)
-- copyK(inout Knot:KNOT, i1, i2, dir:INT)
-- setCr(inout Knot:KNOT, k0, k1, dir:INT):BOOL
-- exg(inout Knot:KNOT, w,w1,cn:INT):BOOL