Stevie G asks on the blitzbasic forums:
My mind’s gone a blank so I’m looking for some help here. What I need is the angle of elevation a weapon needs to be at to launch a projectile and hit a target. The target can be higher or lower than the weapon. I’m working in 2d so have the following information available:
X0 = X coord of weapon
Y0 = Y coord of weapon
X1 = X coord of target
Y1 = Y coord of target
Speed = Launch Speed of projectile
Gravity = -9.8I’m not interested in including wind resistence etc..
A Level maths to the rescue! Use one of the equations of motion:
Where is the distance travelled, is the initial velocity, is the acceleration, and is time elapsed. We want to find an angle to shoot the projectile at which will satisfy this equation.
Deal with the x- and y-components of motion separately. There’s no acceleration in the x-axis, so that equation will be easy to rearrange to get an expression for :
Now we can put that into the equation for the y-axis:
Now some clever cancelling and use of trig identities:
which, if you’re willing to believe it, is a quadratic equation in . Use the quadratic formula to find and hence . Simples!
… that’s a lie, so here’s some bmax code:
Graphics 600,600,0Graphics 600,600,0 Global bullets:TList=New TList Type bullet Field x#,y# Field vx#,vy# Field path#[] Function Create:bullet(x#,y#,vx#,vy#) b:bullet=New bullet bullets.addlast b b.x=x b.y=y b.vx=vx b.vy=vy Return b End Function Method update() path:+[x,y] x:+vx y:+vy vy:+g DrawRect x-5,y-5,10,10 For i=0 To Len(path)-1 Step 2 DrawRect path[i],path[i+1],1,1 Next If x>600 Or y>600 bullets.remove Self EndIf End Method End Type 'the setup is that you've got a cannon at (0,300), trying to fire at the mouse cursor. 'gravity is directed down the screen and the velocity of the projectiles is fixed at 20 px per frame. 'there will be some inaccuracy in the projectiles drawn on the screen because I'm using a discrete timestep model, due to I'm lazy. Const g#=1,v#=20 While Not (KeyHit(KEY_ESCAPE) Or AppTerminate()) sx#=MouseX() sy#=MouseY()-300 a#=g*sx*sx/(2*v*v) 'coefficients of the quadratic equation b#=sx c#=a-sy If b*b>4*a*c 'if solution exists t#=(-b+Sqr(b*b-4*a*c))/(2*a) 'this is tan(phi) an#=ATan(t) DrawLine 0,300,sx,sy+300 If MouseHit(1) bullet.Create 0,300,v*Cos(an),v*Sin(an) EndIf Else DrawText "no solution!",0,0 EndIf For bu:bullet=EachIn bullets bu.update Next Flip Cls Wend
Hope that’s useful!
Leave a comment