!First, the ghosted semicircle in the Nyquist plot should always be on, !I think. Somehow it got turned off entirely on this copy. ! !Bizarre - it is fine on my Mac and PC. I didn't change anything there. !Sometime I have to test your video card. A lot of bizarre things happen. ! !If k = 0, then phi and t0 are undefined. This means that the phi !indicator and rollover are turned off (not the case now), and the t0 = is left blank. ! !Sorry - I thought we decided that if k=0 then phi is pi/2 - 90 degrees. !I will turn it all off again - that is how it was today when you saw it. ! !If k = 0 and also omega = 0, then the only thing which is defined is P, which is !infinity. This means that all the !indicators on the left windows are off, the rollovers are disabled, !there's no bay height indicator or yellow graph line in the middle window. ! !If k is not zero but omega is, then t0 is undefined but everything else is !defined: A = 1, phi = 0, and the Nyquist plot displays the complex number 1. !The bay height is zero, the pass is shown, the rollovers work, the graphing !window shows the yellow line at height 1. ! Tides: OK, one more little bit of logic... when k and omega are both zero, ! we agree that A is undefined. So we shouldn't display it as zero. The ! yellow 'bay' elevation should vanish on the middle window, and on the ! left window, and the sloping pass indicator should vanish too. ! ! In the current typesetting, the >>> keys don't look as good: the >>> slops ! off the left end of the key. We could go back to >>. !! File: Tides !! January 3, 2003 Hubert Hohn 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 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 DECLARE DEF QuitWithin, InfoWithin LET toolHgt= 560 LET toolWid= 780 LET window$= "The d'Arbeloff Interactive Math Project" LET colorscheme= 0 LET title$ = "Tides" SUB ThisProgram CALL Tide 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 51a\TBLibs\TrueCtrl.trc" ! windows LIBRARY "c:\TB Gold 51a\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 --- !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= 6 ! ELSE IF size=12 then ! numeric output - axis labels ! LET CharWidth= 7 ! ELSE IF size=14 then ! rare ! LET CharWidth= 8 ! 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 ------ ! ----------------------------------------------------------- ! *** !Tides. It's tempting to leave phi as it is when k becomes zero, since !the limit as k ---> 0 is indeed pi/2. But in keeping with our rule to !drop undefined values, I think really the phi indicator should go off !when k = 0. We could use >>,<,> keys here rather than "animate." SUB Tide DECLARE PUBLIC black,drkgry,drkmid,midgry,litmid,litgry,white DECLARE PUBLIC red,yellow,green,cyan,blue,magenta,colorscheme DECLARE PUBLIC axislabelclr,axisclr,slideclr,true,false DECLARE PUBLIC workLft,workRgt,workBas,workTop,workMidx DECLARE DEF quitWithin, infoWithin ! --- help screen array --- DIM info$(1:1) MAT READ info$ DATA "Information on tides and linkage coefficients" ! --- color variables --- LET phiclr = green LET ocnClr = cyan LET bayClr = yellow LET ampClr = yellow ! --- Utility functions --- DECLARE DEF clamp,roundn,e DEF RadToDeg(rad)= rad*180/pi ! ---- Functions ---- ! phi = arctan(w/k) ! A = cos(phi) ! ocean= b*cos(w*t) ! bay = A*b*cos(w*t-phi) ! ocean= cos(w*t) ! b = 1 ! bay = A*cos(w*t-phi) ! b = 1 ! as k gets large... ! phi approaches 0 ! A approaches 1 ! bay approaches synchrony with ocean LET period= 12 ! 12 hour cycle DEF pi2 = 2*pi DEF fPhi(k,w) IF k>0 then LET fPhi= atn(w/k) ELSE LET fPhi= pi/2 END IF END DEF DEF fAp(phi)= cos(phi) ! amplitude polar DEF fAc(k,w)= k/sqr(w^2 + k^2) ! amplitude cartesian DEF fP(w) = pi2/w ! P is the period of the tide DEF fT0(phi,w)= phi/w DEF fOcean(w,t) = cos(w*t) DEF fBay(w,t,phi)= A*cos(w*t-phi) ! 1. p(s) is called the characteristic polynomial. ! 2. p(s) = 0 is called the characteristic equation. ! 3. The roots of p(s) = 0 are called the characteristic roots or eigenvalues. ! --- Design and layout --- ! ---------- Graphing plane parameters and methods ---------- ! ------ plane 1 - time series for ocean and bay heights ------- ! --- 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= 0 LET w1xMult = 1 LET w1yPiFlag= 0 LET w1yMult = 1 LET w1Lft= workLft+270 ! window bounds LET w1Rgt= w1Lft+240 LET w1Top= workTop+30 LET w1Bas= w1Top+240 LET w1fLft= 0 ! function bounds LET w1fRgt= 24 LET w1fTop= 1.5 LET w1fBas= -1.5 LET w1xAx$= "t" ! axis labels LET w1yAx$= "x" LET w1xGridstep= 0 ! horizontal grid intervals LET w1yGridstep= 0 ! vertical grid intervals LET w1xSTik = 0 ! horizontal axis Tik marks LET w1xLTik = 6 LET w1xLabel= 0 LET w1xFirst= w1fLft LET w1ySTik = 0 ! vertical axis Tik marks LET w1yLTik = 0.5 LET w1yLabel= 0.5 LET w1yFirst= w1fBas ! --- Plane 1 methods --- DECLARE DEF w1Fncx,w1Fncy,w1Wndx,w1Wndy ! window/function transforms DECLARE DEF w1wWithin, w1Within CALL w1Variables SUB w1Init CALL w1DrawPlane(1,1,1) ! x axis, y axis, zeroaxes CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w1Rgt+8,w1y0+3,w1Xax$,litgry) ! axis labels CALL PlotTextCJ(w1x0,w1Top-10,w1Yax$,yellow) LET bas = w1Top-10 LET txt$= "x' + kx = k cos(wt)" CALL StringWidth(txt$,sw) LET lft = w1Midx-sw/2 LET txt$= "x' + kx = k cos(" CALL PlotTextLJ(lft,bas,txt$,yellow) CALL StringWidth(txt$,sw) LET lft = lft + sw + 2 CALL SwapOmega(lft,bas,"w","w",yellow) LET lft = lft + 12 LET txt$= "t)" CALL PlotTextLJ(lft,bas,txt$,yellow) ! CALL SwapPhi(lft,bas,txt$,"0",yellow) CALL w1KeepGridLayer CALL OceanGraph CALL w1KeepGraphLayer END SUB SUB w1ShowGraphLayer2 BOX SHOW w1graphLayer2$ at w1Lft-5,w1Bas+5 END SUB SUB w1KeepGraphLayer2 BOX KEEP w1Lft-5,w1Rgt+5,w1Bas+5,w1Top-5 in w1graphLayer2$ END SUB ! ------- plane 2 - water level cross section ------------------ ! --- plane 2 data --- DECLARE PUBLIC w2Lft,w2Rgt,w2Bas,w2Top,w2Midx,w2Midy DECLARE PUBLIC w2fLft,w2fRgt,w2fBas,w2fTop,w2x0,w2y0 DECLARE PUBLIC w2xFirst, w2xSTik, w2xLTik, w2xLabel, w2xGridstep DECLARE PUBLIC w2yFirst, w2ySTik, w2yLTik, w2yLabel, w2yGridstep DECLARE PUBLIC w2wWid,w2wHgt,w2fWid,w2fHgt DECLARE PUBLIC w2fxRatio,w2fyRatio,w2wxRatio,w2wyRatio,w2Aspect DECLARE PUBLIC w2xPiFlag, w2xMult, w2yPiFlag, w2yMult LET w2Flag = 1 LET w2xPiFlag= 0 LET w2xMult = 1 LET w2yPiFlag= 0 LET w2yMult = 1 LET w2Lft = worklft + 55 ! pixel bounds LET w2Rgt = w2Lft + 135 LET w2Top = w1Top LET w2Bas = w1Bas LET w2fLft= 0 ! function bounds * pi LET w2fRgt= 3 LET w2fTop= 1.5 LET w2fBas= -1.5 LET w2xGridstep= 0 !0.5 ! horizontal grid intervals LET w2yGridstep= 0 !1 ! vertical grid intervals LET w2xAx$= "t" ! axis labels LET w2yAx$= "I" LET w2xSTik = 0 ! horizontal axis Tik marks LET w2xLTik = 0 LET w2xLabel= 0 LET w2xFirst= w2fLft LET w2ySTik = 0 ! vertical axis Tik marks LET w2yLTik = 0.5 LET w2yLabel= 0.5 LET w2yFirst= w2fBas ! --- plane 2 methods --- DECLARE DEF w2Fncx, w2Fncy, w2Wndx, w2Wndy ! window/function transforms DECLARE DEF w2wWithin, w2Within CALL w2Variables LET w2x1= w2Wndx(1) LET w2x2= w2Wndx(2) SUB w2Init CALL w2DrawPlane(1,1,0) ! x axis, y axis, zeroaxes CALL SetTextFont(1,12,"bold") LET midcol= int((w2lft+w2Wndx(1))/2) CALL PlotTextCJ(midcol,w2Top-5,"Ocean",ocnclr) LET midcol= int((w2Wndx(1)+w2Wndx(2))/2) CALL PlotTextCJ(midcol,w2Top-5,"Pass",white) LET midcol= int((w2Wndx(2)+w2Rgt)/2) CALL PlotTextCJ(midcol,w2Top-5,"Bay",bayclr) CALL PlotTextCJ(w2Midx,w2Bas+15,"Water Levels",litgry) ! draw ocean height range mark LET wx2= w2Wndx( 1) LET wy3= w2Wndy( 1) LET wy4= w2Wndy(-1) CALL PlotLine( wx2,wy3, wx2,wy4, ocnClr) ! CALL PlotLine(w2Lft+1,w2y0, w2Rgt-1,w2y0, litmid) CALL w2KeepGridLayer END SUB ! --------- Plane 3 - middle omega/phi graph ---------------- ! --- plane 3 data --- DECLARE PUBLIC w3Lft,w3Rgt,w3Bas,w3Top,w3Midx,w3Midy DECLARE PUBLIC w3fLft,w3fRgt,w3fBas,w3fTop,w3x0,w3y0 DECLARE PUBLIC w3xFirst, w3xSTik, w3xLTik, w3xLabel, w3xGridstep DECLARE PUBLIC w3yFirst, w3ySTik, w3yLTik, w3yLabel, w3yGridstep DECLARE PUBLIC w3wWid,w3wHgt,w3fWid,w3fHgt DECLARE PUBLIC w3fxRatio,w3fyRatio,w3wxRatio,w3wyRatio,w3Aspect DECLARE PUBLIC w3xPiFlag, w3xMult, w3yPiFlag, w3yMult LET w3Flag = 1 LET w3xPiFlag= 0 LET w3xMult = 1 LET w3yPiFlag= 1 LET w3yMult = pi LET w3Lft = w1Rgt + 110 ! pixel bounds LET w3Rgt = w3Lft + 80 LET w3Top = w1Midy + 22 LET w3Bas = w3Top + 80 LET w3fLft= 0 ! function bounds LET w3fRgt= 1 LET w3fTop= 0 LET w3fBas= -0.5 LET w3xAx$= "w" ! axis labels LET w3yAx$= "" LET w3xGridstep= 0 ! grid line intervals LET w3yGridstep= 0 LET w3xSTik = 0 ! axis Tik marks LET w3xLTik = 0.5 LET w3xLabel= 0.5 LET w3xFirst= w3fLft LET w3ySTik = 0 LET w3yLTik = 0.25 LET w3yLabel = 0.5 LET w3yFirst = w3fBas ! --- plane 3 methods --- DECLARE DEF w3Fncx,w3Fncy,w3Wndx,w3Wndy ! window/function transforms DECLARE DEF w3wWithin, w3Within CALL w3Variables SUB w3Init CALL w3DrawPlane(-1,1,1) ! x axis, y axis, zeroaxes CALL SetTextFont(1,12,"bold") CALL PlotTextRJ(w3x0-5,w3Bas+13,"-",phiclr) CALL DrawPhi12(w3x0-3,w3Bas+13,phiclr) CALL SwapOmega(w3Rgt+8,w3y0+3,"w","w",axislabelclr) ! CALL SetTextFont(1,9,"normal") ! ! LET wy= w3Wndy(0) ! PLOT w3Lft-4,wy; w3Lft-1,wy ! CALL PlotTextRJ(w3Lft-6,wy+3,"0",axisclr) ! ! LET wy= w3Wndy(-pi/4) ! PLOT w3Lft-4,wy; w3Lft-1,wy ! CALL PlotTextRJ(w3Lft-6,wy+3,"-45",axisclr) ! ! LET wy= w3Wndy(-pi/2) ! PLOT w3Lft-4,wy; w3Lft-1,wy ! CALL PlotTextRJ(w3Lft-6,wy+3,"-90",axisclr) CALL w3KeepGridLayer CALL w3KeepGraphLayer END SUB ! ------------- plane 4 - Nyquist real/imaginary --------------- ! --- plane 4 data --- DECLARE PUBLIC w4Lft,w4Rgt,w4Bas,w4Top,w4Midx,w4Midy DECLARE PUBLIC w4fLft,w4fRgt,w4fBas,w4fTop,w4x0,w4y0 DECLARE PUBLIC w4xFirst, w4xSTik, w4xLTik, w4xLabel, w4xGridstep DECLARE PUBLIC w4yFirst, w4ySTik, w4yLTik, w4yLabel, w4yGridstep DECLARE PUBLIC w4wWid,w4wHgt,w4fWid,w4fHgt DECLARE PUBLIC w4fxRatio,w4fyRatio,w4wxRatio,w4wyRatio,w4Aspect DECLARE PUBLIC w4xPiFlag, w4xMult, w4yPiFlag, w4yMult LET w4Flag = 1 LET w4xPiFlag= 0 LET w4xMult = 1 LET w4yPiFlag= 0 LET w4yMult = 1 LET w4Lft = w3Rgt - 112 ! pixel bounds LET w4Rgt = w4Lft + 112 ! 160 LET w4Top = workBas - 145 LET w4Bas = w4Top + 64 LET w4fLft= -0.2 ! function bounds LET w4fRgt= 1.2 LET w4fTop= 0.2 LET w4fBas= -0.6 LET w4xAx$= "Re" ! axis labels LET w4yAx$= "Im" LET w4xGridstep= 0 ! grid line intervals LET w4yGridstep= 0 LET w4xSTik = 0 ! axis Tik marks LET w4xLTik = 0.5 LET w4xLabel= 0.5 LET w4xFirst= 0 LET w4ySTik = 0 LET w4yLTik = 0.5 LET w4yLabel= 0.5 LET w4yFirst= -0.5 ! --- plane 4 methods --- DECLARE DEF w4Fncx,w4Fncy,w4Wndx,w4Wndy ! window/function transforms DECLARE DEF w4wWithin, w4Within CALL w4Variables SUB w4Init CALL w4DrawPlane(-1,1,1) ! x axis, y axis, zeroaxes CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w4Rgt+8,w4y0+3,w4xAx$,axislabelclr) ! axis labels CALL PlotTextCJ(w4x0,w4Top-17,w4yAx$,axislabelclr) LET txt$ = "k / p(iw)" CALL StringWidth(txt$,sw) CALL SwapOmega(w4Midx-sw/2,w4Bas+20,txt$,"w",white) CALL PlotTextCJ(w4Midx,w4Bas+40,"p(s) = s + k",white) ! axis labels CALL w4KeepGridLayer END SUB ! ------------ plane 5 - omega/amplitude graph ---------------- ! --- plane 5 data --- DECLARE PUBLIC w5Lft,w5Rgt,w5Bas,w5Top,w5Midx,w5Midy DECLARE PUBLIC w5fLft,w5fRgt,w5fBas,w5fTop,w5x0,w5y0 DECLARE PUBLIC w5xFirst, w5xSTik, w5xLTik, w5xLabel, w5xGridstep DECLARE PUBLIC w5yFirst, w5ySTik, w5yLTik, w5yLabel, w5yGridstep DECLARE PUBLIC w5wWid,w5wHgt,w5fWid,w5fHgt DECLARE PUBLIC w5fxRatio,w5fyRatio,w5wxRatio,w5wyRatio,w5Aspect DECLARE PUBLIC w5xPiFlag, w5xMult, w5yPiFlag, w5yMult LET w5Flag = 1 LET w5xPiFlag= 0 LET w5xMult = 1 LET w5yPiFlag= 0 LET w5yMult = 1 LET w5Lft = w3Lft ! pixel bounds LET w5Rgt = w5Lft + 80 LET w5Top = w1Top + 40 LET w5Bas = w5Top + 80 LET w5fLft= 0 ! function bounds LET w5fRgt= 1 LET w5fTop= 1 LET w5fBas= 0 LET w5xAx$= "w" ! axis labels LET w5yAx$= "A" LET w5xGridstep= 0 ! grid line intervals LET w5yGridstep= 0 LET w5xSTik = 0 ! axis Tik marks LET w5xLTik = 0.5 LET w5xLabel= 0 LET w5xFirst= w5fLft LET w5ySTik = 0 LET w5yLTik = 0.5 LET w5yLabel= 0.5 LET w5yFirst= w5fBas ! --- plane 5 methods --- DECLARE DEF w5Fncx,w5Fncy,w5Wndx,w5Wndy ! window/function transforms DECLARE DEF w5wWithin, w5Within CALL w5Variables SUB w5Init CALL w5DrawPlane(1,1,1) ! x axis, y axis, zeroaxes CALL SetTextFont(1,12,"bold") CALL SwapOmega(w5Rgt+8,w5y0+3,"w","w",axislabelclr) CALL SuperSubScriptCJ(w5x0,w5Top-10,w5yAx$,ampclr) CALL w5KeepGridLayer END SUB ! ---------- Slider parameters and methods -------- ! --------------- horizontal sliders -------------- ! --- horizontal slider 1 - t value --- DECLARE PUBLIC h1axis,h1wLft,h1wRgt,h1wBas,h1wTop,h1fLft,h1fRgt DECLARE PUBLIC h1name$,h1form$,h1clr,h1First,h1STik,h1LTik,h1Label DECLARE PUBLIC h1PiAxis,h1Mult,h1fMin,h1fMax DECLARE DEF h1Within ! window/function transforms LET h1PiAxis= 0 LET h1Mult = 1 LET h1clr = slideclr LET h1name$ = "t" LET h1form$ = "--%.#" LET h1Places= 1 LET h1axis = w1Bas + 22 LET h1wLft = w1Lft LET h1wRgt = w1Rgt LET h1fLft = 0 LET h1fRgt = 24 LET h1STik = 1 ! short tick marks LET h1LTik = 6 ! long tick marks LET h1Label = 6 ! labels LET h1First = h1fLft ! first tick mark LET h1Click = 1 CALL h1SliderVariables SUB h1SetZero LET t= 0 CALL h1mark(t) END SUB DECLARE DEF h1AnimWithin, h1LStpWithin, h1RStpWithin DECLARE DEF h1AnimStopWithin LET h1AnimStep= 0.2 ! two pixels SUB h1Init LET t= 0 CALL h1DrawSlider(h1name$,t) CALL h1AnimMoveStep(1,0,1) ! animstate,movestate,stepstate END SUB ! --- Slider 2 - omega value --- DECLARE PUBLIC h2axis,h2wLft,h2wRgt,h2wBas,h2wTop,h2fLft,h2fRgt DECLARE PUBLIC h2name$,h2form$,h2clr,h2First,h2STik,h2LTik,h2Label DECLARE PUBLIC h2PiAxis,h2Mult,h2fMin,h2fMax DECLARE DEF h2Within ! window/function transforms LET h2PiAxis= 0 LET h2Mult = 1 LET h2clr = slideclr LET h2name$ = "" LET h2form$ = "%.##" LET h2Places= 2 LET h2axis = h1axis LET h2wLft = w5Lft LET h2wRgt = w5Rgt LET h2fLft = 0 LET h2fRgt = 1 LET h2STik = 0.25 LET h2LTik = 0.5 LET h2Label = 0.5 LET h2First = h2fLft LET h2Click = 0.25 CALL h2SliderVariables SUB h2Init CALL h2DrawSlider(h2name$,w) CALL SwapOmega(h2wLft-16,h2wBas-3,"w","w",white) END SUB ! --- slider 3 --- DECLARE PUBLIC h3axis,h3wLft,h3wRgt,h3wBas,h3wTop,h3fLft,h3fRgt DECLARE PUBLIC h3name$,h3form$,h3clr,h3First,h3STik,h3LTik,h3Label DECLARE PUBLIC h3PiAxis,h3Mult,h3fMin,h3fMax DECLARE DEF h3Within ! window/function transforms LET h3PiAxis= 0 LET h3Mult = 1 LET h3clr = slideclr LET h3name$ = "k" LET h3form$ = "%.##" LET h3Places= 2 LET h3axis = w1Bas + 110 LET h3wLft = h1wLft LET h3wRgt = h3wLft + 100 LET h3fLft = 0 LET h3fRgt = 1 LET h3STik = 0.25 LET h3LTik = 0.5 LET h3Label = 0.5 LET h3First = h3fLft LET h3click = 0.25 CALL h3SliderVariables SUB h3Init CALL h3DrawSlider(h3name$,k) END SUB ! --- text output boxes --- ! --- text rectangle 1 - period equation and value --- ! Period = 2pi/omega LET t1BasLn = w1Bas + 172 LET t1Lft = w1Lft + 15 LET t1Rgt = w1Rgt - 70 LET t1Bas = t1BasLn + 5 LET t1Top = t1BasLn - 15 LET t1Label$= "P = " LET t1Clr = cyan SUB t1Label CALL SetTextFont(1,12,"bold") CALL SuperSubScriptRJ(t1Lft,t1BasLn,t1Label$,t1Clr) END SUB SUB t1Set CALL SetTextFont(1,12,"bold") LET lft= t1Lft CALL SwapPi(lft,t1BasLn,"2w","w",t1Clr) CALL StringWidth("2w",sw) LET lft = t1Lft + sw + 3 CALL DivSign(lft,t1BasLn,t1Clr) LET lft = lft + 8 CALL SwapOmega(lft,t1BasLn,"w","w",t1Clr) CALL StringWidth("w",sw) LET lft = lft + sw + 6 CALL PlotTextLJ(lft,t1BasLn,"=",t1Clr) LET t1vLft = lft + 12 LET t1vRgt = t1vLft + 100 END SUB SUB t1Val CALL t1ClearVal CALL SetTextFont(1,12,"bold") IF w=0 then CALL DrawInf12(t1vLft,t1BasLn,t1Clr) ELSE LET t$= trim$(using$("---%.##",fP(w))) CALL PlotTextLJ(t1vLft,t1BasLn,t$,t1Clr) END IF END SUB SUB t1Clear BOX CLEAR t1Lft-2,t1Rgt,t1Bas,t1Top END SUB SUB t1ClearVal BOX CLEAR t1vLft,t1vRgt,t1Bas,t1Top END SUB SUB t1Init CALL t1Label CALL t1Set CALL t1Val END SUB ! --- text rectangle 2 - t_0 phase lag equation and value --- ! timelag/phaseshift = ( phi/pi2)*Period = phi/omega LET t2BasLn = t1BasLn + 24 LET t2Lft = t1Lft LET t2Rgt = t1Rgt LET t2Bas = t2BasLn + 5 LET t2Top = t2BasLn - 15 LET t2Label$= "t_[0] = " SUB t2Init CALL t2Label CALL t2Set CALL t2Val END SUB SUB t2Label CALL SetTextFont(1,12,"bold") CALL SuperSubScriptRJ(t2Lft,t2BasLn,t2Label$,red) END SUB SUB t2Set CALL SetTextFont(1,12,"bold") ! t_0 = (phi/2 pi)P = phi/omega = CALL StringWidth("(0",sw) CALL SwapPhi(t2Lft,t2BasLn,"(0","0",red) LET lft = t2Lft + sw + 4 CALL DivSign(lft,t2BasLn,red) LET lft = lft + 8 CALL SwapPi(lft,t2BasLn,"2p)P","p",red) CALL StringWidth("2p)P",sw) LET lft = lft + sw + 8 CALL PlotTextLJ(lft,t2BasLn,"=",red) LET lft= lft + 12 CALL SwapPhi(lft,t2BasLn,"0","0",red) CALL StringWidth("0",sw) LET lft= lft + sw + 4 CALL DivSign(lft,t2BasLn,red) LET lft= lft + 8 CALL SwapOmega(lft,t2BasLn,"w","w",red) LET lft= lft+16 CALL PlotTextLJ(lft,t2BasLn,"=",red) LET t2vLft = lft + 12 LET t2vRgt = t2vLft + 40 END SUB SUB t2Val CALL t2ClearVal IF w>0 and k>0 then CALL SetTextFont(1,12,"bold") LET t$ = trim$(using$("---%.##",fT0(phi,w))) CALL PlotTextLJ(t2vLft,t2BasLn,t$,red) END IF END SUB SUB t2Clear BOX CLEAR t2Lft-2,t2Rgt,t2Bas,t2Top END SUB SUB t2ClearVal BOX CLEAR t2vLft-2,t2vRgt,t2Bas,t2Top END SUB ! --- checkbox - Bode and Nyquist switch --- DECLARE PUBLIC cb1Lft,cb1Rgt,cb1Bas,cb1Top,cb1Txt$,cb1Clr,cb1State DECLARE DEF cb1Within LET cb1Lft = w4Lft-22 LET cb1Bas = workBas-3 LET cb1Txt$= "Bode and Nyquist Plots" LET cb1Clr = litgry CALL cb1Variables ! --- end of design and layout --- ! --- initialize default parameters --- LET w,oldw = 0.5 LET k,oldk = 0.2 LET t,oldt = 0 LET cb1State = 0 LET NyState = cb1State LET phi,oldphi= fPhi(k,w) LET A,oldA = fAp(phi) LET timeLag = fT0(phi,w) ! --- Draw the screen --- CALL InitScreen CALL SetTimer SUB InitScreen BOX CLEAR worklft,workrgt,workbas,worktop CALL w1Init CALL w2Init CALL t1Init CALL t2Init CALL BayGraph CALL w2BayRangeMark CALL TsliderAction(t) CALL h1Init CALL h2Init CALL h3Init CALL cb1Init CALL InitBodeNyquist(NyState) END SUB SUB InitBodeNyquist(NyState) IF NyState=1 then CALL w5Init ! Amplitude CALL w3Init ! Phase CALL w4Init ! Nyquist CALL w3Curve CALL w3Value CALL w4Graph CALL w4Value CALL w5Graph CALL w5Value ELSE BOX CLEAR w3Lft-38,w3Rgt+24,w3Bas+18,w3Top-18 BOX CLEAR w4Lft-30,w4Rgt+30,w4Bas+44,w4Top-30 BOX CLEAR w5Lft-26,w5Rgt+24,w5Bas+ 8,w5Top-24 END IF END SUB ! ----------------- Event manager ----------------- DO LET ClearFlag1,ClearFlag3= 0 IF ms<>2 then CALL StoreGraphsForClear DO GET MOUSE: mx,my,ms IF w1Within(mx,my)=true or w2Within(mx,my)=true or w5Within(mx,my)=true then CALL w1AmplitudeRollover ELSE IF w3Within(mx,my)=true and NyState=true then CALL w3PhiRollover ELSE IF ClearFlag1=true then CALL ClearAmpRollover ELSE IF ClearFlag3=true then CALL ClearPhiRollover END IF LOOP until ms=2 END IF ! clean up as needed IF ClearFlag=true then CALL ClearAmpRollover END IF IF ClearFlag3=true then CALL ClearPhiRollover END IF IF h1Within(mx,my)=true then ! time IF my0 or w<>0 then !IF k<>0 then !IF ra<>0 then PLOT w1Lft,wy; w1Rgt,wy PLOT w2Lft,wy; w2Rgt,wy IF NyState=1 then PLOT w5Lft,wy; w5Rgt,wy END IF ! ELSE ! PLOT w2Lft,wy; w2Wndx(2),wy ! END IF CALL PlotTextLJ(w2Rgt+10,wy+4,using$("%.##",ra),yellow) END IF LET ClearFlag1= 1 END IF END SUB SUB w3PhiRollover IF clearflag1=1 then CALL ClearAmpRollover IF k>0 then ! undefined for k=0 IF ClearFlag3=0 then ! don't flicker if on LET wy= w3Wndy(-phi) CALL PlotLine( w3Lft,wy, w3Rgt,wy, phiclr) LET n = round(RadToDeg(-phi)) CALL PlotDegreesLJ(w3Rgt+10,w3Midy+4,n,phiclr) LET ClearFlag3= 1 END IF END IF END SUB SUB StoreGraphsForClear BOX KEEP w1Lft,w1Rgt,w1Bas,w1Top in w1temp$ BOX KEEP w2Lft,w2Rgt,w2Bas,w2Top in w2temp$ IF NyState=1 then ! Bode and Nyquest on? BOX KEEP w5Lft,w5Rgt,w5Bas,w5Top in w5temp$ BOX KEEP w3Lft,w3Rgt,w3Bas,w3Top in w3temp$ END IF END SUB SUB ClearAmpRollover BOX SHOW w1temp$ at w1Lft,w1Bas BOX SHOW w2temp$ at w2Lft,w2Bas BOX CLEAR w2Rgt+8,w2Rgt+45,w2Bas+5,w2Top-5 IF NyState=1 then BOX SHOW w5temp$ at w5Lft,w5Bas END IF LET ClearFlag1= 0 END SUB SUB ClearPhiRollover BOX SHOW w3temp$ at w3Lft,w3Bas BOX CLEAR w3Rgt+8,workrgt,w3Midy+10,w3Midy-10 LET ClearFlag3= 0 END SUB ! --- mouse events --- ! --- slider 1 - t value --- SUB h1MouseClick CALL h1GetClickVal(ms,h1Click,t) LET oldt= -999 ! force redraw CALL h1Action END SUB SUB h1MouseDrag DO CALL h1GetDragVal(ms,h1Places,t) CALL h1Action LOOP until ms=3 END SUB SUB h1Action IF t<>oldt then CALL TsliderAction(t) ! update heights and time marker LET oldt= t END IF END SUB SUB TsliderAction(t) ! response to change in t ! heights in plane 2 and time marker in plane 1 LET ocean= fOcean(w,t) LET bay = fBay(w,t,phi) LET wyO = round(w1Wndy(ocean)) LET wyB = round(w1Wndy(bay)) IF abs(wyO-wyB)<=2 then LET wyO= wyB ! = if within a pixel ! time graphs - current time indicator ! connects points on the two sinusoidal curves in plane 1 CALL w1ShowGraphLayer2 LET wx= w1Wndx(t) ! IF k>0 or w>0 then ! CALL PlotLine( wx,wyO, wx,wyB, white) ! draw the line ! END IF ! DRAW Diamond7(ocnclr) with shift(wx,wyO) ! set the points ! DRAW Diamond7(bayclr) with shift(wx,wyB) IF k>0 and w>0 then CALL PlotLine( wx,wyO, wx,wyB, white) ! draw the line DRAW Diamond7(ocnclr) with shift(wx,wyO) ! set the points DRAW Diamond7(bayclr) with shift(wx,wyB) ELSE DRAW Diamond7(ocnclr) with shift(wx,wyO) ! set the points END IF ! cross section - ocean and bay heights in plane 2 IF w>0 then CALL w2ShowGraphLayer CALL PlotLine( w2Lft+1,wyO, w2x1 ,wyO, ocnclr) ! ocean CALL PlotLine( w2x1 ,wyO, w2x2 ,wyB, white) ! pass CALL PlotLine( w2x2 ,wyB, w2Rgt-1,wyB, bayclr) ! bay ! ELSE IF k=0 and w>0 then ! CALL w2ShowGraphLayer ! CALL PlotLine( w2Lft+1,wyO, w2x1 ,wyO, ocnclr) ! ocean ! CALL PlotLine( w2x1 ,wyO, w2x2 ,wyB, white) ! pass ! CALL PlotLine( w2x2 ,wyB, w2Rgt-1,wyB, bayclr) ! bay ELSE IF w=0 and k>0 then CALL BoxArea(w2Lft+1,w2Rgt-1,w2Bas-1,w2Top+1,black) CALL PlotLine( w2Lft+1,wyO, w2x1 ,wyO, ocnclr) ! ocean CALL PlotLine( w2x1 ,wyO, w2x2 ,wyB, white) ! pass CALL PlotLine( w2x2 ,wyB, w2Rgt-1,wyB, bayclr) ! bay ELSE CALL BoxArea(w2Lft+1,w2Rgt-1,w2Bas-1,w2Top+1,black) CALL PlotLine( w2Lft+1,wyO, w2x1 ,wyO, ocnclr) ! ocean ! CALL PlotLine( w2x2 ,wyB, w2Rgt-1,wyB, bayclr) ! bay END IF END SUB ! --- t slider animation --- SUB Animate LET start= round(w1Wndx(t)) ! start at time t IF start>=w1Rgt then LET start= w1Lft ! start over at t=0? FOR wx= start to w1Rgt LET t= w1Fncx(wx) ! get t CALL TsliderAction(t) ! update left plane CALL h1mark(t) ! update slider handle GET MOUSE: mx,my,ms ! check for mouse event IF ms=2 then ! stop on mousedown CALL h1AnimStopButtonUp(ms) ! get mouse up EXIT FOR END IF CALL Delay(1/30) NEXT wx CALL h1StopButtonClear END SUB ! --- slider 2 - omega value --- SUB h2MouseClick CALL h2GetClickVal(ms,h2Click,w) CALL h2Action END SUB SUB h2MouseDrag DO CALL h2GetDragVal(ms,h2Places,w) CALL h2Action LOOP until ms=3 END SUB SUB h2Action IF w<>oldw then LET phi = fPhi(k,w) LET A = fAp(phi) IF NyState=1 then ! Bode and Nyquest on? CALL w5Value CALL w4Value CALL w3Value END IF CALL OceanGraph ! draw the ocean height curve CALL BayGraph ! draw the bay height curve CALL w2BayRangeMark ! plane 2 bay height range mark CALL t1Val CALL t2Val LET oldw= w END IF END SUB ! --- slider 3 - k value --- SUB h3MouseClick CALL h3GetClickVal(ms,h3Click,k) CALL h3Action END SUB SUB h3MouseDrag DO CALL h3GetDragVal(ms,h3Places,k) CALL h3Action LOOP until ms=3 END SUB SUB h3Action IF k<>oldk then LET phi= fPhi(k,w) LET A = fAp(phi) CALL BayGraph ! draw the bay height curve CALL w2BayRangeMark ! plane 2 bay height range mark IF NyState=1 then ! Bode and Nyquest on? CALL w3Curve CALL w3Value CALL w5Graph CALL w5Value CALL w4Value END IF CALL t2Val LET oldk= k END IF END SUB ! --- plane 2 cross section - water levels --- SUB w2BayRangeMark ! ocean and bay cross section IF w>0 then CALL w2ShowGridLayer ELSE CALL BoxArea(w2Lft+1,w2Rgt-1,w2Bas-1,w2Top+1,black) END IF IF w>0 then SET COLOR bayClr ! show range line for bay height LET wx2= w2Wndx( 2) LET wy1= w2Wndy( A) LET wy2= w2Wndy(-A) PLOT wx2,wy1; wx2,wy2 END IF CALL w2KeepGraphLayer END SUB ! --- plane 3 - phi from omega --- SUB w3Curve ! phi graph CALL w3ShowGridLayer IF k>0 then SET COLOR litmid FOR wx= w3Lft to w3Rgt LET x = w3Fncx(wx) ! omega LET y = -atn(x/k) ! phi LET wy= w3Wndy(y) IF wy>w3Top and wy0 then CALL w3MathToPixels(w,-fPhi(k,w),wx,wy) CALL PlotLine(wx,wy,wx,w3Top+1,phiclr) DRAW Diamond7(phiclr) with shift(wx,wy) END IF END SUB ! ---- plane 4 - complex plane - Nyquist plot ---- SUB w4Graph ! Nyquist curve CALL w4ShowGridLayer IF k>0 and w>0 then SET COLOR 4 LET r,xc= 0.5 FOR ang= 0 to pi step pi/64 CALL PolarToCartesian(r,ang,x,y) ! A,phi to x,y CALL w4MathToPixels(xc+x,-y,wx,wy) PLOT wx,wy; NEXT ang PLOT END IF CALL w4KeepGraphLayer END SUB SUB w4Value CALL w4ShowGraphLayer CALL PolarToCartesian(A,-phi,x,y) ! set the line and point CALL w4MathToPixels(x,y,wx,wy) CALL PlotLine(w4x0,w4y0, wx,wy,ampclr) DRAW diamond7(ampclr) with shift(wx,wy) ! draw the green arc IF k>0 or w>0 then SET COLOR phiclr LET arcrad= sqr(x*x+y*y)/2 FOR ang= 0 to phi step 1/16 CALL PolarToCartesian(arcrad,ang,x,y) PLOT w4Wndx(x),w4Wndy(-y); NEXT ang PLOT ELSE CALL w4ShowGridLayer END IF END SUB ! ---- w5 plane - amplitude graph --- SUB w5Graph ! A = k/sqrt(omega^2 + k^2) SET COLOR litmid CALL w5ShowGridLayer IF w>0 or k>0 then FOR wx= w5lft+1 to w5rgt LET x = w5Fncx(wx) ! omega LET y = fAc(k,x) ! amplitude LET wy= w5Wndy(y) PLOT wx,wy; NEXT wx PLOT END IF CALL w5KeepGraphLayer END SUB SUB w5Value CALL w5ShowGraphLayer IF w>0 or k>0 then LET wx= w5Wndx(w) LET y = fAc(k,w) ! amplitude LET wy= w5Wndy(y) DRAW Diamond7(ampclr) with shift(wx,wy) CALL PlotLine( wx,wy, wx,w5Bas-1, ampclr) END IF END SUB ! --- w1 plane graphing methods - sinusoidal ocean and bay curves --- SUB OceanGraph CALL w1ShowGridLayer IF w>0 then ! show period of ocean tides LET period= pi2/w ! period value LET wpx= w1Wndx(period) IF wpx0 and w>0 then ! display the lag or phase shift LET lag= fT0(phi,w) LET wx = w1Wndx(lag) IF wx0 or w>0 then ! display the lag or phase shift SET COLOR bayclr ! draw the bay curve FOR wx= w1Lft to w1Rgt LET bt = w1Fncx(wx) ! find t LET bay= fBay(w,bt,phi) ! get bay height PLOT wx,w1Wndy(bay); NEXT wx PLOT END IF CALL w1KeepGraphLayer2 END SUB END SUB ! --- end of tide code -------------------