!! File: Initial Conditions !! 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 colorscheme= 0 LET title$= "Initial Conditions" SUB ThisProgram CALL InitialConditions 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 --- !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 ------ ! ----------------------------------------------------------- ! *** SUB InitialConditions DECLARE PUBLIC black,drkgry,drkmid,midgry,litmid,litgry,white DECLARE PUBLIC red,yellow,green,cyan,blue,magenta DECLARE PUBLIC axislabelclr,slideclr DECLARE PUBLIC workLft,workRgt,workBas,workTop,workMidx DECLARE PUBLIC true,false DECLARE DEF quitWithin,infoWithin ! --- help screen array --- DIM info$(1:1) MAT READ info$ DATA "Initial Conditions" ! --- color definition and adjustment --- LET pdclr = green LET ivclr = yellow LET fldclr= drkmid LET posclr= yellow LET velclr= cyan LET trclr = blue SET COLOR MIX(blue) .4,.6,1 ! ---------- Utility functions --- DECLARE DEF clamp,roundn,e ! ---- Functions ---- LET dt= 1/64 DEF dxdt(p,v)= v DEF dvdt(p,v)= -b*v - k*p + cos(omega*t) ! I have three signals in mind ! 0 , cos(omega t) , and sq(omega t) ! There are two basic solutions to the "homogeneous equation" ! x" + bx' + kx = 0 ! y(t) with y(0) = 1 and y'(0) = 0 ! z(t) with z(0) = 0 and z'(0) = 1 SUB SetW(b,k, w) LET w= sqr(abs((b/2)^2 - k)) END SUB SUB SetCritDamp(k,critDamp) LET critDamp= sqr(4*k) END SUB SUB SetNatFreq(k,natFreq) LET natFreq= sqr(k) END SUB SUB SetD(b,k,omega, D) LET D= (k-omega^2)^2 + omega^2*b^2 END SUB SUB SetRS(b,w, r,s) LET r= -b/2 + w LET s= -b/2 - w END SUB SUB SetVars CALL SetW(b,k, w) CALL SetD(b,k,omega, D) CALL SetRS(b,w, r,s) CALL SetCritDamp(k, critDamp) LET b2= b*b LET k4= k*4 END SUB SUB InitialVals(b,k,omega,D, fxp0,dxp0) LET fxp0= (k-omega^2)/D LET dxp0= -(omega^2*b)/D END SUB SUB InitialDifs LET deltax= fx0-fxp0 LET deltad= dx0-dxp0 END SUB DEF y(t) ! velocity ? IF b>critDamp then LET y= 1/(s-r) * (s*e^(r*t) - r*e^(s*t)) ELSE IF bcritDamp then LET z= -1/(s-r) * (e^(r*t) - e^(s*t)) ELSE IF b2 then CALL MouseDown(mx,my,ms) END IF ! mouse down event ! window IF w3Within(mx,my)=true then LET oldmx,oldmy= -999 ! CALL MouseUp(mx,my,ms) ! CALL Orbit(fx0,dx0) CALL w1xpGraph DO GET MOUSE: mx,my,ms IF mx<>oldmx or my<>oldmy then CALL w3wClamp(mx,my) CALL w3PixelsToMath(mx,my,dx0,fx0) CALL w1PlaneGraphs CALL CopyCoords(mx,my,oldmx,oldmy) END IF LOOP until ms=3 ! sliders ELSE IF h2Within(mx,my)=true then ! b IF mycb1Lft and mxcb1Top and my=cllft and mx<=clrgt and my>=cltop and my<=clbas then ! clear CALL MouseButtonUp(clLft,clRgt,clBas,clTop,ms) CALL ShowGraphLayers 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 ShowGridLayers CALL w1ShowGridLayer CALL w3ShowGridLayer END SUB SUB KeepGraphLayers CALL w1KeepGraphLayer CALL w3KeepGraphLayer END SUB SUB ShowGraphLayers CALL w1ShowGraphLayer CALL w3ShowGraphLayer END SUB SUB MarkCritDamp(k) CALL SetCritDamp(k, critDamp) LET wcd = h2Wndx(critDamp) LET cdTop= h2wBas+2 CALL ValueMarker(h2wLft,h2wRgt,wcd,cdtop,litgry) END SUB SUB MarkNatFreq(k) CALL SetNatFreq(k, natFreq) LET wcd = h5Wndx(natFreq) LET cdTop= h5wBas+2 CALL ValueMarker(h5wLft,h5wRgt,wcd,cdtop,litgry) END SUB SUB ValueMarker(wLft,wRgt,wx,wTop,clr) SET COLOR litgry LET wBas= wTop+6 BOX CLEAR wLft-5,wRgt+5,wBas,wTop PLOT wx,wTop; wx,wBas PLOT wx,wTop; wx+2,wTop+2; wx-2,wTop+2; wx,wTop END SUB ! ----- h2 slider event ----- SUB h2MouseClick CALL h2GetClickVal(ms,h2Click,b) CALL H2Action CALL KeepGraphLayers END SUB SUB h2MouseDrag DO CALL h2GetDragVal(ms,h2Places,b) CALL h2Action LOOP until ms=3 CALL KeepGraphLayers END SUB SUB h2Action IF b<>oldb then CALL w1SliderGraphs LET oldb= b END IF END SUB ! ----- h3 slider event ----- SUB h3MouseClick CALL h3GetClickVal(ms,h3Click,k) CALL h3Action CALL KeepGraphLayers END SUB SUB h3MouseDrag DO CALL h3GetDragVal(ms,h3Places,k) CALL h3Action LOOP until ms=3 CALL KeepGraphLayers END SUB SUB h3Action IF k<>oldk then IF critMarks=1 then CALL MarkCritDamp(k) CALL MarkNatFreq(k) END IF CALL w1SliderGraphs LET oldk= k END IF END SUB ! ----- h5 slider event ----- SUB h5MouseClick CALL h5GetClickVal(ms,h5Click,omega) CALL h5Action END SUB SUB h5MouseDrag DO CALL h5GetDragVal(ms,h5Places,omega) CALL h5Action LOOP until ms=3 END SUB SUB h5Action IF omega<>oldomega then IF omega<>oldomega then CALL w1SliderGraphs LET oldomega= omega END IF END IF END SUB ! ----- periodic solution ----- SUB w1xpGraph CALL SetVars CALL ShowGridLayers IF ssFlag=1 then IF D<>0 then CALL InitialVals(b,k,omega,D, fxp0,dxp0) CALL w3MathToPixels(dxp0,fxp0,wx,wy) CALL t2Set IF w3wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,pdclr) END IF SET COLOR pdclr LET oldwy= w1Wndy(xp(0)) LET oldwx= w1Lft FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = xp(t) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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 PLOT ELSE CALL w1ShowGridLayer END IF ELSE CALL w1ShowGridLayer END IF CALL KeepGraphLayers END SUB SUB w1SliderGraphs CALL SetVars CALL ShowGridLayers IF D<>0 then CALL InitialVals(b,k,omega,D, fxp0,dxp0) CALL w3MathToPixels(dxp0,fxp0,wx,wy) CALL InitialDifs IF ssFlag=1 then CALL t2Set IF w3wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,pdclr) END IF END IF IF slFlag=1 or trFlag=1 then CALL t3Set CALL w3MathToPixels(dx0,fx0,wx,wy) IF w3wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,yellow) END IF END IF IF ssFlag=1 then SET COLOR pdclr LET oldwy= w1Wndy(xp(0)) LET oldwx= w1Lft FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = xp(t) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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 PLOT END IF IF slFlag=1 then SET COLOR yellow LET oldwy= w1Wndy(fx(0)) LET oldwx= w1Lft FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = fx(t) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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 PLOT END IF IF trFlag=1 then SET COLOR trclr LET oldwy= w1Wndy(fx(0)) LET oldwx= w1Lft FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = tr(t) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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 PLOT END IF END IF END SUB SUB w1PlaneGraphs CALL SetVars CALL ShowGraphLayers IF D<>0 then IF slFlag=1 or trFlag=1 then CALL InitialVals(b,k,omega,D, fxp0,dxp0) CALL InitialDifs CALL t3Set CALL w3MathToPixels(dx0,fx0,wx,wy) IF w3wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,yellow) END IF END IF IF slFlag=1 then SET COLOR yellow LET oldwy= w1Wndy(fx(0)) LET oldwx= w1Lft FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = fx(t) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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 PLOT END IF IF trFlag=1 then SET COLOR trclr LET oldwy= w1Wndy(fx(0)) LET oldwx= w1Lft FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = tr(t) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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 PLOT END IF END IF END SUB ! ----- transient solution ----- SUB MatchxpGraph ! LET fx0= fxp0 ! LET dx0= dxp0 CALL t3Set CALL w1xGraph END SUB SUB w1xGraph IF slFlag=1 or trFlag=1 then CALL SetVars IF D<>0 then CALL InitialDifs CALL w3MathToPixels(dx0,fx0,wx,wy) CALL w3ShowGraphLayer IF w3wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,yellow) END IF SET COLOR yellow LET oldwy= w1Wndy(fx(0)) LET oldwx= w1Lft CALL w1ShowGraphLayer FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = fx(t) LET wy= w1Wndy(x) IF slFlag=1 then SET COLOR yellow IF wy>w1Top and wyw1Top and oldwyw1Top and wyw1Top and oldwyw1Bas and oldwyw1Top) then ! above and 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) END IF IF trFlag=1 then SET COLOR trclr LET x = tr(t) ! transient !! LET wy= w1Wndy(x) IF wy>w1Top and wyw1Rgt then EXIT DO IF wpy>w1Top and wpyw1Top and oldpy0 or dy<>0 then LET ang= angle(dx,-dy) LET wx1= wx + 8*cos(ang) LET wy1= wy + 8*sin(ang) PLOT wx,wy; wx1,wy1 CALL VectorHead(ang,wx,wy,wx1,wy1) END IF NEXT wx NEXT wy END IF CALL w3KeepGraphLayer END SUB SUB VectorHead(ang,wx,wy,wvx0,wvy0) CALL SetVMat(ang) CALL RotateTranslate(6, 2,wx,wy,wvx1,wvy1) CALL RotateTranslate(6,-2,wx,wy,wvx2,wvy2) PLOT wvx1,wvy1; wvx0,wvy0; wvx2,wvy2 END SUB SUB Rotate(xin,yin,xout,yout) LET xout= xin*vcta + yin*vctb LET yout= xin*vctc + yin*vctd END SUB SUB RotateTranslate(xin,yin,h,v,xout,yout) LET xout= xin*vcta + yin*vctb + h LET yout= xin*vctc + yin*vctd + v END SUB SUB SetVMat(ang) LET vcta= cos(ang) LET vctc= sin(ang) LET vctb= -vctc LET vctd= vcta END SUB END SUB ! --- end of mass spring code -------------------