Code: Select all
; program fully operational at https://www.dionysus.biz/Spider/Trajectory77.html
; program inputs cannon initial firing conditions, and outputs trajectory path considering gravity and air friction. Graphic plotting of path + table.
; I am new to SpiderBasic. This is my first. Program looks nice; but if it does not meet your programming standards, I will not be upset.
;You are Number 1! Keep up the good work and thank you. Fred is the best. CatSquad
Enumeration
#WinInputs
#WinCannon
#WinDragFac
#WinResults
#WinControl
#WinPath
#WinMap
#WinKruppGun
#ProbDescr
#BoreTxtIn
#BoreIn
#VelTxtIn
#VelIn
#WtTxtIn
#WtIn
#AngTxtIn
#AngIn
#HighTxtIn
#HighIn
#DragTxtIn
#DragIn
#FireButton
#GunImg
#GunImgGadget
#ProbInputRptTitle
#BoreTxtOut
#VelTxtOut
#WtTxtOut
#AngTxtOut
#HighTxtOut
#DragTxtOut
#ButtonRunAgain
#ButtonExit
#ButtonToNavalResearch
#ButtonToDionysus
#DragTableImg
#DragTableImgGadget
#MapSknyGadget
#MapSknyImg
#OslyabyaTrans
#FreighterBow
#Shell
#Splash2
#Mortar
#ArrowUp
#Smoke
#ButtonToNotes
#KruppLogoImg
#KruppImgGadget
EndEnumeration
Global descript.s="Gun, Year, Country, Model" ; gadget 1
Global d.f=12.0 ; diameter of shell - inches gadget 2
Global vInit.f=2500.0; initial velocity of projectile ft/sec gadget 4
Global w.f=850.0; projectile weight lbs gadget 6
Global thetaInit.f=20.0 ; Angle of cannon barrel in degrees gadget 8
Global yInit.f=20.0 ; Elevation of tip of gun barrel in feet gadget 10
Global DF.f=10.0 ;Drag Factor is .7-1.6 entered as 7-16 gadget 12
; note The Fire button is gadget 13
Global muzzle.f=20.0
Global flashH.f=18.0
Global xOffset.f=0.0
Global fireTheta.f=0.0
; environmental variables
;Global wide; to describe screen max width
Global tallEff
; plotting variables
Global xScale.f=0.0
Global yScale.f=0.0
Global Scale.f=0.0
; computation global variables
Global Tdelta.f=0.2 ; time step in seconds
Global v.f=vInit
; bashforth procedure globals
Global Dim bash.f(3)
; global return variables
Global xFinal.f=0.0
Global vFinal.f=0.0
Global angFinal.f=0.0
Global timeFinal.f=0.0
Global DI.f=0.0
Global maxIndex=0
Global wide.f
Global maxRange
;Dim timeRecord.f(1000)
Global Dim xRecord.f(1000)
Global Dim yRecord.f(1000)
Procedure RunProgram(Filename.s, Parameter.s)
! if (v_parameter !=""){
! var win = window.open(v_filename,v_parameter);
! win.focus();
! } else {
! window.open(v_filename);
! }
EndProcedure
Procedure HyperLinkGadgetEvent()
If EventGadget()=#ButtonRunAgain ;Run analysis again
RunProgram("https://dionysus.biz/Spider/Trajectory77.html","_blank")
ElseIf EventGadget()=#ButtonToNavalResearch
RunProgram("https://dionysus.biz/Battleships&Subs.html","_blank")
ElseIf EventGadget()=#ButtonToDionysus
RunProgram("https://dionysus.biz/index.html","_blank")
ElseIf EventGadget()=#ButtonToNotes
RunProgram("https://dionysus.biz/CannonNotes.html","_blank")
Else
MessageRequester("Error in HyperLinkGadgetEvent at line 89")
EndIf
EndProcedure
Procedure Loaded(Type,File$,ObjectId); this supports graphic of cannon input dimensions
If File$="GunInitCondit250T.jpg"
OpenWindow(#WinCannon,290,435,300,250,"Firing Variables",#PB_Window_SystemMenu)
ImageGadget(#GunImgGadget,0,0,ImageWidth(ObjectId),ImageHeight(ObjectId),ImageID(#GunImg))
ElseIf File$="DFTable.png"
;OpenWindow(#WinDragFac,600,0,809,623,"Drag Coefficients",#PB_Window_SystemMenu)
OpenWindow(#WinDragFac,600,0,607,685,"Drag Coefficients",#PB_Window_SystemMenu)
ImageGadget(#DragTableImgGadget,0,0,ImageWidth(ObjectId),ImageHeight(ObjectId),ImageID(#DragTableImg))
ElseIf File$="COASTALMAP2.PNG"
x=xOffse+Scale*maxRange
y=400.0
OpenWindow(#WinMap,240,0,wide,560,"Concept Map", #PB_Window_SystemMenu)
ResizeImage(#MapSknyImg,wide,560) ; set to math line 406
StartDrawing(ImageOutput(#MapSknyImg))
Line(50,525,x-50,y-525,RGB(200,0,0))
DrawingMode(#PB_2DDrawing_Outlined)
p=Sqr(Pow(x-50,2)+Pow(y-525,2))
Circle(50,525,p,RGB(200,0,0)); range arc
For I=12 To 4 Step -2
Circle(x,y,I,RGB(10*I+50,0,0))
Next I
StopDrawing()
;ResizeImage(#MapSknyImg,wide,560) ; set to math line 406
ImageGadget(#MapSknyGadget,0,0,wide,ImageHeight(ObjectId),ImageID(#MapSknyImg))
ElseIf File$="SKINNYSEA.PNG"
x=xOffse+Scale*maxRange
y=400.0
OpenWindow(#WinMap,240,0,wide,560,"Concept Map", #PB_Window_SystemMenu)
ResizeImage(#MapSknyImg,wide,560)
StartDrawing(ImageOutput(#MapSknyImg))
Line(85,425,x-85,y-425,RGB(200,0,0))
DrawingMode(#PB_2DDrawing_Outlined)
p=Sqr(Pow(x-85,2)+Pow(y-425,2))
Circle(85,425,p,RGB(200,0,0)); range arc
For I=12 To 4 Step -2
Circle(x,y,I,RGB(10*I+50,0,0))
Next I
StopDrawing()
ImageGadget(#MapSknyGadget,0,0,wide,ImageHeight(ObjectId),ImageID(#MapSknyImg))
ElseIf File$="KRUPPGUN1897PD.JPG"
OpenWindow(#WinKruppGun,0,0,588,394,"Krupp 16 Gun (Public Domain from 1897 Popular Science)", #PB_Window_SystemMenu)
ImageGadget(#KruppImgGadget,0,0,ImageWidth(ObjectID),ImageHeight(ObjectID),ImageID(#KruppLogoImg))
Else
;Debug "Program Issue at Line 87"
EndIf
EndProcedure
Procedure Loading(Type, Filename$)
FlipBuffers() ; start the rendering
EndProcedure
Procedure Bashforth(v,d,w,theta,y)
; establish friction coefficient as function of gross speed. Should not be broken into x & y components
If v<1061.999
k.f=18120.39461*Pow(v,-0.8082372052) ;Bashforth Friction Coefficient k below 1062 ft/sec
Else
k.f=2.9e-8*Pow(v,3)-1.5924e-4*Pow(v,2)+0.213533*v+52.75734 ;Bashforth Friction Coefficient k above 1062 ft/sec
EndIf
densityFactor.f=1.0098095*Pow(2.718281828,-0.00003206*y); Atmospheric density as funct of y has been curve fit
k=DF*densityFactor*k ; overall friction factor k is product of drag factor, air density and k
Ax.f=k*Pow(d,2)*Pow(v,3)*Cos(theta/57.3)/(1e9*w); x component of acceleration
Ay.f=k*Pow(d,2)*Pow(v,3)*Sin(theta/57.3)/(1e9*w); y component of acceleration
bash(0)=k ; an array for return value
bash(1)=Ax
bash(2)=Ay
EndProcedure
Procedure Trajectory()
; establish initial x & y velocities
X1.f=0
Y1.f=yInit
Vx1.f=vInit*Cos(thetaInit/57.3)
Vy1.f=vInit*Sin(thetaInit/57.3)
V1.f=vInit
theta1.f=thetaInit ; this is in degrees
time.f=0.0
Vx2.f=0.0
Vy2.f=0.0
X2.f=0.0
Y2.f=0.0
theta2.f=0.0
xFinal.f=0
vFinal.f=0
angFinal.f=0
; loop to step through time at TBD sec intervals
For i=0 To 1000
bashforth(V1,d,w,theta1,Y1)
k.f=bash(0)
;MessageRequester("Bashforth Constant = " + k)
Ax.f=bash(1)
Ay.f=bash(2)
Vx2.f=Vx1-Ax*Tdelta
Vy2.f=Vy1-Ay*Tdelta-32.0*Tdelta
X2=X1+Vx2*Tdelta
Y2=Y1+Vy2*Tdelta
V2=Sqr(Pow(Vx2,2)+Pow(Vy2,2))
theta2.f=57.3*ATan((Y2-Y1)/(X2-X1)); in degrees
; set old values to new
time=time+Tdelta
X1=X2
Y1=Y2
Vx1=Vx2
Vy1=Vy2
V1=V2
theta1=theta2
xRecord(i)=X2
yRecord(i)=Y2
If Y1<0
Break
EndIf
Next i
For i = 1 To 1000
If yRecord(i)=0
Break
EndIf
Next i
; final variables (all globals)
xFinal=X2
vFinal=V2
angFinal=-1*theta2
timeFinal=time
DI.f=30/Tan(angFinal/57.3)
EndProcedure
Procedure RenderFrame2()
SetActiveWindow(#WinPath)
ClearScreen(RGB(255, 255, 255))
Static x, y, q
y=tallEff-(Scale*yInit)-24.0; Position of the cannon base. Base is 24 pix below img top
DisplaySprite(#GunImg,0,y) ; Cannon
;DisplaySprite(#ArrowUp,784,284) ; Green Arrow
;DisplaySprite(#FreighterBow,860,205) ; Shi
DisplaySprite(#FreighterBow, 0.75*Scale*maxRange,230) ; was 235
ZoomSprite(#FreighterBow,40,40) ; make freighter smaller
xPlot=xOffset+Scale*xFinal-13
ZoomSprite(#Splash2,30,70)
;DisplaySprite(#ArrowUp,xPlot+2,266)
;DisplaySprite(#Splash2,xPlot,188) ; the splash
DisplaySprite(#Splash2,xPlot,190) ; the splash was 198
;DisplaySprite(#ArrowUp,xPlot+2,261) ;the Up Arrow
DisplaySprite(#ArrowUp,xPlot+2,262) ; was 270
;Debug xPlot
RotateSprite(#Smoke,fireTheta,#PB_Absolute) ; this is smoke
y=tallEff-(Scale*yInit)-24-flashH
DisplaySprite(#Smoke,xOffset,y) ; smoke
; diplay trajectory
For i = 1 To maxIndex
x=xOffset+Scale*xRecord(i)
y=tallEff-(Scale*yInit)-(Scale*yRecord(i))-muzzle; plotted y coord for shell
DisplaySprite(#Shell,x,y) ; this is the projectile
Next i
q=q+1
EndProcedure
Procedure AppControl()
If EventGadget()=#ButtonRunAgain ;Run analysis again
HyperLinkGadgetEvent()
CloseWindow(#WinResults)
CloseWindow(#WinPath)
CloseWindow(#WinControl)
ElseIf EventGadget()=#ButtonToNavalResearch
HyperLinkGadgetEvent()
CloseWindow(#WinResults)
CloseWindow(#WinPath)
CloseWindow(#WinControl)
ElseIf EventGadget()=#ButtonToDionysus
HyperLinkGadgetEvent()
CloseWindow(#WinResults)
CloseWindow(#WinPath)
CloseWindow(#WinControl)
ElseIf EventGadget()=#ButtonToNotes
HyperLinkGadgetEvent()
CloseWindow(#WinResults)
CloseWindow(#WinPath)
CloseWindow(#WinControl)
Else
MessageRequester("Error at Line 252. Error in App Control Pnl")
EndIf
EndProcedure
Procedure Gadget0()
descript.s=GetGadgetText(#ProbDescr)
d=GetGadgetState(#BoreIn)
vInit=ValF(GetGadgetText(#VelIn))
v=vInit
w=ValF(GetGadgetText(#WtIn))
thetaInit=GetGadgetState(#AngIn)
yInit=GetGadgetState(#HighIn)
DF=GetGadgetState(#DragIn) ; issue here. DF needs to be divided by 10 before proceeding.
DF=DF/10.0 ;convert Drag Factor to unity based
If w=0
w=0.5*Pow(d,3.0)
EndIf
If vInit>3000.0
vInit=3000.0
EndIf
If vInit<100.0
vInit=100.0
EndIf
If d>21.0
d=21.0
EndIf
If d<3.0
d=3.0
EndIf
If thetaInit<0.2
thetaInit=1.0
EndIf
If thetaInit>70.0
thetaInit=70.0
EndIf
If yInit>500.0
yInit=500.0
EndIf
If yInit<-50.0
yInit=20.0
EndIf
If DF<0.3
DF=1.0
EndIf
If DF>3.0
DF=3.0
EndIf
If EventGadget()=#FireButton
CloseWindow(#WinInputs)
CloseWindow(#WinCannon)
CloseWindow(#WinDragFac)
CloseWindow(#WinKruppGun)
OpenWindow(#WinResults,5, 0, 225, 380, "Air Resistance Trajectory Results", #PB_Window_SystemMenu)
SetActiveWindow(#WinResults)
TextGadget(#ProbInputRptTitle,5,0,150,20,descript+":")
TextGadget(#BoretxtOut,5,30,150,20,"Gun Bore (inches) = "+StrF(d))
TextGadget(#VelTxtOut,5,60,150,20,"Muzzle Vel (ft/sec) = "+StrF(vInit))
TextGadget(#WtTxtOut,5,90,150,20,"Shell Weight (lbs) = "+StrF(w))
TextGadget(#AngTxtOut,5,120,150,20,"Elevation Angle (deg) = "+StrF(thetaInit))
TextGadget(#HighTxtOut,5,150,170,20,"Firing Platform Height (ft) = "+ StrF(yInit))
TextGadget(#DragTxtOut,5,180,150,20,"Drag Factor in Tenths = "+StrF(10.0*DF))
Trajectory()
; find the limits of range and altitude
maxAlt=0.0
maxRange=0.0
maxIndex=0
; find maximum index describing flight
For j = 1 To 999
If yRecord(j)>0
maxIndex=j
EndIf
Next j
; find maxAlt and maxRange values
For j=1 To maxIndex
If yRecord(j)>maxAlt
maxAlt=yRecord(j)
EndIf
If xRecord(j)>maxRange
maxRange=xRecord(j)
EndIf
Next j
temp=ExamineDesktops()
wide.f=DesktopWidth(0)-240
tall.f=DesktopHeight(0)
tallEff=0.30*tall
yScale=(tallEff-25)/(maxAlt+250.0)
xScale.f=(wide-75.0)/maxRange
If xScale<yScale
Scale=xScale
Else
Scale=yScale
EndIf
TextGadget(8,5,210,150,20,"............Results............")
TextGadget(9,5,240,250,20,"Range (ft)="+StrF(Round(xFinal,#PB_Round_Nearest)))
TextGadget(10,5,270,250,20,"Impact Velocity (ft/sec)="+StrF(vFinal)); verify this is correct
TextGadget(11,5,300,250,20,"Horizontal Impact Angle (deg)="+StrF(Round(100*angFinal,#PB_Round_Nearest)/100))
TextGadget(12,5,330,250,20,"Flight Time (sec)="+StrF(Round(10*timeFinal,#PB_Round_Nearest)/10))
TextGadget(13,5,360,250,20,"Danger Interval (ft)="+StrF(Round(10*DI,#PB_Round_Nearest)/10))
OpenWindow(#WinPath,240,600,wide,tallEff,"Trajectory Path with Air Resistance", #PB_Window_SystemMenu) ; was 600 tall
OpenWindowedScreen(WindowID(#WinPath),0,0,wide,tallEff)
SetActiveWindow(#WinPath)
BindEvent(#PB_Event_RenderFrame, @RenderFrame2()) ; if I comment this, then the green background command works.
BindEvent(#PB_Event_Loading, @Loading()) ; NECESSARY
If thetaInit>39.0
LoadSprite(#GunImg,"Mortar4.png")
xOffset=20.0
muzzle=21.0
flashH=21.0
fireTheta=0.0
ElseIf thetaInit>28.0
LoadSprite(#GunImg,"Mortar3.png")
xOffset=21.0
muzzle=19.0
flashH=17.0
fireTheta=16
ElseIf thetaInit>17.0
LoadSprite(#GunImg,"Mortar2.png")
xOffset=23.0
muzzle=19.0
flashH=12.0
fireTheta=22.0
ElseIf thetaInit>10.0
LoadSprite(#GunImg,"Mortar1.png")
xOffset=24.0
muzzle=17.0
flashH=9.0
fireTheta=33.0
Else
LoadSprite(#GunImg,"Mortar0.png")
xOffset=24.0
muzzle=12.0
flashH=2.0
fireTheta=44.0
EndIf
;LoadSprite(0, "CoastMortar.png")
LoadSprite(#ArrowUp, "ArrowUp.png")
;LoadSprite(2, "Oslyabya1.png")
;LoadSprite(2, "Tsar100.png")
;LoadSprite(2, "USCA1.png")
;LoadSprite(2, "Freighter125x73.png")
LoadSprite(#FreighterBow, "FreighterBow.png")
LoadSprite(#Smoke, "Fire4.png")
LoadSprite(#Shell,"Shell.png")
LoadSprite(#Splash2,"Splash2.jpg")
;LoadSprite(#OslyabyaTrans,"OslyabyaTrans.jpg") ; elimination of this enabled display of Freighter Bow
OpenWindow(#WinMap,240,0,wide,560,"Concept Map",#PB_Window_SystemMenu)
;Debug wide
If wide<1477
LoadImage(#MapSknyImg,"SKINNYSEA.PNG")
Else
LoadImage(#MapSknyImg,"COASTALMAP2.PNG")
EndIf
OpenWindow(#WinControl,5,418,225,105,"Program Control:", #PB_Window_SystemMenu)
SetActiveWindow(#WinControl)
ButtonGadget(#ButtonRunAgain,20,5,175,20,"Run Trajectory Analysis")
ButtonGadget(#ButtonToNavalResearch,20,30,175,20,"Goto Naval Research")
ButtonGadget(#ButtonToDionysus,20,55,175,20,"Goto Dionysus Home Page")
ButtonGadget(#ButtonToNotes,20,80,175,20,"Goto Instructions & Credits")
UnbindEvent(#PB_Event_Gadget,@Gadget0())
BindEvent(#PB_Event_Gadget,@AppControl())
EndIf ; End of the fire button press
EndProcedure
temp=ExamineDesktops()
wide=DesktopWidth(0)
tall=DesktopHeight(0)
OpenWindow(#WinInputs, 0, 435, 280, 250, "Enter Firing Conditions", #PB_Window_SystemMenu, #PB_Window_ScreenCentered)
StringGadget(#ProbDescr,8,10,140,20,"Enter Gun Description", #PB_String_LowerCase) ; input problem description
TextGadget(#BoreTxtIn,10,40,200,20,"Gun Bore (max 21 in)"); input gun bore in inches
SpinGadget(#BoreIn,200,37,70,20,3,21)
SetGadgetState(#BoreIn,12) ; initial setting is 12 inches
TextGadget(#VelTxtIn,10,68,250,20,"Muzzle Velocity (max 3000 ft/sec)")
StringGadget(#VelIn,200,64,40,20,"2400",#PB_String_Numeric)
TextGadget(#WtTxtIn,10,95,250,20,"Shell weight (lbs)")
StringGadget(#WtIn,200,90,40,20,"850",#PB_String_Numeric)
TextGadget(#AngTxtIn,10,120,200,20,"Elevation Angle (max 70 deg)")
SpinGadget(#AngIn,200,120,70,20,1,70)
SetGadgetState(#AngIn,20)
TextGadget(#HighTxtIn,10,150,200,20,"Gun Platform Height (max 500 ft)")
SpinGadget(#HighIn,200,150,70,20,0,501)
SetGadgetState(#HighIn,20)
TextGadget(#DragTxtIn,10,180,150,20,"Drag Factor 7 to 16 (tenths)")
SpinGadget(#DragIn,200,180,70,20,3,25)
SetGadgetState(#DragIn,10.0)
ButtonGadget(#FireButton,55,210,100,20,"Fire", #PB_Button_Toggle)
BindEvent(#PB_Event_Loading,@Loaded())
LoadImage(#GunImg,"GunInitCondit250T.jpg")
LoadImage(#DragTableImg,"DFTable.png")
LoadImage(#KruppLogoImg,"KRUPPGUN1897PD.JPG")
BindEvent(#PB_Event_Gadget,@Gadget0())