! I was just playing with some of the tools, which I will domo for ! Dan Freedman's class tomorrow. Isoclines has a bug! - and could ! use some work anyway. ! ! The bug occurs when x' = x(1-x) . Try dragging c; the program vanishes. ! I am using the sunos implementation; I don't know whether that matters. ! ! While we are about it, though, let's simplify a little, and make the ! display under the c slider just say x' = c for each of the cases. ! Those solutions are misleading. !Isoclines: I hadn't noticed the equation for the isocline in terms !of c before. I don't think this is a good idea; I'd prefer to have !the students think of the isocline as given by the EQUATION y' = c, !rather than solving explicity for y as a function of x. ! !Hubbard and West at Cornell wanted their students to attend to !how to draw the graph of the isocline as a function of t. Whatever !students need to know in an engineering context is fine with me. Perhaps !the equations for isoclines is not an issue. I will kill the equations for !the isocline and put the generic "y' = c" for all examples. ! needs homemade pointers everywhere ! last example - use plotlines? ! do we need heads on arrows if they only designate slope? ! does direction matter? ! needed for visibility? use triple weight lines instead? !! File: Isoclines !! 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$ = "Isoclines" SUB ThisProgram CALL Isoclines CLEAR END SUB !! --------------------------------------------------------- !! ------ Start TB4 Mac Header and Subs ------ !LET M68KFlag = 1 !LIBRARY "MacTools*", "HHLib.trc" !ASK PIXELS winWid,winHgt !LET winLft= 0 !LET winTop= 0 !LET winRgt= winWid-1 !LET winBas= winHgt-1 !SET WINDOW 0,winRgt,winBas,0 !CALL Palette !CLEAR ! !CALL ToolPanel !CALL ThisProgram ! !END !EXTERNAL ! !MODULE Mac4Parts ! SUB SetTextFont(font,size,style$) ! CALL MacTextFont(font) ! CALL MacTextSize(size) ! CALL MacTextFace(style$) ! END SUB ! ! SUB StringWidth(sw$,sl) ! DECLARE DEF MacStringWidth ! LET sl= MacStringWidth(sw$) ! END SUB ! ! SUB SetLineWeight(wgt) ! CALL MacPenSize(wgt,wgt) ! END SUB ! ! SUB BoxDisk(Lft,Rgt,Bas,Top) ! CALL MacPaintOval(Lft,Rgt,Bas,Top) ! END SUB !END MODULE !! --- End TB4 Mac Header and Subs --- !!--------------------------------------------------------- !!--- Start TB5 Cross-Platform header and subs --- LIBRARY "c:\TB Gold\TBLibs\TrueCtrl.trc" ! windows LIBRARY "c:\TB Gold\TBLibs\HHLib.trc" !LIBRARY ":TBLibs:TrueCtrl.trc" ! macintosh !LIBRARY "HHLib.trc" ! PUBLIC WinID DECLARE PUBLIC OBJM_SET,OBJM_SYSINFO LET winHgt= toolHgt LET winWid= toolWid DIM values(1) CALL TC_Init CALL Object(OBJM_SYSINFO,WinID,"MACHINE",system$,values()) IF system$="MAC" then LET Mac5Flag= 1 ELSE IF system$="WIN32" then LET PCFlag = 1 END IF CALL TC_SetUnitsToPixels ! 5.1 and up needs this CALL TC_GetScreenSize(scrnLft,scrnRgt,scrnBas,scrnTop) LET winLft= int((scrnRgt-scrnLft-winWid)/2) LET winRgt= winLft+winWid-1 LET winTop= int((scrnBas-scrnTop-winHgt)/2) + 10 LET winBas= winTop+winHgt-1 CALL TC_Win_Create (WinID,"TITLE",winLft,winRgt,winBas,winTop) LET values(1)= 2 CALL Object(OBJM_SET, WinID, "TYPE", "", values()) IF PCFlag=1 then ! kill dithering LET values(1)= 1 CALL Object(OBJM_SET, WinID, "SOLID MIX", "", values()) END IF LET values(1)= 0 CALL TC_SetRect(WinID,winLft,winRgt,winBas,winTop) CALL TC_Win_SetTitle(WinID,window$) CALL TC_Show(WinID) SET MODE "COLORSTANDARD" ASK PIXELS winWid,winHgt ! must follow set mode LET winLft= 0 LET winTop= 0 LET winRgt= winWid-1 LET winBas= winHgt-1 SET WINDOW 0,winRgt,winBas,0 CALL Palette IF PCFlag=1 then LET values(1)= 0 ! now force solid colors CALL Object(OBJM_SET, WinID, "SOLID MIX", "", values()) CALL TC_Win_RealizePalette(WinID) ! some PCs need this CALL TC_Win_SetFont(WinID,"arial",9,"plain") CALL StringWidth("0",sw) IF sw>7 then LET largefonts=1 else LET largefonts=0 END IF CALL TC_Win_Switch(WinID) CALL ToolPanel CALL ThisProgram CALL SetTextFont(1,12,"bold") ! now shut down and clean up LET quit$= "click the mouse or press a key to close..." CALL PlotTextCJ(workmidx,(workbas+worktop)/2,quit$,yellow) CALL TC_CleanUp END EXTERNAL MODULE TB5Parts SUB StringWidth(sw$,sl) DECLARE PUBLIC WinID LET sl= StrWidth(WinID,sw$) END SUB SUB SetLineWeight(wgt) DECLARE PUBLIC OBJM_SET DECLARE PUBLIC WinID DIM values(1) LET values(1)= wgt CALL Object(OBJM_SET,WinID, "WIDTH", "", values()) END SUB SUB SetTextFont(font,size,style$) DECLARE PUBLIC WinID,Mac5Flag,PCFlag,largefonts IF Mac5Flag=1 then SELECT CASE font CASE 4 LET font$= "Courier" CASE 16 LET font$= "Times" CASE else LET font$= "Geneva" END SELECT ELSE IF PCFlag=1 then IF largefonts=1 then IF size<12 then LET size= 6 ELSE IF size=14 then LET size= 10 ELSE IF size=18 then LET size= 12 ELSE IF size=24 then LET size= 14 ELSE IF size=12 then LET size= 8 ELSE LET size= round(72/96 * size * .8) END IF ELSE IF size<12 then LET size= 7 ELSE IF size=14 then LET size= 12 ELSE IF size=12 then LET size= 9 ELSE IF size=18 then LET size= 14 ELSE IF size=24 then LET size= 18 ELSE LET size= round(72/96 * size) END IF END IF SELECT CASE font CASE 4 LET font$= "Courier New" CASE 16 LET font$= "Times New Roman" CASE else LET font$= "Verdana" END SELECT END IF IF style$= "normal" then LET style$= "plain" CALL TC_Win_SetFont(WinID,font$,size,style$) END SUB SUB BoxDisk(Lft,Rgt,Bas,Top) BOX DISK Lft,Rgt,Bas,Top END SUB END MODULE ! --- End TB5 Cross-platform header and subs --- !! --------------------------------------------------------- !! --- Start Unix Header and Subs --- !library "HHLib.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 Isoclines DECLARE PUBLIC workLft,workRgt,workBas,workTop,workMidx ! work area DECLARE PUBLIC black,drkgry,drkmid,midgry,litmid,litgry,white DECLARE PUBLIC red,yellow,green,cyan,blue,magenta,colorscheme DECLARE PUBLIC slideclr,axisclr,axislabelclr,true,false DECLARE DEF quitWithin, infoWithin ! --- info page --- DIM Info$(1:15) MAT READ Info$ DATA "Isoclines" DATA "" DATA "This tool supports visual exploration of isoclines, curves in the tx-plane along which the solution slopes are equal." DATA "" DATA "Drag the slider handle or click above the slider axis to change C and draw isoclines." DATA "" DATA "Click the (t,x) plane to draw solutions." DATA "" DATA "Click the pop-up menu button [v] to open the list of equations." DATA "Click an equation to select it." DATA "" DATA "Click [ ] Slope Field to toggle the slope field on or off." DATA "Click [Clear All] to remove solutions and isoclines from the plane." DATA "Click [Clear Solutions] to remove solutions from the plane." DATA "Click [Clear Isoclines] to remove isoclines from the plane." ! --- utility functions --- DECLARE DEF clamp,roundn,e LET bignum= 10^10 DEF SetColor(n) = red + n ! --- Functions --- ! Equation list panel LET eqcnt= 6 DEF dxdt1(t,x) = 1 DEF dydt1(t,x) = x*(1-x) DEF dxdt2(t,x) = 1 DEF dydt2(t,x) = t-2*x DEF dxdt3(t,x) = 1 DEF dydt3(t,x) = x*x-t DEF dxdt4(t,x) = 1 DEF dydt4(t,x) = x*x-t*t DEF dxdt5(t,x) = 1 DEF dydt5(t,x) = -t/x DEF dxdt6(t,x) = 1 DEF dydt6(t,x) = x/t SUB FetchEq(eq,t,x,dx,dy) SELECT CASE eq CASE 1 LET dx= dxdt1(t,x) LET dy= dydt1(t,x) CASE 2 LET dx= dxdt2(t,x) LET dy= dydt2(t,x) CASE 3 LET dx= dxdt3(t,x) LET dy= dydt3(t,x) CASE 4 LET dx= dxdt4(t,x) LET dy= dydt4(t,x) CASE 5 IF x<>0 then LET dx= dxdt5(t,x) LET dy= dydt5(t,x) ELSE LET dx= 1 LET dy= bignum END IF CASE 6 IF t<>0 then LET dx= dxdt6(t,x) LET dy= dydt6(t,x) ELSE LET dx= 1 LET dy= bignum END IF END SELECT IF dy=99999 then LET err= 1 else LET err= 0 END SUB ! Graphing window LET wsize = 300 LET pisize= 176 ! --- 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 w1yPiFlag= 0 LET w1xMult = 1 LET w1yMult = 1 LET w1Top = worktop + 35 LET w1Bas = w1Top + 400 LET w1Lft = worklft + 70 LET w1Rgt = w1Lft + 400 LET fsz = 4 LET w1fTop = fsz LET w1fBas = -fsz LET w1fLft = -fsz LET w1fRgt = fsz LET w1xAx$= "t" ! axis labels LET w1yAx$= "x" LET w1xGridstep= 0 ! horizontal grid intervals LET w1yGridstep= 0 ! vertical grid intervals LET w1xSTik = 0.5 ! horizontal axis Tik marks LET w1xLTik = 1 LET w1xLabel= 1 LET w1xFirst= w1fLft LET w1ySTik = 0.5 ! vertical axis Tik marks LET w1yLTik = 1 LET w1yLabel= 1 LET w1yFirst= w1fBas ! --- Plane 1 methods --- DECLARE DEF w1fncx,w1fncy,w1wndx,w1wndy ! window/function transforms DECLARE DEF w1wWithin, w1fWithin, w1Within CALL w1Variables LET vrule1= w1Rgt + 70 SUB w1Init(eqnum) CALL w1Bounds(eqnum) CALL w1DrawPlane(1,1,1) ! x axis, y axis, zeroaxes CALL SetTextFont(1,12,"bold") CALL PlotTextLJ(w1Rgt+8,w1y0+3,w1xAx$,axislabelclr) ! axis labels CALL PlotTextCJ(w1x0,w1Top-10,w1yAx$,axislabelclr) CALL w1KeepGridLayer CALL w1KeepGraphLayer END SUB SUB w1Bounds(eqnum) IF eqnum=1 then LET w1fTop = 2 LET w1fBas = -1 ELSE LET w1fTop = 4 LET w1fBas = -4 END IF LET w1yFirst= w1fBas CALL w1Variables END SUB ! --- horizontal slider 1 --- DECLARE PUBLIC h1axis,h1wLft,h1wRgt,h1wBas,h1wTop,h1fLft,h1fRgt DECLARE PUBLIC h1name$,h1form$,h1clr,h1First,h1STik,h1LTik,h1Label DECLARE PUBLIC h1PiAxis,h1Mult,h1fMin,h1fMax LET h1PiAxis= 0 LET h1Mult = 1 LET h1Clr = yellow LET h1name$ = "C" LET h1form$ = "-%.###" LET h1Places= 3 LET h1axis = w1Midy-50 LET h1wLft = vrule1 + 20 LET h1wRgt = h1wLft+120 LET h1fLft = -3 ! h0flft LET h1fRgt = 3 ! h0frgt LET h1STik = 0.25 ! short tick marks LET h1LTik = 0.50 ! long tick marks LET h1Label= 1.00 ! labels LET h1First= h1fLft ! first tick mark LET h1Click= 1 DECLARE DEF h1Within ! window/function transforms CALL h1SliderVariables SUB h1Bounds(eqnum) IF eqnum=1 then LET h1fLft = -2.00 LET h1fRgt = 0.25 LET h1STik = 0.25 ! short tick marks LET h1LTik = 0.50 ! long tick marks LET h1Label= 1.00 ! labels LET h1First= -2.00 ! first tick mark LET h1Click= 0.25 ELSE LET h1fLft = -3 LET h1fRgt = 3 LET h1STik = 0.25 ! short tick marks LET h1LTik = 0.50 ! long tick marks LET h1Label= 1.00 ! labels LET h1First= h1fLft ! first tick mark LET h1Click= 0.50 END IF CALL h1SliderVariables END SUB SUB h1Init(eqnum) CALL h1Bounds(eqnum) CALL h1DrawSlider(h1name$,c) END SUB ! -------- popup menu ------- ! ----- menu parameters ----- DECLARE PUBLIC m1Lft, m1Rgt, m1Bas, m1Top, m1Equation, m1Prefix$, m1Menu1$(), m1tClr DECLARE DEF m1Within MAT redim m1Menu1$(1:eqcnt) MAT READ m1Menu1$ DATA "x(1-x)" DATA "t-2x" DATA "x^[2]-t" DATA "x^[2]-t^[2]" DATA "-t/x" DATA "x/t" LET m1Prefix$= "x' = " LET m1Lft = vrule1 LET m1Top = w1Midy + 30 LET m1tClr = cyan ! ---------- Text Output Rects ---------- ! --- t1 - dynammic output of initial conditions --- LET t1LnSpc = 20 LET t1BasLn1= w1Top + t1Lnspc LET t1BasLn2= t1BasLn1 + t1Lnspc LET t1Lft = vrule1 LET t1Rgt = t1Lft + 80 LET t1Eqx = t1Lft + 27 LET t1Dot = t1Lft + 50 LET t1Top = t1BasLn1 - 15 LET t1Bas = t1BasLn2 + 5 LET t1Clr = cyan LET t1f$ = "---%.##" SUB t1OutputLabels CALL SetTextFont(1,12,"bold") CALL PlotTextRJ(t1Eqx,t1BasLn1,"t = ",t1Clr) CALL PlotTextRJ(t1Eqx,t1BasLn2,"x = ",t1Clr) END SUB SUB t1CursorValues(x,y) CALL t1ClearOutput CALL SetTextFont(1,12,"bold") CALL AlignDot(t1Dot,t1BasLn1,using$(t1f$,x),t1Clr) CALL AlignDot(t1Dot,t1BasLn2,using$(t1f$,y),t1Clr) END SUB SUB t1ClearOutput BOX CLEAR t1Eqx-2,t1Rgt,t1Bas,t1Top+5 END SUB SUB t1Init CALL t1OutputLabels END SUB ! --- t2 - the isocline equations --- DIM ClineEq$(0:5) MAT READ ClineEq$ DATA "(1 +- sqrt(1-4c))/2" DATA "(t-c)/2" DATA "+- sqrt(c+t)" DATA "+- sqrt(c-t)" DATA "-t/c" DATA "c/t" LET t2Lft = h1wLft LET t2Rgt = workrgt LET t2BasLn = h1wBas + 20 LET t2Top = t2BasLn - 12 LET t2Bas = t2BasLn + 5 LET t2Eqx = t2Lft + 30 LET t2Label$= "x' = " SUB t2Clear BOX CLEAR t2Lft,t2Rgt,t2Bas,t2Top END SUB SUB t2ClineEq(ce) CALL SetTextFont(1,12,"bold") CALL t2Clear CALL PlotTextRJ(t2Eqx,t2BasLn,t2Label$,yellow) CALL PlotTextLJ(t2Eqx,t2BasLn,"c",yellow) END SUB ! SUB t2ClineEq(ce) ! CALL SetTextFont(1,12,"bold") ! CALL t2Clear ! CALL PlotTextRJ(t2Eqx,t2BasLn,t2Label$,yellow) ! SELECT CASE ce ! CASE 2,5,6 ! CALL PlotTextLJ(t2Eqx,t2BasLn,ClineEq$(ce-1),yellow) ! CASE 1 ! CALL PlotTextLJ(t2Eqx,t2BasLn,"(1 ",yellow) ! CALL StringWidth("(1 ",sw) ! CALL PlusMinus12(t2Eqx+sw+2,t2BasLn,yellow) ! CALL StringWidth("(1 +",sw) ! CALL PlotTextLJ(t2Eqx+sw+3,t2BasLn,"sqrt(1-4c)) / 2",yellow) ! CASE 3 ! CALL PlusMinus12(t2Eqx+3,t2BasLn,yellow) ! CALL PlotTextLJ(t2Eqx+9,t2BasLn,"sqrt(c+t)",yellow) ! CASE 4 ! CALL PlusMinus12(t2Eqx+3,t2BasLn,yellow) ! CALL PlotTextLJ(t2Eqx+9,t2BasLn,"sqrt(c-t)",yellow) ! END SELECT ! END SUB ! --- single check box --- DECLARE PUBLIC cb1Lft,cb1Rgt,cb1Bas,cb1Top,cb1State,cb1Clr,cb1Txt$ DECLARE DEF cb1Within LET cb1Lft = w1Lft LET cb1Bas = w1Bas + 40 LET cb1Clr = litgry LET cb1Txt$= "Slope Field" CALL cb1Variables ! --- buttons --- LET bwid= 135 LET bhgt= 18 LET clft= w1Lft LET crgt= clft + 90 LET ctop= w1Bas + 60 LET cbas= ctop + bhgt LET cslft= crgt + 2 LET csrgt= cslft + bwid LET cstop= ctop LET csbas= cstop + bhgt LET cclft= csrgt + 2 LET ccrgt= cclft + bwid LET cctop= ctop LET ccbas= cctop + bhgt SUB Buttons CALL SetTextFont(1,12,"bold") CALL DrawButton(clft,crgt,cbas,ctop,5,"Clear All") CALL DrawButton(cslft,csrgt,csbas,cstop,5,"Clear Solutions") CALL DrawButton(cclft,ccrgt,ccbas,cctop,5,"Clear Isoclines") END SUB ! --- default parameters --- DIM cValues(0:50),icValues(0:50,0:1) LET cCount = 0 LET ivCount= 0 LET fieldclr = drkmid LET cb1State = 1 LET fieldState= 1 LET menuState = 0 LET dt,tstep = 1/16 LET f$ = "-%.##" LET elft = t1Lft+32 LET c = 1 LET m1Equation= 3 CALL SetTimer ! --- draw screen --- CALL InitScreen CALL m1InitMenu1 SUB InitScreen BOX CLEAR worklft,workrgt,workbas,worktop CALL w1Init(m1Equation) CALL t1Init CALL Buttons CALL m1ResetMenu(menuState) CALL VectorField CALL h1Init(m1Equation) CALL t2ClineEq(m1Equation) CALL w1KeepGraphLayer CALL cb1Init END SUB ! --- event loop --- DO CALL SetTextFont(1,12,"bold") LET clearflag= 0 IF ms<>2 then DO GET MOUSE: mx,my,ms IF w1Within(mx,my)=true then CALL w1wClamp(mx,my) IF mx<>oldx or my<>oldy then LET t= w1Fncx(mx) LET x= w1Fncy(my) CALL CopyCoords(mx,my,oldx,oldy) CALL t1CursorValues(t,x) LET clearflag= 1 END IF ELSE IF clearflag=1 then CALL CleanUp END IF END IF LOOP until ms=2 END IF IF w1wWithin(mx,my)=true then ! set initial values and draw CALL MouseUp(mx,my,ms) CALL w1PixelsToMath(mx,my,t0,x0) CALL Trajectory(t0,x0) LET icCount= icCount+1 LET icValues(icCount,0)= t0 LET icValues(icCount,1)= x0 ELSE IF h1Within(mx,my)=1 then ! c slider IF myclft and mxctop and mycslft and mxcstop and mycclft and mxcctop and myoldc then CALL Cline(1) LET oldc= c END IF LOOP until ms=3 CALL w1KeepGraphLayer LET cCount= cCount+1 LET cValues(cCount)= c END SUB ! ----- trajectory routines ----- SUB Trajectory(t0,x0) LET dt= tstep ! reset to default CALL DrawTraj(t0,x0) IF ms=2 then EXIT SUB LET dt= -tstep ! reset to default CALL DrawTraj(t0,x0) CALL w1KeepGraphLayer END SUB SUB DrawTraj(t0,x0) SET COLOR cyan CALL CopyCoords(t0,x0,t,x) IF m1Equation<>5 then DO CALL w1MathToPixels(t,x,wx,wy) IF wxw1Lft and wy>w1Top and wybadarg then PLOT wx,wy; ELSE PLOT END IF ELSE PLOT END IF CALL CopyCoords(wx,wy,oldwx,oldwy) CALL AdjustStep(oldwx,oldwy) CALL RungeKutta4(t,x) CALL w1MathToPixels(t,x,wx,wy) IF abs(x)>5 or abs(t)>5 then EXIT DO ! leaving the window? GET MOUSE: mx,my,ms IF ms=2 then EXIT DO LOOP PLOT ELSE ! m1equation is 5: circles LET r= sqr(t*t+x*x) IF x<>0 or t<>0 then LET a= angle(t,x) ELSE LET a= 0 END IF IF r>0 then LET stp= 1/(50*r) IF r=2 and pixels<=4 then EXIT FOR ELSE IF pixels<2 then LET dt= dt*2 ELSE IF pixels>4 then LET dt= dt/2 END IF END IF NEXT i END SUB SUB RungeKutta4(t,x) CALL FetchEq(m1Equation,t,x,dx,dy) LET dx1= dx LET dy1= dy LET x1 = t + .5*dx1*dt LET y1 = x + .5*dy1*dt CALL FetchEq(m1Equation,x1,y1,dx,dy) LET dx2= dx LET dy2= dy LET x2 = t + .5*dx2*dt LET y2 = x + .5*dy2*dt CALL FetchEq(m1Equation,x2,y2,dx,dy) LET dx3= dx LET dy3= dy LET x3 = t + dx3*dt LET y3 = x + dy3*dt CALL FetchEq(m1Equation,x3,y3,dx,dy) LET dx4= dx LET dy4= dy LET dy = (dy1 + 2*dy2 + 2*dy3 + dy4) / 6 LET dx = (dx1 + 2*dx2 + 2*dx3 + dx4) / 6 LET x = x + dt*dy LET t = t + dt*dx END SUB ! ----- end of trajectory routines ----- ! ----- isocline graph routines ----- SUB Cline(vctflag) CALL w1ShowGraphLayer SET COLOR yellow SELECT CASE m1Equation CASE 1 LET n = 1-4*c LET sqrn= sqr(n) IF n>=0 then LET x = (1 + sqrn)/2 LET wx= w1Wndy(x) PLOT w1Lft,wx; w1Rgt,wx LET x = (1 - sqrn)/2 LET wx= w1Wndy(x) PLOT w1Lft,wx; w1Rgt,wx END IF CASE 2 FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = (t-c)/2 LET wy= w1Wndy(x) IF wy>w1Top and wyw1Lft and wx0 then CALL DrawFt( 1) CALL DrawFt(-1) ELSE IF c<0 then CALL DrawFx( 1) CALL DrawFx(-1) ELSE IF c=0 then CALL DrawFt( 1) CALL DrawFt(-1) CALL DrawFx( 1) CALL DrawFx(-1) END IF CASE 5 IF c<>0 then FOR wx= w1Lft to w1Rgt LET t = w1Fncx(wx) LET x = -t/c LET wy= w1Wndy(x) IF wy>w1Top and wyw1Top and wy=0 then LET x = sign*sqr(n) LET wy= w1Wndy(x) IF wy>w1Top and wyw1Lft and wx=0 then LET n = sqr(1-4*c) LET x = (1+n)/2 CALL DrawPointerX LET x = (1-n)/2 CALL DrawPointerX END IF NEXT t CASE 2 ! DEF f2(x) = t-2x FOR t= w1fLft+1 to w1fRgt-1 LET wx= w1Wndx(t) LET x = (t-c)/2 CALL DrawPointerX NEXT t CASE 3 ! DEF f3(x) = x*x-t FOR t= w1fLft to w1fRgt LET wx= w1Wndx(t) IF c+t>=0 then LET n = sqr(c+t) LET x = n CALL DrawPointerX LET x = -n CALL DrawPointerX END IF NEXT t CASE 4 ! DEF f4(x) = x*x-t*t IF c>0 then FOR t= w1fLft+1 to w1fRgt-1 LET wx= w1Wndx(t) IF c+t*t>=0 then LET n = sqr(c+t*t) LET x = n CALL DrawPointerX LET x = -n CALL DrawPointerX END IF NEXT t ELSE IF c<=0 then FOR x= w1fBas+1 to w1fTop-1 LET wy= w1Wndy(x) IF x*x-c>=0 then LET n = sqr(x*x-c) LET t = n CALL DrawPointerT LET t = -n CALL DrawPointerT END IF NEXT x END IF CASE 5 IF c<>0 then LET ang = angle(1,-1/c) LET angle1= -pi/2-ang LET angle2= pi/2-ang FOR r= -3.5 to 3.5 CALL PolarToCartesian(r,ang,x,y) CALL w1MathToPixels(x,y,wx,wy) IF c>0 then DRAW pointer with rotate(angle1) * shift(wx,wy) ELSE DRAW pointer with rotate(angle2) * shift(wx,wy) END IF NEXT r ELSE LET wx= w1x0 FOR r= -3.5 to 3.5 LET wy= w1Wndy(r) DRAW pointer with shift(wx,wy) NEXT r END IF CASE 6 IF c<>0 then LET ang= angle(1,c) FOR r= -3.5 to 3.5 CALL PolarToCartesian(r,ang,x,y) CALL w1MathToPixels(x,y,wx,wy) IF c>0 then DRAW pointer with rotate(-ang) * shift(wx,wy) ELSE DRAW pointer with rotate(-ang) * shift(wx,wy) END IF NEXT r ELSE LET wy= w1y0 FOR r= -3.5 to 3.5 LET wx= w1Wndx(r) DRAW pointer with shift(wx,wy) NEXT r END IF END SELECT END SUB SUB DrawPointerX CALL FetchEq(m1Equation,t,x,dx,dy) LET dx= dx*w1aspect LET wy= w1Wndy(x) CALL AngleRadians(dx,-dy,a) ! PRINT a !CALL DrawIsoPointer(wx,wy,a) DRAW pointer with rotate(a) * shift(wx,wy) END SUB SUB DrawPointerT CALL FetchEq(m1Equation,t,x,dx,dy) LET dx = dx*w1aspect LET wx = w1Wndx(t) ! LET ang = angle(dx,-dy) CALL AngleRadians(dx,-dy,a) !CALL DrawIsoPointer(wx,wy,a) DRAW pointer with rotate(a) * shift(wx,wy) END SUB SUB SlopeMark(sx,sy) CALL FetchEq(m1Equation,sx,sy,dx,dy) ! LET ang= angle(dx,-dy) CALL AngleRadians(dx,-dy,ang) LET sa = 4*sin(ang) LET wy1= wy+sa LET wy2= wy-sa LET ca = 4*cos(ang) CALL VectorHead(ang,wx,wy,wvx0,wvy0) END SUB SUB VectorHead(ang,wx,wy,wvx0,wvy0) CALL SetVMat(ang) CALL Rotate(6, 2,vx1,vy1) CALL Rotate(6,-2,vx2,vy2) LET wvx1= wx+vx1 LET wvy1= wy+vy1 LET wvx2= wx+vx2 LET wvy2= wy+vy2 PLOT wvx1,wvy1; wvx0,wvy0; wvx2,wvy2 END SUB SUB Rotate(xin,yin,xout,yout) LET xout= xin*vcta + yin*vctc LET yout= xin*vctb + yin*vctd END SUB SUB SetVMat(ang) LET vcta= cos(ang) LET vctb= sin(ang) LET vctc= -vctb LET vctd= vcta END SUB PICTURE pointer PLOT 2,-4; 6,0; 2,4 PLOT 6, 0; -6,0 END PICTURE SUB DrawIsoPointer(wxp,wyp,a) CALL SetVMat(a) CALL Rotate(-3, 0,lftx,lfty) CALL Rotate(+3, 0,rgtx,rgty) CALL Rotate( 0,-3,waxm,waym) CALL Rotate( 0,+3,waxp,wayp) PLOT w1Wndx(lftx), w1Wndy(lfty); w1Wndx(rgtx), w1Wndy(rgty) ! PLOT waxm,waym; wrgtx,wrgty ! PLOT waxp,wayp; wrgtx,wrgty END SUB SUB AngleRadians(x,y,a) IF x>0 then LET a= atn(y/x) ELSE IF x<0 and y<>0 then LET a= atn(y/x)+sgn(y) * 180 ELSE IF x<0 and y=0 then LET a= 180 ELSE IF y<>0 then LET a= sgn(y)*90 ELSE END IF END SUB ! ----- end of isocline graph routines ----- SUB VectorField CALL w1ShowGridLayer IF fieldState=1 then SET COLOR fieldclr ! vector field LET vstp = 20 LET hstp = vstp/2 FOR wy= w1top+hstp to w1bas-hstp step vstp FOR wx= w1Lft+hstp to w1Rgt-hstp step vstp CALL w1PixelsToMath(wx,wy,x,y) IF round(y,2)<>0 then CALL FetchEq(m1Equation,x,y,dx,dy) LET dx = dx*w1aspect LET ang= angle(dx,-dy) LET sa = 4*sin(ang) LET wy1= wy+sa LET wy2= wy-sa LET ca = 4*cos(ang) PLOT wx-ca,wy2; wx+ca,wy1 END IF NEXT wx NEXT wy CALL w1KeepGraphLayer ELSE CALL w1KeepGraphLayer END IF END SUB END SUB ! ----- end of isoclines code -----