! b= 0 and k= 1 - big mess ! Initial Conditions: the x-dot(0) display should be yellow, not blue. ! Let's rename "initial conditions" "Transients." ! I think we might as well leave it in terms of b and k ! (rather than switch to omega_n and zeta). ! But it would be nice to add a crosshair and readout ! rollover, as on the Damping Ratio tool. ! Transients ! ! The solutions to a second order LTI equation with sinusoidal signal is ! represented as a superposition of steady state (or periodic solution) ! and transient. ! ! The mass is normalized to one. Sliders at bottom left set the spring ! constant k and the damping constant b, and a slider at bottom center ! sets the circular frequency of the signal. ! ! Initial conditions are controlled by a mouse click on the window at ! upper right, which records the initial position vertically and the ! initial velocity horizontally. The selected value is recorded by a ! yellow diamond and by a yellow readout at upper left. ! ! Buttons at lower right control what is displayed in the graphing window ! at upper right: Steady State (green), Transient (blue), and Solution (yellow). ! Rolling the cursor over this window causes crosshairs to appear and the ! values of t and x to be read out. ! ! If the Steady State is selected for display, its initial value is also ! recorded by a green diamond in the upper left window and a green readout ! at upper left. !! 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$= "Transients" 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:16) MAT READ info$ DATA "Transients" DATA "" DATA "The solution to a second order LTI equation with sinusoidal signal is represented as a superposition of steady state (or periodic solution) and transient." DATA "" DATA "The mass is normalized to one." DATA "Click or drag the k slider handle to set the spring constant." DATA "Click or drag the b slider handle to set the damping constant." DATA "Click or drag the omega slider handle to set the circular frequency of the signal." DATA "Click or drag the mouse on the initial conditions plane to the left to set values for the initial velocity and initial position." DATA "The selected coordinate values for initial velocity and initial position are shown in the plane by a yellow diamond and below the right side of the plane as values." DATA "Buttons at lower right control the graphs to be displayed in the time series plane to the right." DATA "Click the Solution check box to toggle the graph of the solution on and off." DATA "Click the Transient check box to toggle the graph of the transient solution on and off." DATA "Click the Steady State check box to toggle the graph of the steady state solution on and off." DATA "When the Steady State is on, its initial values are shown on the initial value plane by a green diamond and below the left side of the plane as values." DATA "Roll the cursor over the time series plane to display crosshairs and the corresponding the values of t and x." ! --- color definition and adjustment --- LET pdclr = green LET ivclr = yellow LET fldclr= drkmid LET posclr= yellow LET velclr= litgry LET trclr = blue LET ssclr = green 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 LET clearFlag= 0 BOX KEEP w1Lft,w1Rgt,w1Bas,w1Top in temp$ DO GET MOUSE: mx,my,ms IF w1Within(mx,my)=true then CALL w1RollOver ELSE IF clearFlag=1 then CALL w1RollOverClear END IF LOOP until ms=2 END IF IF clearFlag=1 then CALL w1RollOverClear END IF ! mouse down events ! window IF w2Within(mx,my)=true then LET oldmx,oldmy= -999 CALL w1xpGraph DO GET MOUSE: mx,my,ms CALL w2wClamp(mx,my) IF mx<>oldmx or my<>oldmy then CALL w2MouseClickOrDrag END IF LOOP until ms=3 ! sliders ELSE IF v1Within(mx,my)=true then ! b CALL w1xpGraph IF mxcb1Lft 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 w2ShowGridLayer END SUB SUB KeepGraphLayers CALL w1KeepGraphLayer CALL w2KeepGraphLayer END SUB SUB ShowGraphLayers CALL w1ShowGraphLayer CALL w2ShowGraphLayer END SUB SUB w1RollOver CALL w1wClamp(mx,my) IF mx<>oldmx or my<>oldmy then BOX SHOW temp$ at w1Lft,w1Bas CALL PlotLine(mx,w1Top+1, mx,w1Bas-1, litmid) CALL PlotLine(w1Lft+1,my, w1Rgt-1,my, litmid) LET t= w1Fncx(mx) LET x= fx(t) CALL t4Init LET oldmx= mx LET oldmy= my LET clearFlag= 1 END IF END SUB SUB w1RollOverClear CALL t4Clear BOX SHOW temp$ at w1Lft,w1Bas LET clearFlag= 0 END SUB SUB w2MouseClickOrDrag LET oldmx,oldmy= -999 DO GET MOUSE: mx,my,ms CALL w2wClamp(mx,my) IF mx<>oldmx or my<>oldmy then CALL w2PixelsToMath(mx,my,dx0,fx0) CALL v1Mark(fx0) CALL h1Mark(dx0) CALL w2Point(dx0,fx0) CALL w1PlaneGraphs CALL CopyCoords(mx,my,oldmx,oldmy) LET olddx0= dx0 LET oldfx0= fx0 END IF LOOP until ms=3 END SUB SUB w2Point(vel,pos) CALL w2ShowGridLayer CALL t3Set CALL w2MathToPixels(vel,pos,wx,wy) CALL PlotDiamondClr(wx,wy,yellow) END SUB ! ----- v1 slider event ----- SUB v1MouseClick CALL v1GetClickVal(ms,v1Click,fx0) CALL v1Action END SUB SUB v1MouseDrag DO CALL v1GetDragVal(ms,v1Places,fx0) CALL v1Action LOOP until ms=3 END SUB SUB v1Action IF fx0<>oldfx0 then CALL v1Mark(fx0) CALL w1PlaneGraphs LET oldfx0= fx0 END IF END SUB ! ----- h1 slider event ----- SUB h1MouseClick CALL h1GetClickVal(ms,h1Click,dx0) CALL h1Action END SUB SUB h1MouseDrag DO CALL h1GetDragVal(ms,h1Places,dx0) CALL h1Action LOOP until ms=3 END SUB SUB h1Action IF dx0<>olddx0 then CALL h1Mark(dx0) CALL w1PlaneGraphs LET olddx0= dx0 END IF 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 SUB MarkCritDamp(k) CALL SetCritDamp(k, critDamp) LET wcd = h2Wndx(critDamp) LET cdTop= h2wBas+2 CALL ValueMarker(h2wLft,h2wRgt,wcd,cdtop,litgry) 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 SUB MarkNatFreq(k) CALL SetNatFreq(k, natFreq) LET wcd = h4Wndx(natFreq) LET cdTop= h4wBas+2 CALL ValueMarker(h4wLft,h4wRgt,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 ! ----- h4 slider event ----- SUB h4MouseClick CALL h4GetClickVal(ms,h4Click,omega) CALL h4Action END SUB SUB h4MouseDrag DO CALL h4GetDragVal(ms,h4Places,omega) CALL h4Action LOOP until ms=3 END SUB SUB h4Action 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 w2MathToPixels(dxp0,fxp0,wx,wy) CALL t2Set IF w2wWithin(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 w2MathToPixels(dxp0,fxp0,wx,wy) CALL InitialDifs IF ssFlag=1 then CALL t2Set IF w2wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,pdclr) END IF END IF IF slFlag=1 or trFlag=1 then CALL t3Set CALL w2MathToPixels(dx0,fx0,wx,wy) IF w2wWithin(wx,wy)=true then CALL PlotDiamondClr(wx,wy,yellow) END IF END IF IF ssFlag=1 then ! steady state SET COLOR pdclr CALL CopyCoords(w1Lft,w1Wndy(xp(0)),oldwx,oldwy) 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 the plane 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 ! solution SET COLOR yellow CALL CopyCoords(w1Lft,w1Wndy(fx(0)),oldwx,oldwy) 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 ! transient SET COLOR trclr CALL CopyCoords(w1Lft,w1Wndy(fx(0)),oldwx,oldwy) 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 w2MathToPixels(dx0,fx0,wx,wy) IF w2wWithin(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 CALL t3Set CALL w1xGraph END SUB SUB w1xGraph IF slFlag=1 or trFlag=1 then CALL SetVars IF D<>0 then CALL InitialDifs CALL w2MathToPixels(dx0,fx0,wx,wy) CALL w2ShowGraphLayer IF w2wWithin(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 w2KeepGraphLayer 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 -------------------