! In the title line, the ODE, it should be omega_0 , not omega_n. ! (Math standard would write omega_0^2 with the 2 directly above the 0, ! by the way, but this isn't too important.) ! Check subscripts with Haynes !!! ! Dennis Zill on damping ! mx'' + Bx' + kx = 0 where B is a positive damping constant ! x'' + B/m x' + k/m x = 0 ! or ! x'' + 2Z x' + w^2 x = 0 where 2Z = B/m and w^2 = k/m ! engineers call this w the natural frequency, w_n ! 2Z is used for convenience to make the auxiliary equation ! m^2 + 2Zm + w^2 = 0 ! the roots of this equation are ! m1 = (-2Z + sqrt((2Z)^2 - 4w^2)) / 2 ! m2 = (-2Z - sqrt((2Z)^2 - 4w^2)) / 2 ! m1 = (-2Z + sqrt(4Z^2 - 4w^2)) / 2 ! m2 = (-2Z - sqrt(4Z^2 - 4w^2)) / 2 ! m1 = (-2Z + 2sqrt(Z^2 - w^2)) / 2 ! m2 = (-2Z - 2sqrt(Z^2 - w^2)) / 2 ! m1 = -Z + sqrt(Z^2 - w^2) ! m2 = -Z - sqrt(Z^2 - w^2) ! Z = B/(2m) and w = sqrt(k/m) ! if Z^2 = w^2 damping is critical ! if Z = w damping is critical ! if B/2m = sqrt(k/m) damping is critical ! if B = 2m sqrt(k/m) damping is critical ! 2m sqrt(k/m) is the value of critical damping ! x'' + 2Z w_n x' + w_n^2 x = 0 ! w_n = sqrt(k/m) and 2Z = B/m ! x'' + B/m sqrt(k/m) x' + k/m x = 0 !! File: Damping Ratio !! May 26, 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 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 title$ = "The Damping Ratio" SUB ThisProgram CALL DampingRatio 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 x0 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.unix" !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 ------ ! ----------------------------------------------------------- MODULE Zeta SHARE Zeta(0:12,0:7) SHARE thetawid LET thetawid= 8 MAT READ Zeta DATA 1,1,0,1,1,1,1,0 DATA 0,1,1,1,0,0,1,1 DATA 0,1,1,0,0,0,1,1 DATA 0,1,1,1,1,1,1,0 DATA 1,1,0,0,0,0,0,0 DATA 1,1,0,0,0,0,0,0 DATA 1,1,0,0,0,0,0,0 DATA 1,1,0,0,0,0,0,0 DATA 1,1,0,0,0,0,0,0 DATA 0,1,1,1,1,0,0,0 DATA 0,0,0,0,1,1,0,0 DATA 0,0,0,0,1,1,0,0 DATA 0,0,1,1,1,0,0,0 SUB SwapZeta(lft,bas,t$,c$,clr) LET l= len(t$) LET x= lft FOR i= 1 to l LET ch$= t$(i:i) IF ch$=c$ then CALL DrawZeta12(x+1,bas,clr) LET x= x+thetawid+1 ELSE CALL PlotTextLJ(x,bas,ch$,clr) CALL StringWidth(ch$,sw) LET x= x+sw END IF NEXT i END SUB SUB DrawZeta12(lft,bas,clr) SET COLOR clr LET top= bas-9 FOR row= 0 to 12 LET wy= top+row FOR col= 0 to 7 LET bit= Zeta(row,col) IF bit=1 then LET wx= lft+col PLOT wx,wy END IF NEXT col NEXT row END SUB END MODULE ! *** SUB DampingRatio DECLARE PUBLIC black,drkgry,drkmid,midgry,litmid,litgry,white DECLARE PUBLIC red,yellow,green,cyan,blue,magenta,colorscheme DECLARE PUBLIC axislabelclr,slideclr,true,false DECLARE PUBLIC workLft,workRgt,workBas,workTop,workMidx DECLARE DEF quitWithin,infoWithin ! --- colors --- LET waveclr = cyan LET rootclr = yellow LET zetaclr = green LET ivclr = white ! --- help screen array --- ! mx'' + c_vx' + kx = 0 ! where c_v means viscous damping ! x'' + c_v/m x' + k/m x = 0 ! c_c = 2m sqrt(k/m) = 2mw_n ! critical damping ! to simplify the solutions ! w_n = sqrt(k/m) ! natural frequency ! c_c = 2msqrt(k/m) = 2mw_n ! critical damping ! z = c_v / c_c ! damping ratio ! z = c_v / 2mw_n ! b = 2 * w_n * c_v / 2mw_n = c_v/m ! Damping ratio ! ! Set the initial conditions on the window at lower left or using the sliders. ! ! Set the undamped natural circular frequency omega_n using the slider at lower ! right. ! ! Set the damping ratio zeta using the slider at bottem center (which actually ! reads out the negative of zeta). ! The characteristic polynomial is displayed symbolically at right, and its roots ! are displayed in yellow and also represented by yellow diamonds in the window ! at bottom center. The green dot in that window is the value of - zeta. ! ! Buttons control the vertical scale of the right hand graphing window. ! The solution is displayed in blue on that window. ! Crosshairs show when you roll the cursor over the right hand window, ! and the values of t and x are displayed. DIM info$(1:12) MAT READ info$ DATA "The Damping Ratio" DATA "" DATA "This tool supports exploration of the effects of the damping ratio, zeta, upon the solution." DATA "" DATA "The solution is displayed in the time series plane." DATA "The numerical buttons set the vertical scale of time series plane." DATA "Roll the mouse cursor over the time series plane to display the values of t and x." DATA "" DATA "To set the initial conditions, click or drag the mouse in the lower left initial value plane or use the initial value sliders." DATA "Click or drag the omega_[n] slider to set the undamped natural frequency." DATA "Click or drag the -zeta slider to set the negative of the damping ratio. The green dot in the complex plane shows the value of -zeta graphically." DATA "The characteristic polynomial is displayed symbolically at right, and its roots are displayed in yellow and are represented by yellow diamonds in the complex plane." ! Set the initial conditions on the window at lower left or using the sliders. ! ! Set the undamped natural circular frequency omega_n using the slider at lower ! right. ! ! Set the damping ratio zeta using the slider at bottem center (which actually ! reads out the negative of zeta). ! The characteristic polynomial is displayed symbolically at right, and its roots ! are displayed in yellow and also represented by yellow diamonds in the window ! at bottom center. The green dot in that window is the value of - zeta. ! ! Buttons control the vertical scale of the right hand graphing window. ! The solution is displayed in blue on that window. ! DATA ! : LET Z = damping coefficient / critical damping" ! DATA "" ! DATA "if" ! DATA "-mx'' + b x' + kx = 0" ! DATA "then" ! DATA "-x'' + b/m x' + k/m x = 0" ! DATA "if Z = 1/2 B/m and w0 = sqrt(k/m) then" ! DATA "-x'' + 2Zw0 x' + w0^2 x = 0" ! DATA "the auxiliary equation becomes:" ! DATA "-s^2 + 2Zw0 s + w0^2 = 0" ! DATA "and the corresponding roots are:" ! DATA "-r1 = -Zw0 + w0 sqrt(Z^2 - 1) i" ! DATA "-r2 = -Zw0 - w0 sqrt(Z^2 - 1) i" ! DATA "" ! DATA "When Z^2-1 > 0 the system is overdamped. The roots are real and there is no oscillation. The position of the mass crosses the axis at most once." ! DATA "When Z^2-1 = 0 the system is critically damped. There is one real root and no oscillation. A very slight decrease in damping produces oscillation." ! DATA "When Z^2-1 < 0 the system is underdamped. The roots are complex conjugate and the motion is oscillatory." ! ---------- Utility functions --- DECLARE DEF clamp,roundn,e ! ------------ functions ----------- ! x" + 2 zeta w0 x' + w0^2 x = f(t)" ! DE ! s^2 + 2 zeta w0 s + w0^2 ! characteristic equation ! r1 = -Zw0 + w0 sqrt(Z^2 - 1) i ! roots ! r2 = -Zw0 - w0 sqrt(Z^2 - 1) i ! w0 is sqrt(k/m) ! natural frequency SUB SetConstants LET z2 = z*z LET zw = z*w IF abs(z)<=1 then LET sqz2= sqr(1-z2) ELSE LET d = sqr(z^2-1) END IF LET wn = w*sqz2 END SUB DEF fu(t) ! under damped IF w=0 then ! linear LET fu= v0*t + x0 ELSE LET wnt = wn*t LET swnt= sin(wnt) LET ezwt= exp(-zw*t) LET c = ezwt * (cos(wnt) + (z/sqz2)*swnt) LET s = (ezwt*swnt) / wn LET fu = x0*c + v0*s END IF END DEF DEF fc(t) ! critical damping IF w=0 then ! linear LET fc= v0*t + x0 ELSE LET wt = w*t LET ezwt= exp(-wt) ! LET ezwt= exp(-z*wt) ! needed if z can be -1 ! IF z=1 then ! LET c= (1+wt) * ezwt ! ELSE IF z=-1 then ! LET c= (1-wt) * ezwt ! END IF LET c = (1+wt) * ezwt LET s = t * ezwt LET fc= x0*c + v0*s END IF END DEF DEF fo(t) ! over damped IF w=0 then ! linear LET fo= v0*t + x0 ELSE LET d = sqr(z^2-1) IF d<>0 then LET zd = z/d LET wd = 1/(w*d) LET wt = w*t LET a = 0.5*((1 + zd)*x0 + wd*v0) LET b = 0.5*((1 - zd)*x0 - wd*v0) LET fo = a*exp((-z+d)*wt) + b*exp((-z-d)*wt) END IF END IF END DEF DEF env(t) = x0*exp(-zw*t)/sqr(1-z^2) SUB Roots(real,imag,im1,im2) LET real= -z WHEN error in LET imag = sqr(1-z*z) USE END WHEN LET im1 = imag LET im2 = -imag END SUB SUB RealRoots(r1,r2) IF z=1 then LET r1,r2 = -1 ELSE LET d = sqr(z^2-1) LET r1 = (-z + d) LET r2 = (-z - d) END IF END SUB !Steve's equations !LET e= exp(1) !DEF fc(z,t)= (1+t)*e^(-t) ! critical damping !DEF fo(z,t) ! over damped ! LET sqrt= sqr(z*z-1) ! LET t1 = 0.5*(1+z/sqrt) * exp[(-z+sqrt)*t] ! LET t2 = 0.5*(1-z/sqrt) * exp[(-z-sqrt)*t] ! LET fo = t1+t2 !END DEF !DEF fu(z,t) ! under damped ! LET sqrt= sqr(1-z*z) ! LET fu = e^(-z*t)*[cos(sqrt*t)+z/sqrt*sin(sqrt*t)] !END DEF ! ---------- Graphing plane parameters and methods ---------- ! -------------------- w1 plane - time series ----------------------- ! --- w1 plane 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 = workMidx - 310 ! pixel bounds LET w1Rgt = w1Lft + 640 LET w1Top = workTop + 30 LET w1Bas = w1Top + 200 LET w1fLft= 0 ! function bounds * pi LET w1fRgt= 8 LET w1fTop= 1 LET w1fBas= -1 LET w1xGridstep= 0 ! horizontal grid intervals LET w1yGridstep= 0 ! vertical grid intervals LET w1xAx$= "t" ! axis labels LET w1yAx$= "x" LET w1xSTik = 0.25 ! horizontal axis Tik marks LET w1xLTik = 0.50 LET w1xLabel= 1 LET w1xFirst= w1fLft LET w1ySTik = 0.1 ! vertical axis Tik marks LET w1yLTik = 0.5 LET w1yLabel= 0.5 LET w1yFirst= w1fBas ! --- w1 plane methods --- DECLARE DEF w1Fncx, w1Fncy, w1Wndx, w1Wndy ! window/function transforms DECLARE DEF w1wWithin CALL w1Variables SUB w1Init BOX CLEAR worklft,w1Lft,w1Bas+3,w1Top-3 CALL w1DrawPlane(1,1,1) ! grid, axes, zeroaxes CALL Grid1 CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w1Rgt+8,w1y0+3,w1xAx$,axislabelclr) ! axis labels CALL PlotTextCJ(w1x0,w1Top-10,w1yAx$,cyan) CALL w1KeepGridLayer CALL w1KeepGraphLayer END SUB SUB Grid1 LOCAL i,wx SET COLOR drkmid FOR i= 2 to 6 step 2 LET wx= w1Wndx(i*pi) PLOT wx,w1Top+1; wx,w1Bas-1 NEXT i END SUB ! --- zoom buttons --- LET zmHgt = 17 LET zmStp = zmHgt+2 LET zmLft = w1Lft LET zmRgt = zmLft + 40 LET zmTop = w1Bas + 30 LET zmBas = zmTop + 3*zmStp + zmHgt SUB Zoom SELECT CASE zmBtn CASE 0 LET w1fTop = 10 LET w1ySTik= 1 ! vertical axis Tik marks LET w1yLTik= 5 CASE 1 LET w1fTop = 1 LET w1ySTik= 0.1 ! vertical axis Tik marks LET w1yLTik= 0.5 CASE 2 LET w1fTop = 0.10001 ! needed offset numerics error LET w1ySTik= 0.01 ! vertical axis Tik marks LET w1yLTik= 0.05 CASE 3 LET w1fTop = 0.010 LET w1ySTik= 0.001 ! vertical axis Tik marks LET w1yLTik= 0.005 END SELECT LET w1fLft = 0 ! function bounds * pi LET w1fRgt = 8 LET w1fBas = -w1fTop LET w1yLabel= w1yLTik LET w1yFirst= w1fBas CALL w1Variables CALL w1Init END SUB SUB ZoomInit CALL SetTextFont(1,12,"bold") FOR i = 0 to 3 LET t= zmTop + i*zmStp LET b= t + zmHgt SELECT CASE i CASE 0 LET txt$= "10" CASE 1 LET txt$= "1" CASE 2 LET txt$= "0.1" CASE 3 LET txt$= "0.01" END SELECT CALL DrawButton(zmLft,zmRgt,b,t,5,txt$) NEXT i END SUB ! ---------- w2 initial values ------------ ! --- w2 plane 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 = w1Lft ! window bounds LET w2Rgt = w1Lft + 100 LET w2Top = workBas-142 LET w2Bas = w2Top + 100 LET w2fSize= 2 LET w2fLft = -w2fSize ! function bounds LET w2fRgt = w2fSize LET w2fTop = w2fSize LET w2fBas = -w2fSize LET w2xAx$ = "x(0)" ! axis labels LET w2yAx$ = "x(0)" LET w2xGridstep= 1 ! horizontal grid intervals LET w2yGridstep= 1 ! vertical grid intervals LET w2xSTik = 0.5 ! horizontal axis Tik marks LET w2xLTik = 1 LET w2xLabel= 0 LET w2xFirst= w2fLft LET w2ySTik = 0.5 ! vertical axis Tik marks LET w2yLTik = 1 LET w2yLabel= 0 LET w2yFirst= w2fBas ! --- w2 Plane methods --- DECLARE DEF w2Fncx,w2Fncy,w2Wndx,w2Wndy ! window/function transforms DECLARE DEF w2wWithin CALL w2Variables SUB w2Init CALL w2DrawPlane(1,1,1) ! grid, axes, zeroaxes CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w2Rgt+8,w2y0+3,w2xAx$,axislabelclr) ! axis labels CALL StringWidth("x(0)",sw) LET lft= w2x0 - sw/2 CALL PlotTextLJ(lft,w2Top-10,w2yAx$,axislabelclr) CALL PlotTextLJ(lft+2,w2Top-20,".",axislabelclr) CALL w2KeepGridLayer END SUB ! --- w3 plane 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 w3yPiFlag= 0 LET w3xMult = 1 LET w3yMult = 1 LET w3Lft = w2Rgt + 105 ! pixel bounds LET w3Rgt = w3Lft + 200 LET w3Top = workbas - 242 LET w3Bas = w3Top + 200 LET w3fSize= 2 LET w3fLft = -4 ! function bounds LET w3fRgt = 0 LET w3fTop = w3fSize LET w3fBas = -w3fSize LET w3xAx$ = "Re" ! axis labels LET w3yAx$ = "Im" LET w3xGridstep= 1 ! horizontal grid intervals LET w3yGridstep= 1 ! vertical grid intervals LET w3xSTik = 0.5 ! horizontal axis Tik marks LET w3xLTik = 1 LET w3xLabel= 1 LET w3xFirst= w3fLft LET w3ySTik = 0.5 ! vertical axis Tik marks LET w3yLTik = 1 LET w3yLabel= 1 LET w3yFirst= w3fBas ! --- w3 Plane methods --- DECLARE DEF w3Fncx,w3Fncy,w3Wndx,w3Wndy ! window/function transforms DECLARE DEF w3wWithin CALL w3Variables SUB w3Init CALL w3DrawPlane(1,1,1) ! grid, axes, zeroaxes CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w3Rgt+8,w3y0+3,w3xAx$,axislabelclr) ! axis labels CALL PlotTextCJ(w3x0,w3Top-10,w3yAx$,axislabelclr) SET COLOR drkmid FOR ang= pi/2 to 3*pi/2 step pi/200 LET x = cos(ang) LET y = sin(ang) LET wx= w3Wndx(x) LET wy= w3Wndy(y) PLOT wx,wy; NEXT ang PLOT CALL w3KeepGridLayer END SUB ! ---------- Slider parameters and methods ---------- ! ---------------- vertical sliders ----------------- LET slideHeight= 96 ! --- vertical slider 1 --- DECLARE DEF v1Fncy,v1Wndy,v1Within ! window/function transforms DECLARE PUBLIC v1axis,v1wLft,v1wRgt,v1wBas,v1wTop,v1sBas,v1sTop DECLARE PUBLIC v1fBas,v1fTop,v1First,v1STik,v1LTik,v1Label DECLARE PUBLIC v1name$,v1Mult,v1form$,v1clr,v1PiAxis LET v1PiAxis= 0 LET v1Mult = 1 LET v1clr = slideclr LET v1name$ = "" LET v1form$ = "-%.##" LET v1Places= 2 LET v1Click = 0.5 LET v1axis = w2Lft - 24 LET v1wBas = w2Bas LET v1wTop = w2Top LET v1fBas = w2fBas LET v1fTop = w2fTop LET v1STik = 0.5 LET v1LTik = 1 LET v1Label = 1 LET v1First = v1fBas CALL v1SliderVariables SUB v1Init CALL v1DrawSlider(v1name$,y0) END SUB ! ----------- horizontal sliders ------------ ! --- h1 slider - x0 --- 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 LET h1PiAxis= 0 LET h1Mult = 1 LET h1clr = slideclr LET h1name$ = "" LET h1form$ = "-%.##" LET h1Places= 2 LET h1Click = 0.5 LET h1axis = w2Bas + 22 LET h1wLft = w2Lft LET h1wRgt = w2Rgt LET h1fLft = w2fLft LET h1fRgt = w2fRgt LET h1STik = 0.5 ! short tick marks LET h1LTik = 1 ! long tick marks LET h1Label= 1 ! labels LET h1First= h1fLft ! first tick mark CALL h1SliderVariables SUB h1Init CALL h1DrawSlider(h1name$,x0) END SUB ! --- h2 Slider - zeta --- 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 LET h2PiAxis= 0 LET h2Mult = 1 LET h2clr = green LET h2name$ = "-Z" LET h2form$ = "-%.##" LET h2Places= 2 LET h2Click = 0.25 LET h2axis = w3Bas + 22 LET h2wLft = w3Wndx(-1.25) LET h2wRgt = w3Wndx( 0) LET h2fLft = -1.25 LET h2fRgt = 0 LET h2STik = 0.25 ! short tick marks LET h2LTik = 1 ! long tick marks LET h2Label = 0 ! labels LET h2First = -1 ! first tick mark CALL h2SliderVariables SUB h2Init CALL h2DrawSlider("",-z) CALL StringWidth(h2Name$,sw) CALL SwapZeta(h2wLft-7-sw,h2wBas-3,h2Name$,"Z",green) END SUB ! --- h3 slider --- 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 h3Fncx,h3Within LET h3PiAxis= 0 LET h3Mult = 1 LET h3clr = litgry ! slideclr LET h3name$ = "" LET h3form$ = "-%.##" LET h3Places= 2 LET h3Click = 0.1 LET h3axis = h2axis LET h3wLft = w3Rgt + 115 LET h3wRgt = h3wLft + 100 LET h3fLft = 0 LET h3fRgt = 2 LET h3STik = 0.1 LET h3LTik = 0.5 LET h3Label = 1 LET h3First = h3fLft CALL h3SliderVariables SUB h3Init CALL h3DrawSlider("",w) CALL SuperSubScriptOmegaRJ(h3wLft-5,h3wBas-3,"w_[n]","w",litgry) END SUB ! ---------- Text Output Rects ---------- ! ----- t1 DE ----- ! x" + 2ZW_nx' + W_n^2x = 0 LET t1BasLn= w1Top - 13 LET t1Lft = w1Midx - 80 LET t1Rgt = h1wRgt + 30 LET t1Bas = t1BasLn + 5 LET t1Top = t1BasLn - 15 LET t1$= "w_[n]x' + w_[n]^[2]x = 0" ! DE SUB t1Label LET lft= t1Lft CALL XDot2(lft,t1BasLn,cyan) CALL SwapZeta(lft,t1BasLn," + 2Z","Z",cyan) CALL StringWidth(" + 2Z",sw) LET lft= lft + sw + 2 CALL SuperSubScriptOmegaLJ(lft,t1BasLn,"w_[n]","w",cyan) CALL StringWidth("wn",sw) LET lft= lft + sw CALL XDot1(lft,t1BasLn,cyan) CALL PlotTextLJ(lft,t1BasLn," + ",cyan) CALL StringWidth(" + ",sw) LET lft= lft + sw CALL OmegaSubNSqr(lft,t1BasLn,clr) CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(lft,t1BasLn,"x = 0",cyan) END SUB SUB t1Clear BOX CLEAR t1Lft-2,t1Rgt,t1Bas,t1Top END SUB SUB t1Init CALL t1Label END SUB SUB XDot1(lft,bas,clr) CALL PlotTextLJ(lft,bas,"x",clr) CALL PlotTextLJ(lft+2,bas-9,".",clr) CALL StringWidth("x",sw) LET lft= lft + sw END SUB SUB XDot2(lft,bas,clr) CALL PlotTextLJ(lft,bas,"x",clr) CALL PlotTextLJ(lft,bas-9,".",clr) CALL PlotTextLJ(lft+4,bas-9,".",clr) CALL StringWidth("x",sw) LET lft= lft + sw END SUB SUB OmegaSubNSqr(lft,bas,clr) CALL SuperSubScriptOmegaLJ(lft,bas,"w_[n]","w",cyan) CALL StringWidth("w",sw) LET lft= lft + sw + 1 CALL SetTextFont(1,9,"bold") CALL PlotTextLJ(lft,bas-6,"2",cyan) CALL StringWidth("2",sw) CALL SetTextFont(1,9,"bold") LET lft= lft + sw + 1 END SUB ! --- t2 characteristic equation --- ! s^2 + 2ZW_ns + W_n^2 = 0 LET t2BasLn= w3Midy + 3 LET t2Lft = h3wLft - 25 LET t2Rgt = workrgt LET t2Bas = t2BasLn + 5 LET t2Top = t2BasLn - 15 ! LET t2$ = "w_[n]s + w_[n]^[2] = 0" ! characteristic equation SUB t2Label LET lft= t2Lft CALL SuperSubScriptLJ(lft,t2BasLn,"s^[2] + 2",cyan) CALL StringWidth("s2 + 2",sw) LET lft= lft + sw CALL SwapZeta(lft,t2BasLn,"Z","Z",cyan) CALL StringWidth("Z",sw) LET lft= lft + sw + 2 CALL SuperSubScriptOmegaLJ(lft,t2BasLn,"w_[n]s + ","w",cyan) CALL StringWidth("wns + ",sw) LET lft= lft + sw CALL OmegaSubNSqr(lft,t2BasLn,cyan) CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(lft,t2BasLn," = 0",cyan) END SUB SUB t2Clear BOX CLEAR t2Lft-2,t2Rgt,t2Bas,t2Top END SUB SUB t2Init CALL t2Label END SUB ! --- t3 text rectangle - root values --- LET t3BasLn1= t2BasLn + 35 LET t3BasLn2= t3BasLn1 + 20 LET t3Lft = t2Lft LET t3Rgt = workrgt LET t3Bas = t3BasLn2 + 5 LET t3Top = t3BasLn1 - 15 LET t3Label1$= "r_[1] = " LET t3Label2$= "r_[2] = " CALL StringWidth("r2 = ",sw) LET t3Eqx= t3Lft + sw SUB t3Label CALL SuperSubScriptRJ(t3Eqx,t3BasLn1,t3Label1$,yellow) CALL SuperSubScriptRJ(t3Eqx,t3BasLn2,t3Label2$,yellow) END SUB SUB t3SetRoots LOCAL r$,i$,z$ CALL t3Clear IF abs(z)<1 then CALL Roots(real,imag,im1,im2) LET si1 = sgn(im1) LET s1$ = " + " LET si2 = sgn(im2) LET s2$ = " - " LET r$ = using$("-%.##",real*w) LET i1$ = using$("%.##",abs(im1*w)) LET i2$ = using$("%.##",abs(im2*w)) LET txt1$ = r$ & s1$ & i1$ & " i" LET txt2$ = r$ & s2$ & i2$ & " i" CALL PlotTextLJ(t3Eqx,t3BasLn1,txt1$,yellow) CALL PlotTextLJ(t3Eqx,t3BasLn2,txt2$,yellow) ELSE CALL RealRoots(r1,r2) LET r1$ = using$("-%.##",r1*w) LET r2$ = using$("-%.##",r2*w) LET txt1$ = r1$ LET txt2$ = r2$ CALL PlotTextLJ(t3Eqx,t3BasLn1,txt1$,yellow) CALL PlotTextLJ(t3Eqx,t3BasLn2,txt2$,yellow) END IF END SUB SUB t3Clear BOX CLEAR t3Eqx-2,t3Rgt,t3Bas,t3Top END SUB SUB t3Init CALL t3Label CALL t3SetRoots END SUB ! --- t4 text rectangle - rollover t,x values --- LET t4BasLn1= w3Top + 8 LET t4BasLn2= t4BasLn1 + 20 LET t4Lft = t2Lft LET t4Rgt = t4Lft + 100 LET t4Bas = t4BasLn2 + 5 LET t4Top = t4BasLn1 - 15 LET t4Clr = litgry LET t4Label1$= "t = " LET t4Label2$= "x = " CALL StringWidth(t4Label2$,sw) LET t4Eqx= t4Lft + sw SUB t4Label CALL SuperSubScriptRJ(t4Eqx,t4BasLn1,t4Label1$,t4Clr) CALL SuperSubScriptRJ(t4Eqx,t4BasLn2,t4Label2$,cyan) END SUB SUB t4SetCoords LET t = w1Fncx(mx) LET x = w1Fncy(my) LET t$= trim$(using$("--%.##",t)) LET x$= trim$(using$("--%.##",x)) CALL t4Clear CALL PlotTextLJ(t4Eqx,t4BasLn1,t$,t4Clr) CALL PlotTextLJ(t4Eqx,t4BasLn2,x$,cyan) END SUB SUB t4Clear BOX CLEAR t4Eqx-2,t4Rgt,t4Bas,t4Top END SUB SUB t4Init CALL t4Label END SUB ! --- default parameters --- LET w,oldw = 1 ! natural frequency & root modulus LET z,oldz = 0.2 ! damping ratio LET x0,oldx0= 1 ! initial values LET v0,oldv0= 0 LET zmBtn= 1 ! --- Draw the screen --- CALL InitScreen SUB InitScreen BOX CLEAR worklft,workrgt,workbas,worktop CALL w1Init CALL w2Init CALL w3Init CALL v1Init CALL h1Init CALL h2Init CALL h3Init CALL t1Init CALL t2Init CALL t3Init CALL t4Init CALL ZoomInit CALL w1Wave CALL w2PlotInitialValues CALL w3DrawRoots END SUB ! ----------------- Event manager ----------------- DO LET w1Clear= 0 DO GET MOUSE: mx,my,ms IF w1wWithin(mx,my)=true then IF oldmx<>mx or oldmy<>my then CALL w1RollOver END IF ELSE IF w1Clear=1 then CALL w1RollOverClear END IF LOOP until ms=2 ! mouse down? IF w1wWithin(mx,my)=true then DO GET MOUSE: mx,my,ms IF w1wWithin(mx,my)=true then IF oldmx<>mx or oldmy<>my then CALL w1RollOver END IF ELSE IF w1Clear=1 then CALL w1RollOverClear END IF LOOP until ms=3 IF w1Clear=1 then CALL w1RollOverClear ELSE IF w2wWithin(mx,my)=true then CALL w2MouseDrag(mx,my) ELSE IF v1Within(mx,my)=true then ! x0 IF mx=zmLft and mx<=zmRgt and my>=zmTop and my<=zmBas then LET zmBtn= int((my-zmTop)/zmStp) LET t = zmTop + zmBtn*zmStp LET b = t + zmHgt CALL MouseButtonUp(zmLft,zmRgt,b,t,ms) CALL Zoom CALL w1Wave ELSE IF infoWithin(mx,my,ms)=true then CALL infoButtonUp(ms) CALL InfoPage(Info$) CALL InitScreen ELSE IF quitWithin(mx,my,ms)=true then CALL quitButtonUp(ms) EXIT SUB ELSE CALL MouseUp(mx,my,ms) END IF LOOP ! --- Mouse Event Methods --- SUB w1RollOver ! cross hairs and cursor values CALL w1ShowGraphLayer SET COLOR litmid PLOT mx,w1Top+1; mx,w1Bas-1 SET COLOR cyan PLOT w1Lft+1,my; w1Rgt-1,my CALL t4SetCoords LET w1Clear= 1 CALL CopyCoords(mx,my,oldmx,oldmy) END SUB SUB w1RollOverClear CALL w1ShowGraphLayer LET w1Clear= 0 CALL t4Clear END SUB ! --- initial value events --- SUB ResetInitialValues CALL w1Wave CALL w2PlotInitialValues END SUB ! --- w2 - v0 and x0 --- SUB w2MouseDrag(mx,my) DO CALL w2GetDragValues(mx,my,ms,2,2,x0,v0) IF x0<>oldx0 or v0<>oldv0 then CALL ResetInitialValues CALL h1Mark(x0) CALL v1Mark(v0) CALL CopyCoords(x0,v0,oldx0,oldv0) END IF LOOP until ms=3 END SUB ! --- v1 - v0 --- SUB v1MouseClick(mx,my) LET oldv0= 999 CALL v1GetClickVal(ms,v1Click,v0) CALL v1Action END SUB SUB v1MouseDrag(mx,my) DO CALL v1GetDragVal(ms,v1Places,v0) CALL v1Action LOOP until ms=3 END SUB SUB v1Action IF v0<>oldv0 then CALL ResetInitialValues LET oldv0= v0 END IF END SUB ! --- h1 - x0 --- SUB h1MouseClick(mx,my) LET oldx0= 999 CALL h1GetClickVal(ms,h1Click,x0) CALL h1Action END SUB SUB h1MouseDrag(mx,my) DO CALL h1GetDragVal(ms,h1Places,x0) CALL h1Action LOOP until ms=3 END SUB SUB h1Action IF x0<>oldx0 then CALL ResetInitialValues LET oldx0= x0 END IF END SUB ! --- end of initial value events --- ! --- root events --- SUB ResetRootValues CALL w1Wave CALL t3SetRoots CALL w3DrawRoots END SUB ! --- h2 zeta --- SUB h2MouseClick(mx,my) CALL h2GetClickVal(ms,h2Click,z0) CALL h2Action END SUB SUB h2MouseDrag(mx,my) DO CALL h2GetDragVal(ms,h2Places,z0) CALL h2Action LOOP until ms=3 END SUB SUB h2Action LET z= -z0 IF z<>oldz then IF w=0 then CALL t3SetRoots CALL w3DrawRoots ELSE CALL ResetRootValues END IF LET oldz= z END IF END SUB ! --- h3 w0 --- SUB h3MouseClick(mx,my) CALL h3GetClickVal(ms,h3Click,w) CALL h3Action END SUB SUB h3MouseDrag(mx,my) DO CALL h3GetDragVal(ms,h3Places,w) CALL h3Action LOOP until ms=3 END SUB SUB h3Action IF w<>oldw then CALL ResetRootValues LET oldw= w END IF END SUB ! --- end of root events --- ! ------ Graph drawing methods ------ SUB w1Wave CALL SetConstants CALL w1ShowGridLayer LET az= abs(z) IF az=1 then ! critical LET y= fc(0) ELSE IF az<1 then ! under LET y= fu(0) ELSE ! over LET y= fo(0) END IF CALL CopyCoords(w1Lft,w1Wndy(y),oldwx,oldwy) SET COLOR waveclr FOR wx= w1Lft to w1Rgt step 2 LET x = w1Fncx(wx) IF az=1 then LET y= fc(x) ELSE IF az<1 then LET y= fu(x) ELSE LET y= fo(x) END IF LET wy= w1Wndy(y) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! one above and one below IF wy>oldwy then PLOT oldwx,w1top+1; wx,w1bas-1 ELSE PLOT wx,w1top+1; oldwx,w1bas-1 END IF END IF CALL CopyCoords(wx,wy,oldwx,oldwy) NEXT wx CALL w1KeepGraphLayer END SUB SUB w2PlotInitialValues CALL w2ShowGridLayer CALL w2MathToPixels(x0,v0,wx,wy) CALL PlotDiamondClr(wx,wy,white) END SUB SUB w3DrawRoots CALL w3ShowGridLayer LET az= abs(z) IF az<1 then ! complex roots CALL Roots(real,imag,im1,im2) LET wr = w3Wndx(-z) ! complex points LET wi1= w3Wndy(im1) LET wi2= w3Wndy(im2) SET COLOR litmid ! modulus PLOT wr,wi1; wr,wi2 LET wr = w3Wndx(-z) ! complex points LET wi1= w3Wndy(im1) LET wi2= w3Wndy(im2) SET COLOR litmid ! modulus PLOT w3x0,w3y0; wr,wi1 PLOT w3x0,w3y0; wr,wi2 PLOT wr,wi1; wr,wi2 LET wr = w3Wndx(w*real) ! scaled complex points LET wi1= w3Wndy(w*im1) LET wi2= w3Wndy(w*im2) SET COLOR litmid ! modulus PLOT w3x0,w3y0; wr,wi1 PLOT w3x0,w3y0; wr,wi2 LET wr = w3Wndx(-z) ! complex points CALL PlotDiamondClr(wr,w3y0,green) LET wr = w3Wndx(w*real) ! complex points LET wi1= w3Wndy(w*im1) LET wi2= w3Wndy(w*im2) CALL PlotDiamondClr(wr,wi1,rootclr) CALL PlotDiamondClr(wr,wi2,rootclr) ELSE ! real roots CALL RealRoots(r1,r2) LET wz = w3Wndx(-z) ! -z value IF az=1 then ! one real root CALL PlotDiamondClr(wz,w3y0,green) LET wr= w3Wndx(r1*w) CALL PlotDiamondClr(wr,w3y0,rootclr) ELSE CALL PlotDiamondClr(wz,w3y0,green) LET wr1 = w3Wndx(r1*w) LET wr2 = w3Wndx(r2*w) CALL PlotDiamondClr(wr1,w3y0,rootclr) CALL PlotDiamondClr(wr2,w3y0,rootclr) END IF END IF END SUB END SUB ! --- end of damping ratio code -------------