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