Sign in to follow this  
tenpoundbear

How to represent acceleration as a vector?

Recommended Posts

Hey guys, I got a few questions to ask. Basically I am up to a stage where I want to start how to incorporate acceleration and velocity into my game. I understand basic algebra concerning how to find acceleration, velocity and displacement and the equations of motion (I am not sure if this term was only used in the text, Beginning Math and Physics for Game Programmers by Wendy Stahler, or if it is a universal term/convention). In my application this is what I am thinking so far...
Within 1 frame,
If 'w' is pressed down.
{
	Get acceleration.

	If 'w' is still pressed down (that is it is not released yet from before)
		New Acceleration = Current Acceleration add 1
	End If

	Update velocity.
	Work out displacement based on velocity (object always moves forward in the direction it is looking).
	New position = current position add displacement.
	Draw object at new position.
}
Else
{
	Deal with this situation later.
}






I think this would work, I am not looking for perfection but just a level of believability that is acceptable (it is just a sci-fi game after all). So back to my questions I had... With acceleration, how can I represent it as a vector? I mean acceleration is just a number (eg. 12 m/s and a 3D vector has 3 components). I know a vector has direction and length, and I am guessing that the length is what determines the acceleration? My other question is how do game developers determine acceleration in their games? Is it just a magic number made up randomly or is it based on existing technology (eg. I have spaceships in my game, so would I base the acceleration for my object based on say F-14 jet or some NASA space shuttle even?) Another question is have is concerning units of measurements in my game. I am sure game developers wouldn't be using real exact metrics within their game (because the numbers would be too large in certain situations?), but rather down scale the metrics? So using my game as an example, it is set in space, if the moon is 384,403 km from the earth, in my game I would maybe convert that to a smaller number? Is that the normal practice by developers? And if so, what is a good amount to scale it down to, 1/10th or 1/5th of actually distance? Sorry about all the questions guys, and the long post. If there are anything unclear about it please don't hesitate to ask. Many thanks guys.

Share this post


Link to post
Share on other sites
You already got the right idea about the vector. You said that your ship is traveling in the direction it's facing. To express acceleration as a vector, first get the vector representing the direction the ship is facing, the normalize it (it becomes length 1), then multiply by acceleration.

In a game with "real physics", acceleration is not an input. Rather, you add forces to objects at each frame and have the physics library work out acceleration, velocity, position, etc. Objects may also be connected by joints, which add their own forces to keep things connected. Games with "fake physics" just use whatever they want or whatever feels right (gameplay takes precedence), some bother about units but you will typically see "maximum velocity" which is of course nonsense in space (at least up to 2.99792458x10^8 m/s).

Scale is a problem in space games for many reasons. The primary culprit is the inaccuracy of floats, which have something like six significant digits. Once you get a bit (like 1000km) away from the origin, you already cannot tell the difference between millimeters. You can imagine what happens when you get further out. There are also z-buffer fighting artifacts during rendering because the z-buffer does not have enough precision. These problems are not impossible to solve (look into a series of articles called "real-time procedural universe" if you're interested), but you won't have them in the first place if you forget about real-life scale and keep everything in a small area.

Share this post


Link to post
Share on other sites
Quote:

With acceleration, how can I represent it as a vector? I mean acceleration is just a number (eg. 12 m/s and a 3D vector has 3 components). I know a vector has direction and length, and I am guessing that the length is what determines the acceleration?

Yup! So you'd do like:

while(1)
{
if ( 'w' pressed )
cur_vel += vec3( 0, 2.5f , 0 ) * dt;
if ( 's' pressed )
cur_vel += vec3( 0, -2.5f, 0 ) * dt;
if ( 'a' pressed )
cur_vel += vec3( 1.25f, 0, 0 ) * dt;
if ( 'd' pressed )
cur_vel += vec3(-1.25f, 0, 0 ) * dt;

cur_pos += cur_vel * dt;

dt = time_elapsed_since_last_frame;
}

It gets way more complicated than that if you want it to be "real". But at that point, shift to using a physics system like Bullet, PhysX, or Havok.

Quote:

My other question is how do game developers determine acceleration in their games? Is it just a magic number made up randomly or is it based on existing technology

Usually just made up. Sometimes you shoot for realistic numbers like "jet planes fly at 500Mph" or race cars drive at 150Mph. But games are about what feels good, not what is real most the time. So the same reasoning goes for your distances question.

Quote:

some bother about units but you will typically see "maximum velocity" which is of course nonsense in space (at least up to 2.99792458x10^8 m/s).

Not really. I mean you COULD accelerate without bounds, but it is VERY logical to cap speed in space. You usually have finite acceleration, and so if it takes you 1min to get to speed X, it will take you 1min to slow back down. If you are reacting to objects that change on a scale of less than 2min you're kinda screwed.

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran

while(1)
{
if ( 'w' pressed )
cur_vel += vec3( 0, 2.5f , 0 ) * dt;
if ( 's' pressed )
cur_vel += vec3( 0, -2.5f, 0 ) * dt;
if ( 'a' pressed )
cur_vel += vec3( 1.25f, 0, 0 ) * dt;
if ( 'd' pressed )
cur_vel += vec3(-1.25f, 0, 0 ) * dt;

cur_pos += cur_vel * dt;

dt = time_elapsed_since_last_frame;
}


Aren't you mixing local space and world space here?

Quote:
Original post by KulSeran
Not really. I mean you COULD accelerate without bounds, but it is VERY logical to cap speed in space. You usually have finite acceleration, and so if it takes you 1min to get to speed X, it will take you 1min to slow back down. If you are reacting to objects that change on a scale of less than 2min you're kinda screwed.

It's nonsense from a physics perspective. For gameplay it's of course completely logical :D

Share this post


Link to post
Share on other sites
Local and world space haven't really been defined for this problem yet. So afawk it's all the same. (2D platformer maybe, top down shooter like geometry wars?)

Also in the real world exists terminal velocity. If you're not going to incorporate drag then capping the velocity is a way to get reasonably accurate results.

Share this post


Link to post
Share on other sites
Hey guys,

Thanks for replies.

The game is actually a 3D space game btw, sorry I didn't mention that earlier.

I will be following lightbringer's advise, I have actually normalized a vector and then multiple by a scalar value and add to original vector to move it along before but it just didn't tick in my brain that I could treat the scalar value as if it was an acceleration value.

My next question is that if I normalize the vector and then multiply it by the acceleration value, won't that give me a vector that is greater than the original (if acceleration > 1), hence when I add the original vector with this acceleration vector won't it be too big of a jump/displacement?

If I had 35 m/s as my acceleration for example, when I go to multiply that by the normalized vector I will end up with a vector that is 35 larger then original?

A solution to the problem I thought is to maybe divide all my metrics by 100, that way 35 would equal to 0.35 and hence less than 1, and hence the displacement/increments that I add to the original vector wouldn't be such a huge jump? Is that a acceptable solution?

Or did I miss something very important in lightbringer's post, and hence everything I've type so far is invalid :)

Again appreciate it guys.

Share this post


Link to post
Share on other sites
Here's some code for what I'm doing in my games:

  m_vAcceleration = -m_vVelocity.Normalised();
m_vAcceleration *= m_fFriction->GetValueFloat();

MVector2 vDeltaVelocity = ( ( m_vAcceleration * fDelta ) / 1000.0f );

// Cap magnitude of change in velocity to remove integration errors
if( vDeltaVelocity.Magnitude() > m_vVelocity.Magnitude() )
m_vVelocity.Zero();
else m_vVelocity += vDeltaVelocity;

m_vPosition += ( ( m_vVelocity * fDelta ) / 1000.0f );

if(m_vVelocity.Magnitude() < m_fCutOff->GetValueFloat())
m_vVelocity.Zero();


Where most of those variables are 2D vectors. This is actually modified from some university code a while back, so if you don't like it you may blame my lecturer! You can modify the friction value and also the cut-off point, which stops the object from moving if the velocity is minute.

I forgot to add this first time round. I'm applying an impulse based on key-presses in a separate function where input is handled:

	if( pKeyState[SDLK_LEFT] ) m_vVelocity.x -= m_fImpulse->GetValueFloat();
if( pKeyState[SDLK_RIGHT] ) m_vVelocity.x += m_fImpulse->GetValueFloat();
if( pKeyState[SDLK_UP] ) m_vVelocity.y -= m_fImpulse->GetValueFloat();
if( pKeyState[SDLK_DOWN] ) m_vVelocity.y += m_fImpulse->GetValueFloat();


[Edited by - chapter78 on March 16, 2010 4:14:21 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by tenpoundbear
If I had 35 m/s as my acceleration for example, when I go to multiply that by the normalized vector I will end up with a vector that is 35 larger then original?


A normalized vector is always length one. If you multiply by your acceleration you will always get a vector with length equal to the acceleration, which is what you want. Acceleration is in m/s^2, although you will be applying it many times per second so it's not really per second squared. Acceleration affects velocity, and velocity affects position.

Quote:
Original post by tenpoundbear
hence when I add the original vector with this acceleration vector won't it be too big of a jump/displacement?

35 m/s^2 is nothing to sneeze at :) That's more than three times faster rate of change of velocity than for a falling object on the surface of the earth. You can also forget about acceleration and work with velocity directly. When user presses w, increase velocity (scalar), up to whatever maximum you want to cap velocity at. Then to work out position, you can get the current facing vector, normalize it, multiply by velocity scalar, and add to position.

Share this post


Link to post
Share on other sites
Quote:

35 m/s^2 is nothing to sneeze at :)


I'd say a sneeze involves accelerations far, far higher than 3.5G. So would flying a typical space fighter.


Quote:
Then to work out position, you can get the current facing vector, normalize it, multiply by velocity scalar, and add to position.


While that's what the OP asked for, I think it's likely to provide unsatisfying gameplay. If an object always moves in the direction it's facing, it'll behave like a tank, or a shopping cart, or a tricycle.

It'd make more sense to have the ship accelerate in the direction it's facing, but able to travel with any velocity, regardless of its orientation. The only scalar value would be 'thrust', which you'd multiply with the ship's heading, add to whatever accelerations you've gathered, then add to velocity and then to position.

That would feel far more realistic (it'd handle like a rocket) and allow all sorts of other forces to affect the ship realistically: gravity, collisions, explosions, tractor beams, drag and so on.

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
Quote:

With acceleration, how can I represent it as a vector? I mean acceleration is just a number (eg. 12 m/s and a 3D vector has 3 components). I know a vector has direction and length, and I am guessing that the length is what determines the acceleration?

Yup! So you'd do like:


Wrong.

Acceleration is a vector. If it was not then you would not be able to use Newtons equations of motion such as p=ut + 1/2 at^2, as you would be mixing vectors and scalars willy nilly.

Acceleration occurs to to a force being applied. F=MA (force = mass times accleration) or A = F/M. The force applied has a direction and magnitude (i.e. a vector). In the case of a spaceship with a rocket engine, the propellent would be ejected from the rear of the ship, so (using 2d for simplicity) we can work out the force vector as Fx=Fsin(a) and Fy=Fcos(a) where F is the magnitude of the force and a is the angle of direction.

We can then plug this into any of the equations of motion we wish as expressed by vectors, e.g. distance traveled in time t with an inital velocity of u and a constant acceleration a = ut+1/2 at^2.

Share this post


Link to post
Share on other sites
KulSeran's code was a completely appropriate application of eulers method for integrating the equation of motion. (albeit a bit cluttered :P)

I would have written it like this:

const float forwardAcc = 2.5f, sideAcc = 1.25f;
vec3 cur_acc = vec3::ZeroVec;

if ( 'w' pressed ) cur_acc += vec3( 0, forwardAcc, 0 );
if ( 's' pressed ) cur_acc += vec3( 0, -forwardAcc, 0 );
if ( 'a' pressed ) cur_acc += vec3( sideAcc, 0, 0 );
if ( 'd' pressed ) cur_acc += vec3(-sideAcc, 0, 0 );

cur_vel += cur_acc * dt;
cur_pos += cur_vel * dt;


If you want to debate the accuracy of this method, that's a different discussion.

A small modification will make it behave like Helicobster's suggestion:


const float forwardAcc = 2.5f, sideAcc = 1.25f;
const vec3 facingDir = ship.FacingDirection();
const vec3 sideDir = ship.SideDirection();

vec3 cur_acc = vec3::ZeroVec;

if ( 'w' pressed ) cur_acc += facingDir * forwardAcc;
if ( 's' pressed ) cur_acc += facingDir * -forwardAcc;
if ( 'a' pressed ) cur_acc += sideDir * sideAcc;
if ( 'd' pressed ) cur_acc += sideDir * -sideAcc;

cur_vel += cur_acc * dt;
cur_pos += cur_vel * dt;


Share this post


Link to post
Share on other sites
Hey guys,

I just wanted to say thanks for the replies.

I am going to postpone this part of my application for the moment, going to work on a 3D first-person type camera (its for spacecrafts set in space so it has yaw, pitch and roll... and everything in between) instead and come back to this later.

I do have a few questions about some of the replies... but I leave that for later.

Again, appreciate the replies and wanted to just say thanks :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this