drawknot_alg.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
-- IF ELSIF ELSE THEN END RETURN IN ".in("  AND OR LOOP WHILE TRUE FALSE
-- INTEGER BOOLEAN VertexC
-- PROCEDURE BEGIN






class DRAW_ALG

class DRAW_ALG is ------------------------ lattice ---------------------- const LWidthP:INT:=5; const LWidth:INT:=2*LWidthP; const LWidth2:INT:=2*LWidth; shared latticeFlg:BOOL:=false; trimL(c:INT):INT is -- return (c -(c mod LWidth)+LWidthP); return ((c+LWidthP).div(LWidth))*LWidth; end; CnvLattice(c:INT):INT is return trimL(c); end; DrawLattice is loop x:INT:=LWidth.stepto!(KNOTXW::GraphWidth,LWidth2); loop y:INT:=LWidth.stepto!(KNOTXW::GraphHeight,LWidth2); KNOTXW::DrawPoint(x, y, 2); end; end; end; -- for DrawKnot,DrawKnotPic spaced r-dot at under crossing sl(x0, y0:INT, inout x1:INT, inout y1:INT, r:INT) is vx, vy, d, s:INT; -- vx:=LONG(x1-x0); vy:=LONG(y1-y0); -- d:=ABS(vx)+ABS(vy); if d>r then s:=d-r; else s:=0; d:=1; end; -- x1:=x0+SHORT((vx*s) DIV d); y1:=y0+SHORT((vy*s) DIV d); vx:=(x0-x1); vy:=(y0-y1); d:=vx.abs+vy.abs; if d>r then x1:=x1+((vx*r) / d); y1:=y1+((vy*r) / d); else x1:=x0; y1:=y0; end; end; ---------------------- mark ------------------------ circleK(Knot:KNOT, i,sw,r,col:INT) is -- Draw circle at vertex/edge. -- sw=0:vertex, sw=1:edge. if (sw=1)or(sw=0) then KNOTXW::DrawCircle((Knot[i].x+Knot[i+sw].x)/ 2, -(Knot[i].y+Knot[i+sw].y)/ 2, r, col, false); end; end; circleF(Knot:KNOT, i,r,col:INT) is KNOTXW::DrawCircle(Knot[i].x, -Knot[i].y, r, col, true); end; UpdateVE(Knot:KNOT,inout i0:INT, i1:INT, inout sw0:INT, sw1:INT) is #OUT+"UpdateVE is uncertified.\n"; if (i0/=i1)or(sw0/=sw1) then -- MouseK.Off; if 0<i0 then circleK(Knot,i0,sw0,5,KNOTX::kMark); end; circleK(Knot,i1,sw1,5,KNOTX::kMark); i0:=i1; sw0:=sw1; -- MouseK.On; end; end; ------------- state of nearMark ----------- shared smoothDraw:BOOL:=false; shared markVertex:BOOL:=false; const near:INT:=16; const far:INT:=10000; shared nearMarkd0:INT:=far; shared nearMarkx0:INT:=0; shared nearMarky0:INT:=0; nearMark(Knot:KNOT,pt,d,sw:INT) is -- Markup the point, if near. if nearMarkd0<near then KNOTXW::DrawCircle(nearMarkx0,-nearMarky0,5,KNOTX::kMark,false); end; if sw>=2 then d:=far; end; if d <near then nearMarkx0:=(Knot[pt].x+Knot[pt+sw].x)/ 2; nearMarky0:=(Knot[pt].y+Knot[pt+sw].y)/ 2; KNOTXW::DrawCircle(nearMarkx0,-nearMarky0,5,KNOTX::kMark,false); end; nearMarkd0:=d; end; end; -- DRAW_ALG

class DRAWKNOT_ALG

class DRAWKNOT_ALG is --------------------------- Draw Knot -------------------- const arrowLen:FLT:=10.0; const arrowRatio:FLT:=1.0/3.0; const arrowLenS:FLT:=arrowLen/arrowRatio; arrow(inout gx0,inout gy0,inout gx1,inout gy1,inout gx2,inout gy2:INT) is -- Draw arrow at the center of pt0 and pt1 -- return line pt0-pt1-pt2 ux, uy, vx, vy, s:FLT; ux:=(gx1-gx0).flt; uy:=(gy1-gy0).flt; gx1:=(gx1+gx0)/2; gy1:=(gy1+gy0)/2; s:=(ux*ux+uy*uy).sqrt; if s>=arrowLenS then s:=arrowLen/s; else s:=arrowRatio; end; ux:=ux*s; uy:=uy*s; gx0:=gx1+(-ux+uy*0.6).round.int; gy0:=gy1+(-uy-ux*0.6).round.int; gx2:=gx1+(-ux-uy*0.6).round.int; gy2:=gy1+(-uy+ux*0.6).round.int; end; arrowS(gx0, gy0, gx1, gy1, col:INT) is -- Draw arrow at the center of pt.0 and pt.1 gx2, gy2:INT; arrow(inout gx0,inout gy0,inout gx1,inout gy1,inout gx2,inout gy2); KNOTXW::DrawLine(gx0, gy0, gx1, gy1, col); KNOTXW::DrawLine(gx2, gy2, gx1, gy1, col); end; Bezier(x0, y0, x1, y1, x2, y2, col:INT) is s, s0, s1, s2, x0l, y0l, x1l, y1l, x2l, y2l:INT; step:INT:=8; step2:INT:=step*step; x0l:=x0; y0l:=y0; x1l:=x1; y1l:=y1; x2l:=x2; y2l:=y2; loop i::=1.upto!(step); -- Followings are scaled ``step''. -- Bezier curve of order 2. -- $p(t)=(1-t)^2 p0 + 2t(1-t) p1 + t^2 p2$ s:=i; s1:=step-s; s0:=s1*s1; s1:=s*s1; s1:=s1+s1; s2:=s*s; x1:=((s0*x0l+s1*x1l+s2*x2l)/ step2); y1:=((s0*y0l+s1*y1l+s2*y2l)/ step2); KNOTXW::DrawLine(x0, y0, x1, y1, col); x0:=x1; y0:=y1; end; end; next(Bridge:KNOT, inout x0, inout y0, inout x1, inout y1, inout x2, inout y2, fi:INT) is x0:=x2; y0:=y2; x1:=Bridge[fi].x; y1:=Bridge[fi].y; x2:=(Bridge[fi+1].x+x1)/ 2; y2:=(Bridge[fi+1].y+y1)/ 2; end; flush(inout Bridge:KNOT,col:INT) is -- display bridge x0,x1,x2, y0,y1,y2:INT; fi:INT; if DRAW_ALG::smoothDraw then Bridge.append(Bridge[1].x,Bridge[1].y); fi:=0; next(Bridge,inout x0,inout y0,inout x1,inout y1,inout x2,inout y2,fi); loop fi:=1.upto!(Bridge.length-3); next(Bridge,inout x0,inout y0,inout x1,inout y1,inout x2,inout y2,fi); Bezier(x0, y0, x1, y1, x2, y2,col); end; fi:=Bridge.length-2; next(Bridge,inout x0,inout y0,inout x1,inout y1,inout x2,inout y2,fi); if (Bridge[0].x=x1)and(Bridge[0].y=y1) then Bezier(x0, y0, x1, y1, x2, y2, col); else KNOTXW::DrawLine(x0, y0, x1, y1, col); fi:=0; -- draw 1st segment next(Bridge,inout x0,inout y0,inout x1,inout y1,inout x2,inout y2,fi); KNOTXW::DrawLine(x1, y1, x2, y2, col); end; else loop fi:=0.upto!(Bridge.length-2); KNOTXW::DrawLine(Bridge[fi].x,Bridge[fi].y, Bridge[fi+1].x,Bridge[fi+1].y,col); end; end; Bridge:=#; end; DrawKnot(Knot:KNOT) is col:INT; (* current line width/color*) i,band_sgn1,band_sgn2:INT; gx0, gx1, gy0, gy1:INT; px0, py0, px1, py1:INT; firstK:BOOL; fPos:INT; -- #OUT+"DrawKnot:\n"; Knot.checkKnot; Bridge:KNOT:=#; fBridge:KNOT:=#; KNOTXW::ClearWindow; i:=0; loop if ((i+1)>Knot.length) or VERTEXC::endc.in(Knot[i].sep ) then break!; end; Knot[i].work:=0; gx0:=gx1; gy0:=gy1; gx1:=Knot[i+1].x; gy1:=-Knot[i+1].y; if DRAW_ALG::markVertex and VERTEXC::normal.in(Knot[i].sep) then DRAW_ALG::circleK(Knot,i,0,1,col); end; if VERTEXC::separator.in(Knot[i].sep) then -- start point of a string if VERTEXC::gs.in(Knot[i].sep) then firstK:=true; col:=KNOTX::kStr; elsif VERTEXC::ks.in(Knot[i].sep) then firstK:=true; col:=KNOTX::kStr; elsif VERTEXC::ts.in(Knot[i].sep) then firstK:=false; col:=KNOTX::tStr; if Knot.is_coherent(i) then col:=KNOTX::tStr; else col:=KNOTX::rtStr; end; end; i:=i+1; elsif VERTEXC::separator.in(Knot[i+1].sep) then --end of the string if VERTEXC::ge.in(Knot[i+1].sep) then DRAW_ALG::circleF(Knot,i,4,col); elsif VERTEXC::ks.in(Knot[i-1].sep) then DRAW_ALG::circleK(Knot,i,0,3,col); --first point of ``AddCompo'' elsif VERTEXC::ke.in(Knot[i+1].sep) then if firstK then -- The component has no under crossings. Bridge.append(gx0, gy0); else if (gx0/=fBridge[0].x)or(gy0/=fBridge[0].y) then Bridge.append(gx0,gy0);flush(inout Bridge,col); end; fPos:=-1; Bridge.append(fBridge); end; flush(inout Bridge,col); else --te:end of band Bridge.append(gx0, gy0); flush(inout Bridge,col); end; i:=i+2; --jump the end code and go to start code of next string else px0:=gx0; py0:=gy0; px1:=gx1; py1:=gy1; if VERTEXC::under.in(Knot[i+1].sep) then DRAW_ALG::sl(px0, py0,inout px1,inout py1, 7); end; if VERTEXC::under.in(Knot[i].sep) then DRAW_ALG::sl(px1, py1,inout px0,inout py0, 7); elsif VERTEXC::ks.in(Knot[i-1].sep) or VERTEXC::ts.in(Knot[i-1].sep) then arrowS(gx0, gy0, gx1, gy1,col); -- start point elsif VERTEXC::band.in(Knot[i].sep) then DRAW_ALG::circleK(Knot,i,0,4,KNOTX::kMark); end; Bridge.append(px0, py0); if VERTEXC::under.in(Knot[i+1].sep) or VERTEXC::band.in(Knot[i+1].sep) then Bridge.append(px1, py1); if firstK then fBridge:=Bridge; firstK:=false; Bridge:=#; else flush(inout Bridge,col); end; end; i:=i+1; end; end; -- Knot.checkCode; end; ChangeScreen(Knot:KNOT, latticeFlg:BOOL) is -- writePage:=WPCh-writePage; Screen(Mode, 0, writePage, dispPage); DrawKnot(Knot); if latticeFlg then DRAW_ALG::DrawLattice; end; -- dispPage:=DPCh-dispPage; Screen(Mode, 0, writePage, dispPage); end; ResetPage(Knot:KNOT) is KNOTXW::WindowSw(0); DrawKnot(Knot); KNOTXW::FlushPixel; KNOTXW::WindowSw(1); -- ChangeScreen(false); -- REPEAT;ChangeScreen(false);UNTIL writePage=Wp1; end; end; -- DRAWKNOT_ALG