Feeds:
Posts
Comments

Archive for March, 2010

therevills asks on the blitzbasic.com forums:
Does any one know how to do this?

I know the following:

* Start x,y
* End x,y
* Gravity
* Height of the wall

Diagrams:

………………..wall
____s______|__________e_________

_s_|
……|
……|
……|_e_

etc

Any ideas?

What I’ll do is find the smallest possible solution to this problem – the angle and speed to fire the projectile such that it just skims the top of the wall before it hits the end point. I’ll also only consider the case where the end point is at the same height as the start point. You can use the ideas in my previous post to sort out the other cases.
The relevant equation of motion is:
s = ut + \frac{1}{2}at^2
where s is distance travelled, u is initial velocity, a is acceleration, and t is time elapsed.
Suppose that the projectile reaches the wall at t_0 and the end point at t_1.
We’ll say that the distance from the start to the wall is x_1, the distance to the end point is x_2, and the height of the wall is y.
We’ll also say that the speed of the projectile is V and the angle it is fired at is \theta.
So we want:
\begin{array}{rcl} x_2 &=& t_1 V \cos(\theta) \\ 0 &=& t_1 V \cos(\theta) + \frac{1}{2}gt_1^2 \\ x_1 &=& t_0 V \cos(\theta) \\ y &=& t_0 V \sin(\theta) + \frac{1}{2} g t_0^2 \end{array}
We can rearrange the first two equations (involving three unknowns, so we definitely need the other two!) to find v in terms of \theta:
t_1 = \frac{x_2}{V \cos(\theta)}
\frac{x_2}{\cos(\theta)} \sin(\theta) +\frac{1}{2}g\frac{x_2^2}{V^2 \cos^2 (\theta)} = 0
V^2 \sin(\theta) \cos(\theta) = - \frac{1}{2} a x_2
Use the fact that \sin(2\theta) = 2\sin(\theta)\cos(\theta) to get
V^2 = \frac{-ax_2}{\sin(2\theta)},
which will come in handy in a bit.
Doing the same kind of thing with the other two equations, we get
\sin(2\theta) + \frac{ax_1}{V^2} = 2\frac{y}{x_1}\cos^2(\theta)
Substitute the thing we had for V^2 to get
\sin(2\theta) - \frac{x_1\sin(2\theta)}{x_2} = 2\frac{y}{x_1}\cos^2(\theta)
Rearrange and use that trig fact again to get
\frac{2\cos(\theta)\sin(\theta)}{2\cos^2(\theta)} = \frac{yx_2}{x_1x_2 - x_1^2}
Cancel down the left side and use \tan(\theta) = \frac{\sin(\theta)}{\cos(\theta)}:
\tan(\theta) = \frac{yx_2}{x_1x_2 - x_1^2}
Hooray, we’ve got a formula for \theta! Once we’ve found that, we can put it back into the handy equation for V^2, and we’ve got both the angle and speed of the projectile. Remember this give the minimum solution – you can increase V and rearrange the handy equation to get a suitable value for \theta.
As always, here’s some BlitzMax code demonstrating this:
Graphics 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

Const g#=1,x1#=300

While Not (KeyHit(KEY_ESCAPE) Or AppTerminate())
	x2#=MouseX()
	y#=MouseY()-300

	DrawLine 300,300,300,300+y
	DrawLine 0,300,x2,300

	If MouseHit(1)
		If x2>x1 And y<0
			theta# = ATan(-y*x2/(x2*x1-x1*x1))
			v=Sqr(g*x2/(Sin(2*theta)))
			Print theta
			Print v
			bullet.Create(0,300,v*Cos(-theta),v*Sin(-theta))
		EndIf
	EndIf

	For bu:bullet=EachIn bullets
		bu.update
	Next

	Flip
	Cls
Wend

Read Full Post »