# Thread: Force and Velocity Physics

1. ## Force and Velocity Physics

I'm having trouble with the physics in my asteroid game. This is how I'm doing it now:

For the ship I know:
• It's heading in degrees (I'm thinking using degrees was a bad idea now.)
• It's speed
• It's position
• It's direction of momentum (The direction it's moving).

Basically when thrust is pressed, the direction of momentum is set to the ships current heading, then the ship is moved based off of that.

Now, it doesn't look that bad, except when you accelerate in a straight line, stop accelerating and change the direction of the ship, then thrust in the new direction. Instead of make a kind of arc like you would expect, it suddenly changes to the new direction.

I have some vague ideas of how fix this, but I wanted your advice David 2. Storing its heading is good, though you may want to store it in radians, given that that's what the trig functions in C++ use.

Storing speed and momentum direction separately is a bad idea. You need to store a movement vector. (Basically, its direction multiplied by the speed.) Every time unit, you simply add the vector to the position vector, and you've got the new position.

For thrust, you simply add sin(heading) to the x component of speed, and cos(heading) to the y component. If you want, you can multiply those by the thrust strength (e.g. if there's a power booster or something, or if it's simply off scale). You may also have to multiply it by the time delta. E.g. if you say that the spaceship accelerates by 1 per time unit, and 0.4 time units have elapsed since your last loop, you need to multiply by 0.4. If the player collects a thrust boost powerup, making his acceleraton 2.5 per time unit, then the next frame (0.6 time units later) must multiply by 1.5. 3. Storing its heading is good, though you may want to store it in radians, given that that's what the trig functions in C++ use.
Yeah, I should, because I was just converting it on the fly for the trig functions.

Storing speed and momentum direction separately is a bad idea. You need to store a movement vector. (Basically, its direction multiplied by the speed.) Every time unit, you simply add the vector to the position vector, and you've got the new position.
So a movement vector has, say rads multiplied by the speed?

I don't think this will fix the problem I'm really having trouble with. Here if you are on Windows you can test this and see what I mean.
http://idioticproductions.net/stuff/Asteroids2.zip
Just accelerate in one direction, stop accelerating and change direction then accelerate again.
You will see it just doesn't look right. 4. You add the vectors together to get what you want.

velocity.x += thrust.x;
velocity.y += thrust.y; 5. I really appreciate the effort, but I just can't comprehend it. Would you mind giving me a quick example? 6. This is what CornedBee and Bubba was talking about.

Store your positions, velocities and forces in vectors, that is something like
Code:
`float speed;`

Let the first value in the vector be the x value and the second value be the y value.

Then your position update function would be something like this:

Code:
```// angle is the direction of the object in radians.
force = cos(angle) * thrust;
force = sin(angle) * thrust;

for (i = 0; i < 2; i++) {
// mass is a float with the mass of the object and time_step is the time between each frame.
velocity[i] += mass * force[i] * time_step;
position[i] += velocity[i] * time_step;
}```
And then you just draw the object at its new position.

Try searching google for vector class implementations (most are 3d but that doesn't matter).

Good luck.

/f 7. OK, wow. The first time I read through that I didn't really get what you were doing, but then it just clicked. Once I get it all working nicely I'll post it in the games sticky.

Thank you so much guys!  8. I don't take into account the mass but do the same thing.

Code:
```void PlayerShip::Thrust()
{

m_vecVel.x -= (sinf(m_Angle)*1.5f);
m_vecVel.y += (cosf(m_Angle)*1.5f);

}

void PlayerShip::Update(float fTimeDelta)
{
m_vecPos.x += (m_vecVel.x * fTimeDelta);
m_vecPos.y += (m_vecVel.y * fTimeDelta);
...```
The - and + in Thrust() are to align my coordinates.

BTW you should probably divide by mass since a large mass in that posted equation will result in a large overall velocity which is inverse of what should really happen.

It's F=ma but in this case we are trying to find out the acceleration, not the force. The force being applied is the thrust vector. So the result is A= F/m. 9. OK, well I think is what is throwing me off, is when you are using (x,y) I don't know if you mean them as coordinates or as vector x and y components?

So for this example that you gave:
velocity.x += thrust.x;
velocity.y += thrust.y;

velocity x and y aren't coordinates, they must be the a and b of the triangle formed by the velocity vector?

Sorry I'm slow about this stuff, I just haven't had any courses over it yet, and it's hard for me to learn this stuff off internet tutorials. EDIT: Yah! sweet, that did the trick. It works great now. 10. Originally Posted by IdioticCreation OK, well I think is what is throwing me off, is when you are using (x,y) I don't know if you mean them as coordinates or as vector x and y components?
With vectors, there isn't much difference. It's only in the usage. When the vector describes a position, x and y are coordinates. When it describes movement, they are offsets. When it describes thrust, they are force components. And so on. 11. As Bubba pointed out, I should of course have written that you should multiply with the inverse of the mass...

Code:
```// angle is the direction of the object in radians.
force = cos(angle) * thrust;
force = sin(angle) * thrust;

for (i = 0; i < 2; i++) {
// mass is a float with the mass of the object and time_step is the time between each frame.
velocity[i] += inv_mass * force[i] * time_step;
position[i] += velocity[i] * time_step;
}```
/f 12. Originally Posted by fractality This is what CornedBee and Bubba was talking about.

Code:
`  velocity[i] += mass * force[i] * time_step;`
That simply isn't right. According to this, objects with larger masses will accelerate more quickly than objects with smaller masses. Get back to the basic equation:

F = ma
a = F / m

Make the finite difference approximation:

a = dv/dt ~= delta_v / delta_t = F / m
delta_v = F / m * delta_t.

In other words, you must divide by mass, not multiply by it. 13. Hey brewbuck we already caught that up there somewhere. My last post talks about the issue. Popular pages Recent additions 