!! File: WaveSums.68k !! Sept 13, 2003, Hubert Hohn for Haynes Miller, MIT PUBLIC PCFlag,Mac5Flag,M68KFlag,UnixFlag,xmax,ymax PUBLIC toolLft,toolRgt,toolBas,toolTop,toolhdr,toolHgt,toolWid ! tool boundaries PUBLIC winLft,winRgt,winBas,winTop,winHgt,winWid ! window PUBLIC workLft,workRgt,workBas,workTop,workMidx ! work area PUBLIC backclr,black,drkgry,drkmid,midgry,litmid,litgry,white PUBLIC red,yellow,green,cyan,blue,magenta,pink,colorscheme PUBLIC planeclr,gridclr,rimclr,axisclr,axislabelclr,titleclr,rightsclr PUBLIC numberlineclr,slotdrkclr,slotlgtclr,slideclr PUBLIC largefonts, title$, SLUmode LET toolHgt= 560 LET toolWid= 780 LET window$= "The d'Arbeloff Interactive Math Project" LET colorscheme= 0 LET title$ = "Wave Sums" SUB ThisProgram CALL WaveSums CLEAR END SUB !! --------------------------------------------------------- !! ------ Start TB4 Mac Header and Subs ------ !LET M68KFlag = 1 !LIBRARY "MacTools*", "HHLib.trc" !ASK PIXELS winWid,winHgt !LET winLft= 0 !LET winTop= 0 !LET winRgt= winWid-1 !LET winBas= winHgt-1 !SET WINDOW 0,winRgt,winBas,0 !CALL Palette !CLEAR ! !CALL ToolPanel !CALL ThisProgram ! !END !EXTERNAL ! !MODULE Mac4Parts ! SUB SetTextFont(font,size,style$) ! CALL MacTextFont(font) ! CALL MacTextSize(size) ! CALL MacTextFace(style$) ! END SUB ! ! SUB StringWidth(sw$,sl) ! DECLARE DEF MacStringWidth ! LET sl= MacStringWidth(sw$) ! END SUB ! ! SUB SetLineWeight(wgt) ! CALL MacPenSize(wgt,wgt) ! END SUB ! ! SUB BoxDisk(Lft,Rgt,Bas,Top) ! CALL MacPaintOval(Lft,Rgt,Bas,Top) ! END SUB !END MODULE !! --- End TB4 Mac Header and Subs --- !!--------------------------------------------------------- !!--- Start TB5 Cross-Platform header and subs --- LIBRARY "c:\TB Gold\TBLibs\TrueCtrl.trc" ! windows LIBRARY "c:\TB Gold\TBLibs\HHLib.trc" !LIBRARY ":TBLibs:TrueCtrl.trc" ! macintosh !LIBRARY "HHLib.trc" ! PUBLIC WinID DECLARE PUBLIC OBJM_SET,OBJM_SYSINFO LET winHgt= toolHgt LET winWid= toolWid DIM values(1) CALL TC_Init CALL Object(OBJM_SYSINFO,WinID,"MACHINE",system$,values()) IF system$="MAC" then LET Mac5Flag= 1 ELSE IF system$="WIN32" then LET PCFlag = 1 END IF CALL TC_SetUnitsToPixels ! 5.1 and up needs this CALL TC_GetScreenSize(scrnLft,scrnRgt,scrnBas,scrnTop) LET winLft= int((scrnRgt-scrnLft-winWid)/2) LET winRgt= winLft+winWid-1 LET winTop= int((scrnBas-scrnTop-winHgt)/2) + 10 LET winBas= winTop+winHgt-1 CALL TC_Win_Create (WinID,"TITLE",winLft,winRgt,winBas,winTop) LET values(1)= 2 CALL Object(OBJM_SET, WinID, "TYPE", "", values()) IF PCFlag=1 then ! kill dithering LET values(1)= 1 CALL Object(OBJM_SET, WinID, "SOLID MIX", "", values()) END IF LET values(1)= 0 CALL TC_SetRect(WinID,winLft,winRgt,winBas,winTop) CALL TC_Win_SetTitle(WinID,window$) CALL TC_Show(WinID) SET MODE "COLORSTANDARD" ASK PIXELS winWid,winHgt ! must follow set mode LET winLft= 0 LET winTop= 0 LET winRgt= winWid-1 LET winBas= winHgt-1 SET WINDOW 0,winRgt,winBas,0 CALL Palette IF PCFlag=1 then LET values(1)= 0 ! now force solid colors CALL Object(OBJM_SET, WinID, "SOLID MIX", "", values()) CALL TC_Win_RealizePalette(WinID) ! some PCs need this CALL TC_Win_SetFont(WinID,"arial",9,"plain") CALL StringWidth("0",sw) IF sw>7 then LET largefonts=1 else LET largefonts=0 END IF CALL TC_Win_Switch(WinID) CALL ToolPanel CALL ThisProgram CALL SetTextFont(1,12,"bold") ! now shut down and clean up LET quit$= "click the mouse or press a key to close..." CALL PlotTextCJ(workmidx,(workbas+worktop)/2,quit$,yellow) CALL TC_CleanUp END EXTERNAL MODULE TB5Parts SUB StringWidth(sw$,sl) DECLARE PUBLIC WinID LET sl= StrWidth(WinID,sw$) END SUB SUB SetLineWeight(wgt) DECLARE PUBLIC OBJM_SET DECLARE PUBLIC WinID DIM values(1) LET values(1)= wgt CALL Object(OBJM_SET,WinID, "WIDTH", "", values()) END SUB SUB SetTextFont(font,size,style$) DECLARE PUBLIC WinID,Mac5Flag,PCFlag,largefonts IF Mac5Flag=1 then SELECT CASE font CASE 4 LET font$= "Courier" CASE 16 LET font$= "Times" CASE else LET font$= "Geneva" END SELECT ELSE IF PCFlag=1 then IF largefonts=1 then IF size<12 then LET size= 6 ELSE IF size=14 then LET size= 10 ELSE IF size=18 then LET size= 12 ELSE IF size=24 then LET size= 14 ELSE IF size=12 then LET size= 8 ELSE LET size= round(72/96 * size * .8) END IF ELSE IF size<12 then LET size= 7 ELSE IF size=14 then LET size= 12 ELSE IF size=12 then LET size= 9 ELSE IF size=18 then LET size= 14 ELSE IF size=24 then LET size= 18 ELSE LET size= round(72/96 * size) END IF END IF SELECT CASE font CASE 4 LET font$= "Courier New" CASE 16 LET font$= "Times New Roman" CASE else LET font$= "Verdana" END SELECT END IF IF style$= "normal" then LET style$= "plain" CALL TC_Win_SetFont(WinID,font$,size,style$) END SUB SUB BoxDisk(Lft,Rgt,Bas,Top) BOX DISK Lft,Rgt,Bas,Top END SUB END MODULE ! --- End TB5 Cross-platform header and subs --- !! --------------------------------------------------------- !! --- Start Unix Header and Subs --- !LIBRARY "HHLib.trc" !LET UnixFlag= 1 !ASK PIXELS winWid,winHgt !LET winLft= 0 !LET winTop= 0 !LET winRgt= winWid-1 !LET winBas= winHgt-1 !SET WINDOW 0,winRgt,winBas,0 !CALL Palette ! !CALL ToolPanel !CALL ThisProgram ! !END !EXTERNAL ! !MODULE UnixParts ! SHARE CharWidth ! ! SUB SetTextFont(font,size,style$) ! LET font$= "-adobe-courier-" ! IF style$= "normal" then ! LET style$= "medium-r-normal--" ! ELSE ! LET style$= "bold-r-normal--" ! END IF ! IF size=9 then ! LET size$= str$(10) ! ELSE ! LET size$= str$(size) ! END IF ! LET test= SetFont(font$&style$&size$&"*") ! ! IF size=9 then ! LET CharWidth= 7 ! ELSE IF size=12 then ! numeric output - axis labels ! LET CharWidth= 8 ! ELSE IF size=14 then ! rare ! LET CharWidth= 9 ! ELSE IF size=18 then ! rare ! LET CharWidth= 10 ! END IF ! END SUB ! ! SUB StringWidth(sw$,sl) ! string width in pixels ! ! LET sl= StrWidth(sw$) ! LET chars= len(sw$) ! LET sl = chars*CharWidth ! END SUB ! ! SUB SetLineWeight(wgt) ! ! CALL PenSize(wgt,wgt) ! END SUB ! ! SUB BoxDisk(Lft,Rgt,Bas,Top) ! CALL Fill_Circle(Lft,Rgt,Bas,Top) ! END SUB !END MODULE !! ------ End of TB Unix Header and Subs ------ ! ----------------------------------------------------------- ! *** SUB WaveSums DECLARE PUBLIC black,drkgry,drkmid,midgry,litmid,litgry,white DECLARE PUBLIC red,yellow,green,cyan,blue,magenta,colorscheme DECLARE PUBLIC slideclr,axisclr,axislabelclr,true,false DECLARE PUBLIC workLft,workRgt,workBas,workTop,workMidx DECLARE DEF quitWithin,infoWithin ! --- help screen array --- DIM info$(1:12) MAT READ info$ DATA "Wave Sums" DATA "" DATA "This tool supports graphical exploration of the sum of two moving waves. The red wave moves to the right, the green wave moves to the left, and their sum is displayed in yellow." DATA "" DATA "The waves can be toggled on and off by clicking the check boxes for Left, Right, and Sum." DATA "Roll the mouse over the xt plane to display a vertical rule and its position as an angle in degrees." DATA "" DATA "Click the [v] popdown menu button to display the wave sum equations. Click one of the equations to select it." DATA "" DATA "Click or drag the t slider handle to set the time variable, and display the wave graphs for that time." DATA "Click the [<][>] step buttons to change t by .05. Click the [>>>] animation button to animate the motion." DATA "Click among the slider hash marks to jump to the nearest quarter pi." ! --- colors --- LET lftclr= green LET rgtclr= red LET sumclr= yellow ! ---------- Utility functions --- DECLARE DEF clamp,roundn,e ! --- functions - not used - replaced by vector list --- DECLARE DEF asin DEF ZigZag(x) LET n= sin(x) IF abs(n)<1 then LET ZigZag= atn(n/sqr(1-n*n)) ELSEIF n=1 then LET ZigZag= pi2 ELSEIF n=-1 then LET ZigZag= -pi2 END IF END DEF LET eq= 2 DEF f(x,t) ! wave from left IF eq=1 then LET f= sin(x+t) ELSE IF eq=2 then LET f= sin(x+t) ELSE IF eq=3 then LET f= ZigZag(x+t) END IF END DEF DEF g(x,t) ! wave from right IF eq=1 then LET g= sin(x-t) ELSE IF eq=2 then LET g= sin(2*x-t) ELSE IF eq=3 then LET g= ZigZag(x-t) END IF END DEF SUB Constants ! used to define vertices LET x1 = -pi LET y1 = 0 LET x8 = 2*pi LET y8 = 0 LET t2 = t*2 LET pi2 = pi*2 LET pid2= pi/2 LET pi3 = pi*3 LET x23 = -pi/2 LET x45 = pi/2 LET x67 = 3*pi/2 LET w1RollStep = pi/360 END SUB ! ----- design and layout - sizes and positions of interface ----- ! ------------ Graphing plane parameters and methods ------------- ! ------ plane 1 data ------ DECLARE PUBLIC w1Lft,w1Rgt,w1Bas,w1Top,w1Midx,w1Midy DECLARE PUBLIC w1fLft,w1fRgt,w1fBas,w1fTop,w1x0,w1y0 DECLARE PUBLIC w1xFirst, w1xSTik, w1xLTik, w1xLabel, w1xGridstep DECLARE PUBLIC w1yFirst, w1ySTik, w1yLTik, w1yLabel, w1yGridstep DECLARE PUBLIC w1wWid,w1wHgt,w1fWid,w1fHgt DECLARE PUBLIC w1fxRatio,w1fyRatio,w1wxRatio,w1wyRatio,w1Aspect DECLARE PUBLIC w1xPiFlag, w1xMult, w1yPiFlag, w1yMult LET w1Flag = 1 LET w1xPiFlag= 1 LET w1xMult = pi LET w1yPiFlag= 0 LET w1yMult = 1 LET w1Lft = workLft + 80 ! pixel bounds LET w1Rgt = w1Lft + 600 LET w1Top = workTop + 50 LET w1Bas = w1Top + 320 LET w1fLft= -1 ! function bounds LET w1fRgt= 2 LET w1fTop= 4 LET w1fBas= -4 LET w1xAx$= "t" ! axis labels LET w1yAx$= "x" LET w1xGridstep= 0 ! horizontal grid intervals LET w1yGridstep= 0 ! vertical grid intervals LET w1xSTik = 1/4 ! horizontal axis Tik marks LET w1xLTik = 1/2 LET w1xLabel= 1 LET w1xFirst= w1fLft LET w1ySTik = 0 ! vertical axis Tik marks LET w1yLTik = 1 LET w1yLabel= 1 LET w1yFirst= w1fBas ! ------ Plane 1 methods ------ DECLARE DEF w1fncx,w1fncy,w1wndx,w1wndy ! window/function transforms DECLARE DEF w1wWithin, w1Within CALL w1Variables DIM lftlist(0:1,0:1),rgtlist(0:1,0:1),sumlist(0:1,0:1) MAT redim lftlist(0:w1wWid,0:1),rgtlist(0:w1wWid,0:1),sumlist(0:w1wWid,0:1) SUB w1Init CALL w1DrawPlane(1,1,1) ! x axis, y axis, zeroaxes LET wx= w1Wndx(pi) CALL PlotLine( wx,w1Top+1, wx,w1Bas-1, drkmid) CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w1Rgt+8,w1y0+3,w1xAx$,axislabelclr) ! axis labels CALL PlotTextCJ(w1x0,w1Top-10,w1yAx$,axislabelclr) CALL w1KeepGridLayer END SUB ! ----------- horizontal sliders ------------ ! --- h1 horizontal slider --- ! --- h1 data --- DECLARE PUBLIC h1axis,h1wLft,h1wRgt,h1wBas,h1wTop,h1fLft,h1fRgt DECLARE PUBLIC h1name$,h1form$,h1clr,h1First,h1STik,h1LTik,h1Label DECLARE PUBLIC h1PiAxis,h1Mult,h1fMin,h1fMax LET h1PiAxis= 1 LET h1Mult = pi LET h1clr = white LET h1name$ = "t" LET h1form$ = "--%.##" LET h1Places= 2 LET h1axis = w1Bas + 24 LET h1wLft = w1Rgt - 400 LET h1wRgt = h1wLft + 400 LET h1fLft = 0 LET h1fRgt = 2 LET h1STik = 0.25 ! short tick marks LET h1LTik = 0.50 ! long tick marks LET h1Label = 0 ! labels LET h1First = 0 ! first tick mark LET h1Click = 0.25*pi ! tik mark click step LET h1AnimStep= .05 !pi/90 ! animation step LET h1fMin = 0 LET h1fMax = h1fRgt*h1Mult ! --- h1 methods --- DECLARE DEF h1Wndx,h1Within ! window/function transforms DECLARE DEF h1AnimWithin,h1AnimStopWithin DECLARE DEF h1LstpWithin,h1RstpWithin CALL h1SliderVariables SUB h1Init(t) CALL h1DrawSlider(h1name$,t) CALL h1AnimButtons END SUB ! ------- text boxes - t rollover -------- LET t1BasLn= w1Top-25 LET t1Top = t1BasLn-15 LET t1Bas = t1BasLn+ 5 LET t1Lft = w1Lft-30 LET t1Rgt = w1Rgt+30 LET t1Form$= "---%" SUB t1ValueSet(x) LET deg= 180*x/pi LET wx = w1Wndx(x) CALL t1ValueClear CALL PlotDegreesCJ(wx,t1BasLn,deg,litgry) END SUB SUB t1ValueClear BOX CLEAR w1Lft-30,w1Rgt+30,w1Top-20,w1Top-40 END SUB ! --- check boxes - graph switches --- DECLARE PUBLIC c1cnt, c1stp, c1siz DECLARE PUBLIC c1lft, c1rgt, c1bas, c1top DECLARE PUBLIC c1NameList$(),c1ColorList(),c1Switch() DECLARE DEF c1Within LET c1cnt= 3 ! box count LET c1top= h1wBas+40 LET c1lft= w1Lft CALL c1Variables MAT redim c1NameList$(1:c1cnt) DATA "Right","Left","Sum" MAT READ c1NameList$ MAT redim c1ColorList(1:c1cnt) DATA 23,25,24 ! 7, 9, 8 MAT READ c1ColorList MAT redim c1Switch(1:c1cnt) DATA 0, 0, 1 MAT READ c1Switch SUB c1Init CALL c1DrawCheckBoxes CALL c1SetCheckBox END SUB ! ----- popup menu parameters ----- DECLARE PUBLIC m1Lft, m1Rgt, m1Bas, m1Top, m1Equation, m1Prefix$, m1Menu1$(), m1tClr DECLARE DEF m1Within MAT redim m1Menu1$(1:3) MAT READ m1Menu1$ DATA "sin(x+t) + sin(x-t)" DATA "sin(x+t) + sin(2x-t)" DATA "zig zag" LET m1Prefix$ = "y = " LET m1Lft = h1wLft LET m1Top = h1wBas+40 LET m1tClr = yellow LET m1Equation= 1 ! ----- end of design and layout definitions ----- ! --- default parameters --- LET t= pi/4 CALL Constants LET eq,m1Equation= 2 ! --- Draw the screen --- CALL InitScreen CALL SetTimer ! tune timer to cpu CALL m1InitMenu1 SUB InitScreen BOX CLEAR worklft,workrgt,workbas,worktop CALL h1Init(t) ! slider CALL w1Init ! graph plane CALL c1Init ! check boxes IF eq=3 then CALL Graph(t) ELSE CALL SineGraphs(t) END IF CALL m1ResetMenu(menuState) ! CALL m1Init END SUB ! --------------- Main Event Manager Loop --------------- DO LET clearflag= 0 IF ms<>2 then ! if mouse not down DO GET MOUSE: mx,my,ms CALL w1RollOver(mx) LOOP until ms=2 ! mouse state - down? END IF IF clearflag=1 then CALL w1RollOverClear END IF IF h1Within(mx,my)=true then IF myoldmx then LET x= w1Fncx(mx) LET x= roundn(x,w1RollStep) ! step one degree CALL w1ShowGraphLayer ! show graph layer CALL PlotLine( mx,w1Top+1, mx,w1Bas-1, litgry) ! vertical rule CALL t1ValueSet(x) LET clearflag= 1 LET oldmx = mx END IF ELSE IF clearflag=1 then CALL w1RollOverClear END IF END SUB SUB w1RollOverClear CALL w1ShowGraphLayer ! show graph layer CALL t1ValueClear LET clearflag= 0 END SUB ! --- h1 slider event --- SUB h1MouseClick(ms) CALL h1GetClickVal(ms,h1Click,t) CALL h1Action END SUB SUB h1MouseDrag(ms) DO CALL h1GetDragVal(ms,h1Places,t) CALL h1Action LOOP until ms=3 END SUB SUB h1Action IF t<>oldt then IF eq=3 then CALL Graph(t) ELSE CALL SineGraphs(t) END IF LET oldt= t END IF END SUB ! --- h1 button event --- SUB Animate DO LET t= t + h1AnimStep LET t= mod(t,pi2) IF eq=3 then CALL Graph(t) ELSE CALL AnimateSineGraphs(t) END IF CALL h1Mark(t) GET MOUSE: mx,my,ms IF ms=2 then ! mouse down? CALL h1AnimStopButtonUp(ms) EXIT DO END IF CALL Delay(1/16) ! speed control LOOP CALL w1KeepGraphLayer END SUB ! --- Tool specific drawing and typesetting routines --- SUB SineGraphs(t) CALL w1ShowGridLayer IF c1Switch(1)=true then SET COLOR red FOR wx= w1Lft to w1Rgt step 2 LET x= w1Fncx(wx) LET y= f(x,t) PLOT wx,w1Wndy(y); NEXT wx PLOT END IF IF c1Switch(2)=true then SET COLOR green FOR wx= w1Lft to w1Rgt step 2 LET x= w1Fncx(wx) LET y= g(x,t) PLOT wx,w1Wndy(y); NEXT wx PLOT END IF IF c1Switch(3)=true then SET COLOR yellow FOR wx= w1Lft to w1Rgt step 2 LET x= w1Fncx(wx) LET y= f(x,t)+g(x,t) PLOT wx,w1Wndy(y); NEXT wx PLOT END IF CALL w1KeepGraphLayer END SUB SUB AnimateSineGraphs(t) CALL w1ShowGridLayer IF c1Switch(3)=true then SET COLOR yellow FOR wx= w1Lft to w1Rgt step 5 LET x= w1Fncx(wx) LET y= f(x,t)+g(x,t) PLOT wx,w1Wndy(y); NEXT wx PLOT END IF IF c1Switch(1)=true then SET COLOR red FOR wx= w1Lft to w1Rgt step 5 LET x= w1Fncx(wx) LET y= f(x,t) PLOT wx,w1Wndy(y); NEXT wx PLOT END IF IF c1Switch(2)=true then SET COLOR green FOR wx= w1Lft to w1Rgt step 5 LET x= w1Fncx(wx) LET y= g(x,t) PLOT wx,w1Wndy(y); NEXT wx PLOT END IF END SUB SUB Graph(t) ! calculates vertices and connects them ! faster than using a function to plot every pixel LET tpi= t LET t2 = tpi*2 IF tpi>=0 and tpi=pi/2 and tpi=pi and tpi=pi3/2 and tpi<=pi2 then ! t is 270 to 360 ! --- sum graph vertices LET tshift= tpi - pi2 LET yshift= round(pi3 - t2,6) LET y23= yshift LET x2 = x23 + tshift LET y2 = y23 LET x3 = x23 - tshift LET y3 = y23 LET y45= -yshift LET x4 = x45 + tshift LET y4 = y45 LET x5 = x45 - tshift LET y5 = y45 LET y67= y23 LET x6 = x67 + tshift LET y6 = y67 LET x7 = x67 - tshift LET y7 = y67 ! --- left moving graph vertices LET myshift= pi/2 - (tpi-3*pi/2) LET ly1= myshift LET lx2= x3 LET ly2= -pid2 LET lx3= x5 LET ly3= pid2 LET lx4= x7 LET ly4= -pid2 LET ly5= -myshift ! --- right moving graph vertices LET ry1= -myshift LET rx2= x2 LET ry2= -pid2 LET rx3= x4 LET ry3= pid2 LET rx4= x6 LET ry4= -pid2 LET ry5= myshift END IF ! ----- convert math vars to pixels ----- ! ----- sum graph LET wx1= w1Lft LET wy1= w1Wndy(0) CALL w1MathToPixels(x2,y2, wx2,wy2) CALL w1MathToPixels(x3,y3, wx3,wy3) CALL w1MathToPixels(x4,y4, wx4,wy4) CALL w1MathToPixels(x5,y5, wx5,wy5) CALL w1MathToPixels(x6,y6, wx6,wy6) CALL w1MathToPixels(x7,y7, wx7,wy7) LET wx8= w1Rgt LET wy8= w1Wndy(0) ! ----- left moving graph LET lwx1= w1Lft LET lwy1= w1Wndy(ly1) CALL w1MathToPixels(lx2,ly2, lwx2,lwy2) CALL w1MathToPixels(lx3,ly3, lwx3,lwy3) CALL w1MathToPixels(lx4,ly4, lwx4,lwy4) LET lwx5= w1Rgt LET lwy5= w1Wndy(ly5) ! ----- right moving graph LET rwx1= w1Lft LET rwy1= w1Wndy(ry1) CALL w1MathToPixels(rx2,ry2, rwx2,rwy2) CALL w1MathToPixels(rx3,ry3, rwx3,rwy3) CALL w1MathToPixels(rx4,ry4, rwx4,rwy4) LET rwx5= w1Rgt LET rwy5= w1Wndy(ry5) ! ----- draw zigzags that are on ----- CALL w1ShowGridLayer ! show grid buffer IF c1Switch(1)=true then ! right moving graph SET COLOR rgtclr PLOT rwx1,rwy1; rwx2,rwy2; rwx3,rwy3; rwx4,rwy4; rwx5,rwy5 END IF IF c1Switch(2)=true then ! left moving graph SET COLOR lftclr PLOT lwx1,lwy1; lwx2,lwy2; lwx3,lwy3; lwx4,lwy4; lwx5,lwy5 END IF IF c1Switch(3)=true then ! sum graph SET COLOR sumclr PLOT wx1,wy1; wx2,wy2; wx3,wy3; wx4,wy4; wx5,wy5; wx6,wy6; wx7,wy7; wx8,wy8 END IF CALL w1KeepGraphLayer ! buffer for rollover END SUB END SUB ! --- end of zigzag code -------------------