Feeds:
Posts
Comments

Posts Tagged ‘trig’

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.8

I’m not interested in including wind resistence etc..

A Level maths to the rescue! Use one of the equations of motion:

s = ut + \frac{1}{2}at^2

Where s is the distance travelled, u is the initial velocity, a is the acceleration, and t is time elapsed. We want to find an angle \phi 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 t:

\begin{array}{rcl}s_x &=& x_1-x_0 \\ u_x &=& V \cos(\phi) \\ a_x &=& 0 \\ \\ s_x &=& (V \cos(\phi))t \\ t &=& \frac{s_x}{V \cos(\phi)} \end{array}

Now we can put that into the equation for the y-axis:

\begin{array}{rcl}s_y &=& y_1-y_0 \\ u_y &=& V \sin(\phi) \\ a_y &=& g \\ \\ s_y &=& V \sin(\phi) (\frac{s_x}{V \cos(\phi)}) + \frac{1}{2}g(\frac{s_x^2}{V^2\cos^2(\phi)}) \end{array}

Now some clever cancelling and use of trig identities:

\begin{array}{rcl} s_x \tan(\phi) + \frac{gs_x^2}{2V^2}\sec^2(\phi) - s_y &=& 0 \\ \frac{gs_x^2}{2V^2}\tan^2(\phi) + s_x\tan(\phi) + (\frac{gs_x^2}{2V^2} - s_y) &=& 0 \end{array}

which, if you’re willing to believe it, is a quadratic equation in \tan(\phi). Use the quadratic formula to find \tan(\phi) and hence \phi. 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!

Read Full Post »

Jussi writes,

Given the lengths of c1 and c2 and angle alpha, what’s the simplest and fastest way to calculate the length of d (see the attached image)?

vector1

Looks tricky at first, but trying to do it the boring way ended up giving me a nice answer.

What we want is to have the line with angle alpha intersect the hypotenuse of the triangle. So, let’s write down the equations of the two lines:

The hypotenuse can be written using the normal straight line formula:

y = c_1 - \frac{c_1}{c_2}x

While the other line is in polar co-ordinates because we only know the angle alpha:

\begin{array}{rcl} x &=& d \cos \alpha \\ y &=& d \sin \alpha \end{array}

Substitute those into the first equation:

d \sin \alpha = c_1 - \frac{c_1}{c_2}d \cos \alpha

We want to find d, so collect all the terms with d together:

d( \sin \alpha + \frac{c_1}{c_2}) = c_1

And finally divide by the stuff in the brackets:

d = \frac{c_1}{\sin \alpha + \frac{c_1}{c_2} \cos \alpha}

Now let’s check that it works with some bmax code:

Graphics 600,600,0

c1#=300
c2#=400

an#=0

While Not (KeyHit(KEY_ESCAPE) Or AppTerminate())
	x#=300-c2/2
	y#=300-c1/2
	DrawLine x,y,x+c2,y
	DrawLine x,y,x,y+c1
	DrawLine x+c2,y,x,y+c1

	an = (an+1) Mod 90

	t#=an/90
	r#=c1/(Sin(an)+(c1/c2)*Cos(an))
	DrawLine x,y,x+Cos(an)*r,y+Sin(an)*r

	Flip
	Cls
Wend

Yep!

Read Full Post »