ndata.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
--
-- c.f.
--  n-data for links:
--  Masaaki WADA. "CODING LINK DIAGRAMS".
--
-- Copyright (C) 1992 1996 Kouji KODAMA
-- 1998/4 K.Kodama History
-- 1996/10 K.Kodama LINUX version
-- 1992/10/12
--  k49c 49 crossing Pretzel Knot [9,9,9,9,9,3,1]
--  Knot2NData: 6.987 sec
--  WriteNData: 3.363 sec
--  readNData : 3.796 sec
--  NData2Knot: 0.826 sec
-- 1992/10/10
--  k49c 49 crossing Pretzel Knot [9,9,9,9,9,3,1]
--  Knot2NData: 12.172 sec
--  WriteNData: 3.363 sec
--  readNData : 3.796 sec
--  NData2Knot: 0.826 sec
--NData: K49C
--n1 n3 n5 n3 n7 n9 2n11 2n13 r6 r18 r2 r16 r8 r4 r12 r10 r14 u7 u13
--u7 2u5 u7 u5 u3 4n3 n9 n3 n9 n3 r10 r14 r18 r8 r16 r6 r4 r2 r12 u3
-- u5 u3 u7 u9 3u3 n3 n5 n3 n9 n5 n13 n3 n5 r10 r14 r8 r16 r4 r18 r2
-- r6 r12 u17 u9 u11 u9 2u3 u5 u3 4n3 n7 n3 n5 n3 r18 r16 r8 r10 r12
-- r14 r2 r4 r6 u17 u15 u7 u11 u5 u3 u5 u3 3n3 n5 n3 3n7 r18 r16 r14
-- r12 r10 r6 r8 r4 r2 u13 u15 u13 2u9 u3 u5 u3 2n3 r4 r2 r6 2u3 r2 u3 u1
-- 49 crossing
-- 140 Code
-- 405 char
-- max:
-- 49 crossing
-- maxC*4 = 200 code
-- (code)*3 =600 char
-- 1992/10 Kouji KODAMA
--  NData --> Knot Diagram.



class NCODE

class NCODE is attr typ:INT; attr str:CARD; -- str-th string attr index:CARD; -- braid/ndata index attr pos:INT; -- height -- attr weight:INT; -- work -- types -- const tw:=0;-- empty/work const tz:=1;-- terminator const tn:=2;-- code n const tu:=3;-- code u const tr:=4;-- code r const tl:=5;-- code l create:SAME is res:SAME:=new; res.typ:=tw; res.str:=0; res.index:=0; res.pos:=0.int; return res; end; create(t:INT, s:CARD):SAME is res:SAME:=new; res.typ:=t; res.str:=s; res.index:=0; res.pos:=0.int; return res; end; clone:SAME is res:NCODE:=#; res.typ:=typ; res.str:=str; res.index:=index; res.pos:=pos; return res; end; end; -- class NCODE

class NDATA

class NDATA is attr nd:ARRAY{NCODE}; create:SAME is res:SAME:=new; res.nd:=#(1); res.nd[0]:=#(NCODE::tz,0); return res; end; clone:SAME is res:SAME:=#; res.nd:=#(nd.size); loop i::=nd.ind!; res.nd[i]:=nd[i].clone; end; return res; end; size:CARD is return nd.size; end; aget(i:CARD):NCODE is return nd[i]; end; aset(i:CARD, v:NCODE) is nd[i]:=v; end; aget(i:INT):NCODE is return nd[i.card]; end; aset(i:INT, v:NCODE) is nd[i.card]:=v; end; append(ncode:NCODE) is -- append ncode at the end of self. nd:=nd.resize(nd.size+1); if nd.has_ind(nd.size-2) and nd[nd.size-2].typ=NCODE::tz then nd[nd.size-1]:=nd[nd.size-2]; nd[nd.size-2]:=ncode; else nd[nd.size-1]:=ncode; end; end; append(Type:INT,String:CARD) is append(#NCODE(Type,String)); end; printD is -- print for debug/check #OUT+"NDATA\n"; #OUT+NDATA2STR::N2S(self)+"\n"; end; check:BOOL is if void(self) then return false; elsif void(nd) then return false; elsif nd.size=0 then return false; elsif nd[nd.size-1].typ/=NCODE::tz then return false; end; ind::=0; loop i::=nd.ind!; case nd[i].typ when NCODE::tn then if (nd[i].str<=0)or(nd[i].str>(ind+1)) then return false; end; ind:=ind+2; when NCODE::tu then if (nd[i].str<=0)or(nd[i].str>=ind) then return false; end; ind:=ind-2; when NCODE::tr then if (nd[i].str<=0)or(nd[i].str>=ind) then return false; end; when NCODE::tl then if (nd[i].str<=0)or(nd[i].str>=ind) then return false; end; when NCODE::tz then if ind/=0 then return false; end; if i/=(nd.size-1) then return false; end; when NCODE::tw then ; else return false; end; end; return true; end; setIndex:BOOL is if ~check then #OUT+"setIndex: check error\n"; return false; end; ind::=0; loop i::=nd.ind!; case nd[i].typ when NCODE::tn then if nd[i].str>(ind+1) then #OUT+"setIndex: error tn\n"; return false; end; ind:=ind+2; nd[i].index:=ind; when NCODE::tu then if nd[i].str>=ind then #OUT+"setIndex: error tu\n"; return false; end; nd[i].index:=ind; ind:=ind-2; when NCODE::tr then if nd[i].str>=ind then #OUT+"setIndex: error tr\n"; return false; end; nd[i].index:=ind; when NCODE::tl then if nd[i].str>=ind then #OUT+"setIndex: error tl\n"; return false; end; nd[i].index:=ind; when NCODE::tz then if ind/=0 then #OUT+"setIndex: error tz\n"; return false; end; nd[i].str:=0; nd[i].index:=ind; when NCODE::tw then nd[i].index:=ind; else #OUT+"setIndex: unknown code\n"; return false; end; end; return true; end; initPos:BOOL is -- Set pos: position on diagram if size<=0 then return false; end; loop i::=nd.ind!; nd[i].pos:=i.int; end; return true; end; end; -- class NDATA is

class NDATA2STR

class NDATA2STR is ------------------- NDATA --> STR ------------- private addS(inout wordStr:STR, ite:CARD, mark:STR, strnum:CARD) is if ite>1 then wordStr:=wordStr+ite.str; end; wordStr:=wordStr+mark+strnum.str+" "; end; N2S(NData:NDATA):STR is mark:STR; wordStr::=""; ite::=1; loop wi::=NData.nd.ind!; if NData.nd.has_ind(wi+1) and (NData[wi].str=NData[wi+1].str) and (NData[wi].typ=NData[wi+1].typ) then ite:=ite+1; else case NData[wi].typ when NCODE::tn then mark:="n"; addS(inout wordStr, ite, mark, NData[wi].str); ite:=1; when NCODE::tu then mark:="u"; addS(inout wordStr, ite, mark, NData[wi].str); ite:=1; when NCODE::tr then mark:="r"; addS(inout wordStr, ite, mark, NData[wi].str); ite:=1; when NCODE::tl then mark:="l"; addS(inout wordStr, ite, mark, NData[wi].str); ite:=1; when NCODE::tz then mark:="endcode "; ite:=1; wordStr:=wordStr+mark; when NCODE::tw then mark:="w"; addS(inout wordStr, ite, mark, NData[wi].str); ite:=1; else mark:="?";-- Unknown code wordStr:=" endcode "; return wordStr; end; if (wi+1).mod(10)=0 then wordStr:=wordStr+"\n"; end; end; end; return wordStr; end; NData2Str(NData:NDATA, out wordStr:STR):BOOL is if ~NData.check then #OUT+"NData2Str: failed to convert ndata to str.\n"; wordStr:=" endcode ";return false; end; wordStr:=N2S(NData); return true; end; end; -- class NDATA2STR

class STR2NDATA

class STR2NDATA is ---------------- STR --> NDATA ------------- errMsg(n:CARD) is #OUT+"Str2NData: Cannot parse the NDATA expression.("+n.str+")\n"; end; Str2NData(wordStr:STR, out NData:NDATA):BOOL is strnum:INT; wstr, typeC:STR; if wordStr.size<1 then return false; end; sc::=wordStr.cursor; NData:=#; ip::=0; ite:INT:=1.int; loop -- parse wordStr if sc.is_done then errMsg(1); NData:=#; return false; end; wstr:=STRINGSK::splitStr(inout sc); -- if wstr="endcode" then if ~NData.check then errMsg(2); NData:=#; return false; end; return NData.setIndex; end; ip:=0; if ~STRINGSK::Str2Int(wstr,inout ip,inout ite) then ite:=1.int; end; if ite.is_non_pos then errMsg(3); NData:=#; return false; elsif ite>1.int then if sc.is_done then errMsg(4); NData:=#; return false; end; typeC:=STRINGSK::splitStr(inout sc); -- else typeC:=wstr; end; if sc.is_done then errMsg(5); NData:=#; return false; end; wstr:=STRINGSK::splitStr(inout sc); -- ip:=0; if ~STRINGSK::Str2Int(wstr,inout ip,inout strnum) then errMsg(6); NData:=#; return false; end; loop ite.times!; case typeC when "n" then NData.append(#NCODE(NCODE::tn,strnum.card)); when "u" then NData.append(#NCODE(NCODE::tu,strnum.card)); when "r" then NData.append(#NCODE(NCODE::tr,strnum.card)); when "l" then NData.append(#NCODE(NCODE::tl,strnum.card)); else errMsg(7); NData:=#; return false; end; end; end; end; end; -- class STR2NDATA

class NDATA2KNOT

class NDATA2KNOT is -------------NData[] --> Knot[] --------------------- findStart(NData:NDATA, KTbl:ARRAY{BOOL}, out wi:CARD):BOOL is --search start point of a component -->wi wi:=0; loop if NData[wi].typ=NCODE::tz then return false; end; if (NCODE::tn=NData[wi].typ )and(~KTbl[wi]) then return true; end; wi:=wi+1; end; end; searchNext(NData:NDATA, inout wi:CARD, dir0:INT, str0:CARD):BOOL is -- search next code loop wi:=(wi.int+dir0).card; if ~NData.nd.has_ind(wi) then return false; end; case NData[wi].typ when NCODE::tn, NCODE::tu then break!; when NCODE::tr, NCODE::tl then if (NData[wi].str=str0)or(NData[wi].str+1=str0) then break!; end; end; end; return true; end; setStr1(NData:NDATA, wi:CARD, dir0:INT, inout str0:CARD, inout dir1:INT, inout str1:CARD, inout ofs:INT) is -- wi,dir0,str0 ---> str0,dir1,str1,ofs dir1:=dir0; str1:=str0; ofs:=1.int; if dir0=1.int then case NData[wi].typ when NCODE::tn then if NData[wi].str>str0 then str0:=str0+1; ofs:=-1; else str1:=str0+2; str0:=str0+1; end; when NCODE::tu then if NData[wi].str>=str0 then if NData[wi].str=str0 then str1:=str0+1; dir1:=-1; end; else ofs:=-1; if NData[wi].str+1=str0 then str1:=str0-1; dir1:=-1; else str1:=str0-2; end; end; when NCODE::tr, NCODE::tl then if NData[wi].str=str0 then str1:=str0+1; else ofs:=-1; str1:=str0-1; end; end; else -- dir=-1 case NData[wi].typ when NCODE::tu then if NData[wi].str>str0 then str0:=str0+1; ofs:=-1; else str1:=str0+2; str0:=str0+1; end; when NCODE::tn then if NData[wi].str>=str0 then if NData[wi].str=str0 then str1:=str0+1; dir1:=1; end; else ofs:=-1; if NData[wi].str+1=str0 then str1:=str0-1; dir1:=1; else str1:=str0-2; end; end; when NCODE::tr, NCODE::tl then if NData[wi].str=str0 then str1:=str0+1; else ofs:=-1; str1:=str0-1; end; end; end; end; shared str0:CARD; --current str. shared str1: CARD; shared pos0: INT; -- current pos. shared dir0:INT; -- current dir= -1/ 1 shared dir1:INT; shared ofs:INT; -- slope shared v0,v1,v2,p0,scale:VERTEXK; setPts(NData:NDATA,wi:INT) is -- x0:=px0+(pos0*2+1-dir0)*xscale; -- y0:=py0+(str0*2 -index )*yscale; -- x1:=px0+(pos0*2+1+dir0)*xscale; -- y1:=py0+((str0+ofs)*2 -index )*yscale; -- x2:=(x0+x1) DIV 2; -- y2:=(y0+y1) DIV 2; vd:VERTEXK:=scale.transform(dir0,ofs); v0:=scale.transform(pos0*2+1-dir0, str0.int*2.int -NData[wi].index.int)+p0; v2:=v0+vd; v1:=v2+vd; --x2:=px0+(pos0*2+1)*xscale; x0:=x2-d; x1:=x2+d; --y0:=py0 + (str0*2 -NData[wi].index )*yscale; y2:=y0+o; y1:=y2+o; end; PointInPt2(NData:NDATA,inout Knot:KNOT,wi1:CARD,dir0:INT,str1:CARD,pos0,ofs:INT,v:VERTEXK, inout pt:CARD,inout needPt0:BOOL) is -- check the condition of the next code, -- then set (x1,y1) to Knot[] if needed -- and set "needPt0" be true if (x0,y0) of the next code is needed. -- --> needPt0. le, ge, og:BOOL; if NData[wi1].pos=pos0+dir0 then needPt0:=false; le:=NData[wi1].str<=str1; ge:=NData[wi1].str>=str1; og:=(ofs=1.int); case NData[wi1].typ when NCODE::tn then if dir0=1.int then --if (NData[wi1].str>str1) and (ofs=-1) then --elsif (NData[wi1].str<=str1)and(ofs=1) then --else Knot.CodeIn(x, y, pt); pt:=pt+1; ; --end; if le/=og then Knot.CodeIn(v, pt); pt:=pt+1; end; else -- dir0=-1 --if (NData[wi1].str>=str1) and (ofs=1) then --elsif (NData[wi1].str < str1) and (ofs=-1) then --else Knot.CodeIn(x, y, pt); pt:=pt+1; ; --end; if ge/=og then Knot.CodeIn(v, pt); pt:=pt+1; end; end; when NCODE::tu then if dir0=1.int then --if (NData[wi1].str>=str1) and (ofs=1) then --elsif (NData[wi1].str < str1) and (ofs=-1) then --else Knot.CodeIn(x, y, pt); pt:=pt+1; ; --end; if ge/=og then Knot.CodeIn(v, pt); pt:=pt+1; end; else -- dir0=-1 --if (NData[wi1].str>str1)and(ofs=-1) then --elsif (NData[wi1].str<=str1)and(ofs=1)then --else Knot.CodeIn(x, y, pt); pt:=pt+1; ; --end; if le/=og then Knot.CodeIn(v, pt); pt:=pt+1; end; end; when NCODE::tr, NCODE::tl then if (NData[wi1].str=str1)and og then ; elsif (NData[wi1].str+1 =str1)and (~og) then ; else Knot.CodeIn(v, pt); pt:=pt+1; end; end; else Knot.CodeIn(v, pt); pt:=pt+1; needPt0:=true; end; end; PointInCr(inout Knot:KNOT,inout tp:CARD, OverSw:BOOL) is Knot.CodeIn(v2, tp); if (str1>str0)=OverSw then Knot[tp].sep:=VERTEXC::cross_over; else Knot[tp].sep:=VERTEXC::cross_under; end; tp:=tp+1; end; errMsg(n:CARD) is #OUT+"NData2Knot: failed to convert ndata to knot.("+n.str+")\n"; end; NData2Knot(ndata:NDATA, inout Knot:KNOT):BOOL is wi, tp:CARD; -- wi, dir0/1, str0/1, pos0, ofs ,x , y, tp if ndata.size=0 then Knot:=#; return true; end; if ~ ndata.check then errMsg(1); return false; end; NData:NDATA:=ndata.clone; if ~ NData.initPos then errMsg(2);return false; end; if ~ NData.setIndex then errMsg(3);return false; end; maxWidth:INT:=0.int; maxDepth:INT:=0.int; KTbl:ARRAY{BOOL}:=#(NData.size); -- false: not used. true: used. loop wi:=NData.nd.ind!; KTbl[wi]:=false; maxWidth:=maxWidth.max(NData[wi].index.int); maxDepth:=maxDepth.max(NData[wi].pos); end; screenX::=KNOTXW::GraphWidth-20; screenY::=KNOTXW::GraphHeight-20; scale:=#(screenX.div((maxDepth+1)*2.int),screenY.div((maxWidth-1)*2.int)); scale:=scale.max(2.int,2.int).min(20.int,20.int); -- xscale:=screenX.div((maxDepth+1)*2); xscale:=xscale.max(2).min(20); -- yscale:=screenY.div((maxWidth-1)*2); yscale:=yscale.max(2).min(20); if (scale.y*100.int)>(scale.x*140.int) then scale.y:=(scale.x*140.int+50)/100.int; end; if (scale.x*100.int)>(scale.y*140.int) then scale.x:=(scale.y*140.int+50)/100.int; end; p0:=#(screenX/2.int -(maxDepth+1)*scale.x, -screenY/2.int -scale.y); needPt0:BOOL; -- true if needed to set Pt0 at the next code Knot:=#; tp:=0; wi:=0; loop while!(findStart(NData,KTbl,out wi)) ; KTbl[wi]:=true; Knot.CodeIn(0.int, 0.int,VERTEXC::knot_s, tp); tp:=tp+1; Knot.CodeIn(0.int, 0.int,VERTEXC::knot_e, tp); dir0:=-1; str0:=NData[wi].str+1; pos0:=NData[wi].pos; setStr1(NData,wi,dir0,inout str0,inout dir1,inout str1,inout ofs); setPts(NData,wi.int); Knot.CodeIn(v2, tp); tp:=tp+1; v1:=#(v0.x,v1.y); loop if ~searchNext(NData,inout wi,dir1,str1) then errMsg(4);return false; end; PointInPt2(NData,inout Knot,wi,dir1,str1,pos0,ofs,v1,inout tp,inout needPt0); dir0:=dir1; str0:=str1; pos0:=NData[wi].pos; setStr1(NData,wi,dir0,inout str0,inout dir1,inout str1,inout ofs); setPts(NData,wi.int); if needPt0 then Knot.CodeIn(v0, tp); tp:=tp+1; end; if dir0=1.int then case NData[wi].typ when NCODE::tu then if dir1=-1 then Knot.CodeIn(v2, tp); tp:=tp+1; v1:=#(v0.x,v1.y); end; when NCODE::tn then ; when NCODE::tr then PointInCr(inout Knot,inout tp,false); when NCODE::tl then PointInCr(inout Knot,inout tp,true); end; else --dir0=-1 case NData[wi].typ when NCODE::tn then if dir1=1.int then Knot.CodeIn(v2, tp); tp:=tp+1; v1:=#(v0.x,v1.y); if KTbl[wi] then tp:=tp+1; break!; end; -- end of the component KTbl[wi]:=true; end; when NCODE::tu then ; when NCODE::tr then PointInCr(inout Knot,inout tp,true); when NCODE::tl then PointInCr(inout Knot,inout tp,false); end; end; end; end; Knot.concat; Knot.edge_clean; Knot.shiftToInside; return true; end; end; -- class NDATA2KNOT

class KNOT2NDATA

class KNOT2NDATA is ----------------- Knot[] --> NData[] -------------------------- -- Note. -- Let -- p: prime (> maxY) -- q: (p,q)=1 (coprime). -- r: rx= p*x+q*y -- ry= y --then -- for points (x1,y1) and (x2,y2), -- if rx1=rx2 then x1=x2, y1=y2. --Because, x and y are integer. --This means that -- points in RKnot[] have difference x-coordinates each other. --The following is the FLT version of the above. --Let -- delta=0.05; -- theta0=0.0003 ( < 1/screenDepth ) -- + delta; --r: --rx = x +theta*y --ry = y x_is_lt(Knot:KNOT, i,j:CARD):BOOL is -- sorting order return Knot[i].x < Knot[j].x; end; checkRegular(inout Knot:KNOT, inout SortX:ARRAY{CARD}):BOOL is --Check if Knot[] is in a standard/regular position. --Especially, it check condition around crossing points. --And it make a table of critical points SortX[]. kp, kp1, sp, i:CARD; fp:BOOL; kp:=1; -- start of compo kp1:=Knot.cmpOf(kp.int-1).card-2; -- back 1 vertex loop fp:=(Knot[kp].x<Knot[kp1].x)=(Knot[kp].x<Knot[kp+1].x); if VERTEXC::crossing.in(Knot[kp].sep) then -- tr or tl SortX:=SortX.resize(SortX.size+1); SortX[SortX.size-1]:=kp; if fp then return false; --check crossing condition be regular end; else -- Now, normal.in(Knot[].sep) --SortX[] contains critical pts. only. --So it is tn or tu. if fp then -- tn or tu SortX:=SortX.resize(SortX.size+1); SortX[SortX.size-1]:=kp; end; end; -- move to next vertex if VERTEXC::separator.in(Knot[kp+2].sep) then kp:=kp+4; -- head of next component if kp>=Knot.length then break!; end; kp1:=Knot.cmpOf(kp.int-1).card-2; else kp1:=kp; kp:=kp+1; end; end; lt:ROUT{CARD,CARD}:BOOL:=bind(x_is_lt(Knot,_,_)); SortX.insertion_sort_by(lt); -- check if coord of each vertex be unique up to crossings. --I assumed that the diagram be regular projection. --Not needed the following checker of regularity on vertices. -- Because, Knot[], knot in new coordinate is in regular position. --loop sp:=0.upto!(SortX.size-2); -- if (Knot[SortX[sp]].x=Knot[SortX[sp+1]].x) and -- (Knot[SortX[sp]].y/=Knot[SortX[sp+1]].y) -- then return false; -- end; --end; return true; end; rotToNormal(inout Knot:KNOT, inout SortX:ARRAY{CARD}):BOOL is -- p be prime>(knot Height) and not overflow on p*(knot x coord) maxX,minX,maxY,minY:INT; Knot.width(out minX,out maxX,out minY,out maxY); p:INT:=(maxY-minY)+1; if p.is_even then p:=p+1; end; loop until!(p.is_prime); p:=p+2; end; -- (p,q)=1 coprime q:INT:=1; loop until!(p.gcd(q)=1.int); q:=q+1; end; -- prepare for "SortRecords" and compare -- delta is a divisor of q, and $(p,q)=1$. Knot.transform(p,q,0.int,1.int); if ~checkRegular(inout Knot,inout SortX) then #OUT+"Cannot move to good position. (rotateToNormal)\n"; return false; -- cannot find a good position end; -- find a good position. -- Now, Knot[] is in normal position. -- And we can think a Morse function according Knot[] and SortX[]. return true; end; countLowerEdge(Knot:KNOT, kp:CARD):CARD is v0::=Knot[kp]; count::=0; k1::=1; loop v1::=Knot[k1]-v0; v2::=Knot[k1+1]-v0; if ((v1.x.is_pos)/=(v2.x.is_pos))and(v1.x.is_non_zero)and(v2.x.is_non_zero) then -- check the edge: y-coord if ( v1.y.is_pos and v2.y.is_pos) then ; elsif ( v1.y.is_neg and v2.y.is_neg) then count:=count+1; elsif (v1.outer(v2).is_pos )=(v1.x<v2.x) then count:=count+1; -- if condition of slope --y1/x1 > y2/x2 when (x1<x2) --y1/x1 < y2/x2 when (x1>x2) --then line p1-p2 through under the point p0. end; end; -- move to next vertex if VERTEXC::separator.in(Knot[k1+2].sep) then k1:=k1+4; -- head of next component if k1>=Knot.length then break!; end; else k1:=k1+1; end; end; return count; end; makeNData(Knot:KNOT, SortX:ARRAY{CARD}, inout NData:NDATA):BOOL is wl, kp, kp1, kp2:CARD; tmp:CARD; -- Now, SortX[] is the sorted table of critical points -- and RKnot[] is unique in height function '.x' . -- So, we can use these as if a Morse function. NData:=#; wl:=0; loop sp::=SortX.ind!; kp:=SortX[sp]; if VERTEXC::crossing.in(Knot[kp].sep) and (Knot.cmpOf(kp.int)=SortX[sp+1].int) then -- crossing tr/tl kp1:=kp+1; if Knot[kp].x<Knot[kp1].x then kp1:=kp1-2; end; kp2:=SortX[sp+1]+1; if Knot[kp].x<Knot[kp2].x then kp2:=kp2-2; end; if ~VERTEXC::over.in(Knot[kp].sep) then tmp:=kp1; kp1:=kp2; kp2:=tmp; end; if Knot[kp].outer(Knot[kp1],Knot[kp2]).is_pos then NData.append(NCODE::tr,countLowerEdge(Knot,kp)+1); else NData.append(NCODE::tl,countLowerEdge(Knot,kp)+1); end; elsif VERTEXC::normal.in(Knot[kp].sep) then -- SortX[] contains critical pts. only. kp2:=kp+1; if Knot[kp].x<Knot[kp2].x then -- tn NData.append(NCODE::tn,countLowerEdge(Knot,kp)+1); else -- Knot[kp].x>Knot[kp2].x --tu NData.append(NCODE::tu,countLowerEdge(Knot,kp)+1); end; end; end; if NData[NData.size-1].typ/=NCODE::tz then NData.append(NCODE::tz,0); end; return NData.setIndex; end; errMsg(n:CARD) is #OUT+"Knot2NData: failed to convert knot to ndata.("+n.str+")\n"; end; Knot2NData(knot:KNOT, inout NData:NDATA):BOOL is NData:=#; if ~knot.is_proper then return false; end; if knot.has_band then #OUT+"Band is not supported.\n"; return false; end; if knot.CrossSet then ; end; KnotW:KNOT:=knot.clone; SortX:ARRAY{CARD}:=#; -- SortX is a list of critical points of a Morse function. -- It is a table of index of vertex and crossing pts. if ~rotToNormal(inout KnotW, inout SortX) then errMsg(1); elsif ~makeNData(KnotW,SortX,inout NData) then errMsg(2); end; return true; end; end; -- class KNOT2NDATA

class NDATA_CNV

class NDATA_CNV is shared packNData:BOOL;-- TRUE: reduce the diagram. Not implemented. Knot2NDataStr(Knot:KNOT, out strNData:STR):BOOL is if Knot.is_proper.not then strNData:=" endcode "; return false; end; NData:NDATA:=#; strNData:=" endcode "; k::=Knot.clone; k.transform(0.int,-1,1.int,0.int); reply:BOOL:=KNOT2NDATA::Knot2NData(k,inout NData); if ~ reply then strNData:=" endcode "; return false; end; reply:=NDATA2STR::NData2Str(NData,out strNData) and reply; -- Note that 'reply' is afterward return reply; end; NDataStr2Knot(strNData:STR, inout Knot:KNOT):BOOL is --#OUT+"NDataStr2Knot:1 \n"; NData:NDATA:=#; HISTORY::put(Knot.clone); reply:BOOL:=STR2NDATA::Str2NData(strNData,out NData); if NData.size>0 then reply:=reply and NDATA2KNOT::NData2Knot(NData,inout Knot); Knot.transform(0.int,1.int,-1,0.int); else Knot:=#; end; if ~reply then HISTORY::back(inout Knot); end; return reply; end; SetNDiagram(inout Knot:KNOT) is str:STR; if Knot2NDataStr(Knot,out str) and NDataStr2Knot(str,inout Knot) then; end; end; end; -- class NDATA_CNV