y = 0 ' initial displacement vy = 0 ' initial velocity t = 0 ' initial time dt = 0.001 ' time interval between updates
[start] accn =F /m ' Newton's Second Law vy =vy +accn *dt ' since accn =vel'y change /time interval y =y +vy *dt ' since velocity =pos'n change /time interval t =t +dt ' ie time moves on a step of dt if still in range, goto [start] and repeat.This is a loop which we go round, stepping forward by a step dt in time which is small enough to create only small changes in the other variables. The results can be a table; exported as csv; or, best, displayed as a graph. This is quite the easiest way to see what is happening.
'Initial conditions x = 0 ' initial horizontal position. Try changing to say 10. vx = 0 ' try changing this to say 5 m s^-1. t = 0 ' initial time. dt = 1 ' time interval between updates. ( Use .001 to slow it down.) force = 1 ' constant, forward force. Try changing this to 0. mass = 1 ' mass of moving object. [here] print t, x, vx, accnx 'The calculation loop accnx =force /mass vx =vx +accnx *dt x =x +vx *dt t =t +dt scan if x <500 then goto [here] wait end
'Initial conditions x = 60 ' initial horizontal position. t = 0 ' initial time. dt = 1 ' time interval between updates. mass = 1 ' mass of moving object. [here] 'The calculation loop print t, x, vx, accnx if t >15 then force =2 else force =0 if t >30 then force =-4 accnx =force /mass vx =vx +accnx *dt x =x +vx *dt t =t +dt scan if x <500 and x >0 then goto [here] wait endThis just printed a table of time, position, velocity and acceleration. It is much more useful to graph the results.
nomainwin WindowWidth =650 WindowHeight =680 graphicbox #w.g, 10, 10, 620, 620 open "1D motion under steady force."for window as #w #w, "trapclose [quit]" #w.g, "fill white" #w.g, "color lightgray ; backcolor lightgray" #w.g, "up ; goto 590 190 ; down ; goto 10 190" #w.g, "up ; goto 590 390 ; down ; goto 10 390" #w.g, "up ; goto 590 590 ; down ; goto 10 590" #w.g, "up ; goto 0 200 ; down ; boxfilled 620 204" #w.g, "up ; goto 0 400 ; down ; boxfilled 620 404" #w.g, "backcolor white" #w.g, "color red ; up ; goto 10 190 ; down ; goto 10 10" #w.g, "place 40 100" #w.g, "\Position x /m" #w.g, "color blue ; up ; goto 10 390 ; down ; goto 10 210" #w.g, "place 40 300" #w.g, "\Velocity vx /m s^-1" #w.g, "color black ; up ; goto 10 590 ; down ; goto 10 410" #w.g, "place 40 500" #w.g, "\Acceleration accnx /m s^-2" #w.g, "color darkgray" #w.g, "place 540 580" #w.g, "\Time t /s" #w.g, "place 540 380" #w.g, "\Time t /s" #w.g, "place 540 180" #w.g, "\Time t /s" 'Initial conditions x = 0 ' initial horizontal position. t = 0 ' initial time. dt = 0.01 ' time interval between updates. force = 1 ' constant, forward force. mass = 1 ' mass of moving object. [here] 'The calculation loop print t, x, vx, accnx ' known max's 32, 500, 30, 1 from printing tomainwin call display t, x, vx, accnx accnx =force /mass vx =vx +accnx *dt x =x +vx *dt t =t +dt scan if x <500 then goto [here] wait sub display t, x, vx, accnx #w.g, "size 5 ; set 608 "; 190 -180 *x /500; " ; size 1" displayHoriz =10 +600 *t /32 yx =190 -180 *x /500 yvx =390 -180 *vx /30 yaccnx =590 -180 *accnx /1 #w.g, "color red ; set "; displayHoriz; " "; yx #w.g, "color darkblue ; set "; displayHoriz; " "; yvx #w.g, "color black ; set "; displayHoriz; " "; yaccnx end sub [quit] close #w endSimilarly, with the varying force,
nomainwin WindowWidth =790 WindowHeight =680 UpperLeftX = 20 UpperLeftY = 20 graphicbox #w.g, 10, 10, 640, 620 graphicbox#w.g2, 660, 10, 120, 100 open "1D motion under force proportional to distance from a centre." for window as #w #w, "trapclose [quit]" #w.g2, "down" #w.g, "fill white" #w.g, "color lightgray ; backcolor lightgray" #w.g, "up ; goto 590 190 ; down ; goto 10 190" #w.g, "up ; goto 590 300 ; down ; goto 10 300" #w.g, "up ; goto 590 500 ; down ; goto 10 500" #w.g, "up ; goto 0 200 ; down ; boxfilled 620 204" #w.g, "up ; goto 0 400 ; down ; boxfilled 620 404" #w.g, "backcolor white" #w.g, "color red ; up ; goto 10 190 ; down ; goto 10 10" #w.g, "place 40 100" #w.g, "\Position x /m" #w.g, "color blue ; up ; goto 10 390 ; down ; goto 10 210" #w.g, "place 40 300" #w.g, "\Velocity vx /m s^-1" #w.g, "color black ; up ; goto 10 590 ; down ; goto 10 410" #w.g, "place 40 500" #w.g, "\Acceleration accnx /m s^-2" #w.g, "color darkgray" #w.g, "place 540 580" #w.g, "\Time t /s" #w.g, "place 540 380" #w.g, "\Time t /s" #w.g, "place 540 180" #w.g, "\Time t /s" 'Initial conditions x = 10 ' initial horizontal position. t = 0 ' initial time. dt = 0.01 ' time interval between updates. mass = 1 ' mass of moving object. [here] 'The calculation loop print t, x, vx, accnx ' call display t, x, vx, accnx ' Define a force towards 40 mark and proportional to distance from it. force =( 40 -x) /2 ' Add air drag prop'l v^2. if vx >0 then force =force -( vx^2 /100) else force =force +( vx^2 /100) accnx =force /mass vx =vx +accnx *dt x =x +vx *dt t =t +dt scan if x <500 then goto [here] wait sub display t, x, vx, accnx ' #w.g, "size 5 ; set 608 "; 150 -180 *x /100; " ; size 1" #w.g2, "set "; x *1.5; " "; vx *2 +50 displayHoriz =10 +600 *t /100 yx =150 -180 *x /100 yvx =300 -180 *vx /50 yaccnx =500 -180 *accnx /50 #w.g, "color red ; set "; displayHoriz; " "; yx #w.g, "color darkblue ; set "; displayHoriz; " "; yvx #w.g, "color black ; set "; displayHoriz; " "; yaccnx end sub [quit] close #w end
nomainwin UpperLeftX = 10 UpperLeftY = 10 WindowWidth = 800 WindowHeight = 700 graphicbox #w.g, 10, 10, 710, 610 textbox #w.t, 10, 620, 610, 30 open "Rocket vertical flight simulation" for window as #w #w, "trapclose [quit]" #w.g, "size 2 ; goto 5 505 ; down ; goto 705 505" mbody = 0.0200 ' fixed mass of body mfuel = 0.0100 ' 10gm of fuel mcase = 0.0200 ' 20gm casing & nozzle. burntime = 0.7 ' burn lasts for this time burnrate = mfuel /burntime ' assume linear reaction rate A = 0.0004 ' csa of rocket g = 9.81 ' acc'n of gravity D = 1.2 ' density of air Cd = 0.75 ' allows for the streamlined shape y = 0 ' initial vertical height vy = 0 ' initial vertical displacement t = 0 ' initial time dt = 0.001 ' time interval between updates accn = 0 hasTakenOf = 0 global mbody, mfuel, mcase, burntime, burnrate, A, g, Cd, y, vy, t, dt, g, D [here] force =thrust( t) -g *mass( t) -drag( t) if hasTakenOff <>0 then accn =force /mass( t) else accn =0 if thrust( t) >( mass( t) *g) then hasTakenOff =1 vy =vy +accn *dt #w.g, "color green ; set "; 5 +600 *t /10; " "; 505 -500 *vy /250 y =y +vy *dt t =t +dt #w.t, " Time = "; using( "##.###", t); " force = "; using( "##.###", force);_ " accn = "; using( "#####.##", accn); " velocity = "; using( "###.##", vy);_ " and height = "; using("#######.##", y) #w.g, "color black ; set "; 5 +600 *t /10; " "; 505 -500 *y /120 scan if y <500 and y >-1 then goto [here] wait ' _____________________________________________________________________ function thrust( tt) th =0 if tt <=0.7 then th =2 else th =0 if tt <=0.3 then th =10 -80 *( tt -0.2) if tt <=0.2 then th =50 *tt #w.g, "color red ; set "; 5 +600 *t /10; " "; 505 -500 *th /50 thrust =th end function ' _____________________________________________________________________ function mass( tt) select case tt case tt <=0.7 ' it burns 0.0035kg in 0.7s. m =mbody +mcase +mfuel -tt *burnrate case else m =mbody +mcase end select mass =m end function '____________________________________________________________________________ function drag( tt) if vy >0 then drag =0.5 *D *vy^2 *Cd *A else drag =-0.5 *D *vy^2 *Cd *A end function [quit] close #w end
' /////////////////// CentralForceConstant ' to-dos: ' Makeforce vector display length proportional to magnitude ' Offer option to display all at say 1/10 scale ' add sound freq'y proportional to velocity? nomainwin UpperLeftX = 10 UpperLeftY = 2 WindowWidth = 920 WindowHeight = 650 graphicbox #w.g1, 10, 10, 880, 480 graphicbox #w.g3, 500, 510, 100, 100 open "Motion under constant centripetal force." for window as #w #w, "trapclose [quit]" global pi pi =3.1415923535 #w.g1, "down ; size 4 ; set 200 200 ; size 1; flush" #w.g3, "down ; backcolor red ; color red" vmax =10 x = 0 ' initial horizontal position vx =vmax y = 15 ' initial vertical height vy = 0 ' initial vertical velocity force =( vx^2 +vy^2) /15 ' exact circular orbit velocity. Try *0.9 or *1.2 t = 0 ' initial time dt = 0.01 ' time interval between updates [here] RadDist =( x^2 +y^2)^0.5 theta =atan2( y, x) print x, y, theta accny =-1 *force *sin( theta) accnx =-1 *force *cos( theta) vy =vy +accny *dt y =y +vy *dt vx =vx +accnx *dt x =x +vx *dt t =t +dt #w.g1, "set "; 200 +10 *x; " "; 200 -10 *y #w.g3, "cls ; home ; north ; turn "; 90 -theta *180 /pi; " ; circle 30 ; size 2 ; go -30" scan if RadDist >10 and RadDist <80 then goto [here] #w.g1, "flush" wait function atan2( y, x) if x >0 then at =atn( y /x) if y >=0 and x <0 then at =atn( y /x) +pi if y <0 and x <0 then at =atn( y /x) -pi if y >0 and x =0 then at = pi /2 if y <0 and x =0 then at = 0 -pi /2 if y =0 and x =0 then notice "undefined": end atan2 =at end function [quit] close #w end
If the force is NOT constant, but proportional to distance (think swinging a cat round your head on its elastic tail!) we get interesting shapes:-
' /////////////////// CentralForceKTimesExtn nomainwin UpperLeftX = 10 UpperLeftY = 2 WindowWidth = 920 WindowHeight = 650 graphicbox #w.g1, 10, 10, 880, 480 graphicbox #w.g3, 500, 510, 100, 100 open "Motion under constant centripetal force plus k x extension." for window as #w #w, "trapclose [quit]" global pi pi =3.1415923535 k =10 ' Hooke's Law, spring constant #w.g1, "down ; size 4 ; set 200 200 ; size 1; flush" #w.g3, "down ; backcolor red ; color red" vmax =10 x = 0 ' initial horizontal position vx =vmax y = 18 ' initial vertical height vy = 0 ' initial vertical velocity force1 =( vx^2 +vy^2) /15 ' exact circular orbit velocity. Try *0.9 or *1.2 t = 0 ' initial time dt = 0.01 ' time interval between updates [here] RadDist =( x^2 +y^2)^0.5 theta =atan2( y, x) print x, y, theta force =force1 + ( RadDist -15) *k accny =-1 *force *sin( theta) accnx =-1 *force *cos( theta) vy =vy +accny *dt y =y +vy *dt vx =vx +accnx *dt x =x +vx *dt t =t +dt #w.g1, "set "; 200 +10 *x; " "; 200 -10 *y #w.g3, "cls ; home ; north ; turn "; 90 -theta *180 /pi; " ; circle 30 ; size 2 ; go -30" scan if RadDist >10 and RadDist <80 then goto [here] #w.g1, "flush" wait function atan2( y, x) if x >0 then at =atn( y /x) if y >=0 and x <0 then at =atn( y /x) +pi if y <0 and x <0 then at =atn( y /x) -pi if y >0 and x =0 then at = pi /2 if y <0 and x =0 then at = 0 -pi /2 if y =0 and x =0 then notice "undefined": end atan2 =at end function [quit] close #w end
' /////////////////// CentralForceRepulsive nomainwin UpperLeftX = 10 UpperLeftY = 2 WindowWidth = 920 WindowHeight = 650 graphicbox #w.g1, 10, 10, 880, 480 graphicbox #w.g3, 500, 510, 100, 100 open "Motion under constant centripetal force." for window as #w #w, "trapclose [quit]" global pi pi =3.1415923535 #w.g1, "goto 200 200 ; down ; backcolor lightgray ; circlefilled 160 ; size 3 ; set 200 200 ; size 1 ; flush" #w.g3, "down ; backcolor red ; color red" c = 0 'for yy =-27 to 27 step 0.3 for i =1 to 1000 x = -20 ' initial horizontal position y = -27 +55 *rnd( 1) ' random incident height vx = 50 vy = 0 ' initial vertical velocity t = 0 ' initial time dt = 0.001 ' time interval between updates [here] theta =atan2( y, x) force =(( x^2 +y^2)^-1) *1000 accny =1 *force *sin( theta) accnx =1 *force *cos( theta) vy =vy +accny *dt y =y +vy *dt vx =vx +accnx *dt x =x +vx *dt t =t +dt '#w.g1, "color "; c; " 40 "; 255 -c #w.g1, "set "; 200 +10 *x; " "; 200 -10 *y #w.g3, "cls ; home ; north ; turn "; 90 -theta *180 /pi; " ; circle 30 ; size 2 ; go -30" scan if ( x^2 +y^2) <4900 then goto [here] 'c =c +1 next i'next yy #w.g1, "flush" wait function atan2( y, x) if x >0 then at =atn( y /x) if y >=0 and x <0 then at =atn( y /x) +pi if y <0 and x <0 then at =atn( y /x) -pi if y >0 and x =0 then at = pi /2 if y <0 and x =0 then at = 0 -pi /2 if y =0 and x =0 then notice "undefined": end atan2 =at end function [quit] close #w end