Answered by:
Tanks Physics
Question

Answers

First of all the best way to handle this is to break the movement down into x and y components. The x movement is unaffected by gravity. There are basic equations to do with Newtonian mechanics which I advise you to look up in case my memory is failing. (Look up "Equations of motion").
v = u + at
where v = velocity
u = initial velocity
a = acceleration (in this case 0)
This will give you your x velocity which unless there is any drag will be a constant u as there is no acceleration a.
s = ut + 0.5at^2
s = distance travelled
a = acceleration (in this case g = 9.81 m/s^2)
Note that if y is up then a will be negative.
Try these to start with. You may then consider adding atmospheric drag or wind effects. See Small Basic Gorillas; banana, tank shell, they behave the same way. Proposed as answer by FremyCompany [MSFT] Thursday, June 25, 2009 6:52 PM
 Marked as answer by Ed Price  MSFTMicrosoft employee, Owner Tuesday, October 23, 2012 7:50 AM

If you ignore air viscosity this way should be OK:
alpha=45 velocity=50 xpos=200 ypos=200 gravity=10 wind=1 xvel=velocity*Math.Cos(alpha*Math.Pi/180) yvel=velocity*Math.Sin(alpha*Math.Pi/180) GraphicsWindow.Show() GraphicsWindow.PenColor=0 For i=1 To 200 oldy=ypos oldx=xpos yvel=yvelgravity*i*0.1 xvel=xvel+wind ypos=yposyvel 'Y axis is reversed in graphics window! xpos=xpos+xvel GraphicsWindow.DrawLine(oldx,oldy,xpos,ypos) EndFor
Grzesio Proposed as answer by FremyCompany [MSFT] Thursday, June 25, 2009 6:52 PM
 Marked as answer by Ed Price  MSFTMicrosoft employee, Owner Tuesday, October 23, 2012 7:51 AM

Nice,
If The Hacker wants to include air resistance (friction  not a big issue for a heavy tank shell but why not) we need a term to modify xvel and yvel accordingly. For turbulent flow in air it is reasonable to assume the frictional deceleration is proportional to the square of velocity, using the Math.Abs to keep the sign correct.
Try:
yvel=yvelgravityfriction*yvel*Math.Abs(yvel)
xvel=xvel+wind*0.1friction*xvel*Math.Abs(xvel)
where friction = 0.001
Also if we want to work in real units we can assume 1 pixel = 1m. Then gravity = 10 m/s2. Wind is m/s etc. To run with this we should use smaller timesteps (currently dt = 1s) since these are set by i incrementing by 1.
If we set dt = 0.1 (s) (or smaller  consider velocity is now hundreds of m/s)
Then:
yvel=yvelgravity*dtfriction*yvel*Math.Abs(yvel)*dt
xvel=xvel+wind*dtfriction*xvel*Math.Abs(xvel)*dt
ypos=yposyvel*dt 'Y axis is reversed in graphics window!
xpos=xpos+xvel*dt
Also initial velocities are then in m/s (typically around 300m/s)
xvel=velocity*Math.Cos(angle*Math.Pi/180)
yvel=velocity*Math.Sin(angle*Math.Pi/180)
The only advantage of considering the units is that we can more easily set up more realistic tank shots (low angle & high velocity) rather than big lobbing 'cannon balls' and the 'normalisations' have physical significance.
 Edited by litdevModerator Thursday, June 25, 2009 8:30 PM
 Marked as answer by Ed Price  MSFTMicrosoft employee, Owner Tuesday, October 23, 2012 7:51 AM
All replies

First of all the best way to handle this is to break the movement down into x and y components. The x movement is unaffected by gravity. There are basic equations to do with Newtonian mechanics which I advise you to look up in case my memory is failing. (Look up "Equations of motion").
v = u + at
where v = velocity
u = initial velocity
a = acceleration (in this case 0)
This will give you your x velocity which unless there is any drag will be a constant u as there is no acceleration a.
s = ut + 0.5at^2
s = distance travelled
a = acceleration (in this case g = 9.81 m/s^2)
Note that if y is up then a will be negative.
Try these to start with. You may then consider adding atmospheric drag or wind effects. See Small Basic Gorillas; banana, tank shell, they behave the same way. Proposed as answer by FremyCompany [MSFT] Thursday, June 25, 2009 6:52 PM
 Marked as answer by Ed Price  MSFTMicrosoft employee, Owner Tuesday, October 23, 2012 7:50 AM

If you ignore air viscosity this way should be OK:
alpha=45 velocity=50 xpos=200 ypos=200 gravity=10 wind=1 xvel=velocity*Math.Cos(alpha*Math.Pi/180) yvel=velocity*Math.Sin(alpha*Math.Pi/180) GraphicsWindow.Show() GraphicsWindow.PenColor=0 For i=1 To 200 oldy=ypos oldx=xpos yvel=yvelgravity*i*0.1 xvel=xvel+wind ypos=yposyvel 'Y axis is reversed in graphics window! xpos=xpos+xvel GraphicsWindow.DrawLine(oldx,oldy,xpos,ypos) EndFor
Grzesio Proposed as answer by FremyCompany [MSFT] Thursday, June 25, 2009 6:52 PM
 Marked as answer by Ed Price  MSFTMicrosoft employee, Owner Tuesday, October 23, 2012 7:51 AM

In the absence of wind or air resistance we should have a parabolic flight. The change in y velocity arising from gravity should be proportional to gravity * timestep and not gravity * time.
yvel=yvelgravity*i*0.1
Should be
yvel=yvelgravity*dt
Where dt is a constant (timestep) scaled to fit the units and window size being used, say dt = 0.8 works for starters OK here.


I've added some comments, normalizations, GraphicsWindow resizing etc. and published on: http://smallbasic.com/program/?KDM274
Grzesio 
Nice,
If The Hacker wants to include air resistance (friction  not a big issue for a heavy tank shell but why not) we need a term to modify xvel and yvel accordingly. For turbulent flow in air it is reasonable to assume the frictional deceleration is proportional to the square of velocity, using the Math.Abs to keep the sign correct.
Try:
yvel=yvelgravityfriction*yvel*Math.Abs(yvel)
xvel=xvel+wind*0.1friction*xvel*Math.Abs(xvel)
where friction = 0.001
Also if we want to work in real units we can assume 1 pixel = 1m. Then gravity = 10 m/s2. Wind is m/s etc. To run with this we should use smaller timesteps (currently dt = 1s) since these are set by i incrementing by 1.
If we set dt = 0.1 (s) (or smaller  consider velocity is now hundreds of m/s)
Then:
yvel=yvelgravity*dtfriction*yvel*Math.Abs(yvel)*dt
xvel=xvel+wind*dtfriction*xvel*Math.Abs(xvel)*dt
ypos=yposyvel*dt 'Y axis is reversed in graphics window!
xpos=xpos+xvel*dt
Also initial velocities are then in m/s (typically around 300m/s)
xvel=velocity*Math.Cos(angle*Math.Pi/180)
yvel=velocity*Math.Sin(angle*Math.Pi/180)
The only advantage of considering the units is that we can more easily set up more realistic tank shots (low angle & high velocity) rather than big lobbing 'cannon balls' and the 'normalisations' have physical significance.
 Edited by litdevModerator Thursday, June 25, 2009 8:30 PM
 Marked as answer by Ed Price  MSFTMicrosoft employee, Owner Tuesday, October 23, 2012 7:51 AM


My apologies. After checking, it seems that the drag is proportional to the square of the speed, but the power required to overcome the drag at a constant speed (in a car for example) is proportional to the cube of the speed which is not relevant to this problem.

Stendec,
Projectiles is not an area of physics I have any particular expertise, but if you look at (for example) http://en.wikipedia.org/wiki/Drag_coefficient :
Fd is the deceleration force proportional to acceleration and Cd is a constant (drag coefficient), where v is velocity. I am more certain that turbulent flow pressure gradient is proportional to v^2 and think the analogy to projectile friction probably holds. I am certainly interested to learn differently. 
The deceleration is proportional to velocity squared. Line 719 of the last stargates uses it to slow down the ships exploding bits, visually looks pretty real, although i made up all the drag coefficient & gravity numbers to make it look pretty.
Making games realistic is fun, but many times unrealistic behavior is even more so... 
The only advantage of considering the units is that we can more easily set up more realistic tank shots (low angle & high velocity) rather than big lobbing 'cannon balls' and the 'normalisations' have physical significance.
You are right but real tanks don't change their shot power. Aiming relies on angle only and trajectories are quite flat.
Setting angle+power and looking at steep lobs heavily changed by wind seems to be more funny in computer games. ;)
Even when it is not very realistic...
Grzesio 

