Skip to main content
gamedev.net
🔒 Locked

Some basic 2D physics

Started by sakky Feb 17, 2005 at 4:05 PM 10 replies 2k views
Original Post
sakky
sakky
Okay, I need to simulate the physics behind an Asteroids game and I'm using 2D mathematics not 3D. I know this may seam like a similar question in a different post, but its use in my project is different. So, I rotate a vector left or right (CW or CCW). Lets call the rotating vector the velocity or direction to where we want to go. Now I apply a force in the direction of the velocity with an acceleration that is constant for now, but I hope to change it to gradually increase to a set rate. So what is the math to move a from one position in the direction of the velocity by a specific force? What formula do I use?
Take back the internet with the most awsome browser around, FireFox
No_Germs
No_Germs
if i understand you correctly...
speed is the change in location over time, and acceleration is the change in speed over time, thus:

Speed.X+=Force.X;
Speed.Y+=Force.Y;

Location.X+=Speed.X;
Location.Y+=Speed.Y;

Motorherp
Motorherp
To get the acceleration from the force use newton 2:

Force = mass * acceleration

Then to get the velocity and position you need to do a bit of numerical integration. A basic euler integrator should do the trick. So:

Velocity += acceleration * dt
Position += velocity * dt

where dt is the time difference between updates. Simple as that.
[size="1"] [size="4"]:: SHMUP-DEV ::
JohnBolton
JohnBolton
It's better to have different vectors for the ship's direction and its velocity. I assume you want to accelerate in the direction the ship is pointing, which can be different from the direction of its velocity (for example, if the ship is traveling backwards).

The math is straightforward:

D = the direction the ship is pointing (a unit vector)
A = the ship's new acceleration (vector)
V0 = the ship's current velocity (vector)
V = the ship's new velocity (vector)
P0 = the ship's current position (vector)
P = the ship's new position (vector)
t = time passed since the last update
a = magnitude of acceleration

A = aD
V = V0 + At
P = P0 + V0t + ½At2

Both solutions posted by No_Germs and Motorherp have problems (the first requires a fixed time per frame, and the results in the second can quickly diverge from the correct values).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Zakwayda
Zakwayda
In addition to JohnBolton's suggestions, I'd like to add that Chris Hecker's articles on physics offer an excellent overview of 2D rotations and physics simulation. It's short, to the point, and covers all the basics. It might be very helpful to you.
Alpha_ProgDes
Alpha_ProgDes
Quote:
Original post by JohnBolton
It's better to have different vectors for the ship's direction and its velocity. I assume you want to accelerate in the direction the ship is pointing, which can be different from the direction of its velocity (for example, if the ship is traveling backwards).

The math is straightforward:

D = the direction the ship is pointing (a unit vector)
A = the ship's new acceleration (vector)
V0 = the ship's current velocity (vector)
V = the ship's new velocity (vector)
P0 = the ship's current position (vector)
P = the ship's new position (vector)
t = time passed since the last update
a = magnitude of acceleration

A = aD
V = V0 + At
P = P0 + V0t + ½At2

Both solutions posted by No_Germs and Motorherp have problems (the first requires a fixed time per frame, and the results in the second can quickly diverge from the correct values).


if a unit vector is always 1, IIRC, then wouldn't A = a?
unless D is measured in degrees or radians.
Beginner in Game Development?  Read here. And read here.  
sakky
sakky
So Bolton, its just the simple velocity and distance formulas in physics then? After reading these replies I need to change a few things.

The ship has a pointer vector called DIR(short for direction) and a velocity vector VEL. The ship may point in any direction it may and it will accelerate in the direction of the velocity. Or so to speak.

Basically, if the ship is traveling upwards and pointing to the left, applying thrust will in the direction the ship is pointing will change the direction of the velocity. Mass really has now concept here because it is not integrated in my scheme but I will integrate it now. So way, the ship has 900kg mass and it's thrusters produce around 500kg of thrust. Friction should also be applied here, but since the simulation takes place in space, friction or gravity really has no effect, or does it?

Any ways, to thrust forward is to thrust in the direction of DIR and to thrust backwards is the opposite (sort of like breaks). The thrusters start at a initial thrust, but because of the mass of the ship, the take off isn't so fast and jerky. So that being said, the thrust is constant but the acceleration isn't so I don't think those formula Bolton gave will work because they use constant acceleration and that is not true in my case.

So I use the thrust which is a constant 500kg and the mass of the ship which is a constant 900kg. Substituting acceleration for thrust I have a force of 450,000 WOW!

I think I just need to sit down and study the math and physics for this. Because it seams that this is a common problem with more then one solution.
Take back the internet with the most awsome browser around, FireFox
JohnBolton
JohnBolton
Quote:
Original post by Alpha_ProgDes
if a unit vector is always 1, IIRC, then wouldn't A = a?
unless D is measured in degrees or radians.
A is a vector, a is a scalar value (not a vector), and D is a unit vector. A = aD is how you compute a vector in the direction of D with a length of a.


sakky: Thrust (or force) and acceleration are related like this (as Motorherp already stated):

a = F/m

So, if you have constant force and constant mass, then you have constant acceleration (as long as the direction of the force is constant). You don't need varying acceleration -- a constant acceleration will cause the velocity to steadily increase or decrease, which is what I assume you are looking for.

Now, you might want to limit the velocity (for gameplay reasons) and there are different ways of doing that (clamp it or simulate drag).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
sakky
sakky
Well here is what I have right now. I don't know any other way to do this in Direct3D

// ----------------------------------------------------------------------------// Objects// ----------------------------------------------------------------------------typedef struct _OBJECT {	D3DXVECTOR3 POS ;	D3DXVECTOR3 DIR ;	D3DXVECTOR3 VEL ;} OBJECT, *LPOBJECT ;// ----------------------------------------------------------------------------// Name		: RotateObjectDirection( ... )// Desc		: Roate the direction vector of an object// ----------------------------------------------------------------------------void __stdcall RotateObjectDirection( LPOBJECT lpObject, FLOAT fAmount ){	D3DXMATRIX				 xRot ;	D3DXVECTOR3				 vRot ;	D3DXMatrixRotationY( &xRot, fAmount ) ;	vRot.x = ( xRot._11 * xRot._12 * xRot._13 * xRot._14 * lpObject->DIR.x ) ;	vRot.y = ( xRot._21 * xRot._22 * xRot._23 * xRot._24 * lpObject->DIR.y ) ;	vRot.z = ( xRot._31 * xRot._32 * xRot._33 * xRot._34 * lpObject->DIR.z ) ;	lpObject->DIR = vRot ;}// ----------------------------------------------------------------------------// Name		: ApplyThrustToObject( ... )// Desc		: Applies thrust to an object// ----------------------------------------------------------------------------void __stdcall ApplyThrustToObject( LPOBJECT lpObject, FLOAT fThrust ){	lpObject->VEL += ( lpObject->DIR * fThrust ) ;	lpObject->POS += lpObject->VEL ;}


Sorry, but the direction vector is normalized always and so is the velocity
Take back the internet with the most awsome browser around, FireFox
sakky
sakky
I can't get my object to rotate. How do you rotate in Direct3D using a vector? The way I'm doing it isn't working! I can't do anything because the object won't rotate.
Take back the internet with the most awsome browser around, FireFox
JohnBolton
JohnBolton
Quote:
Original post by sakky
I can't get my object to rotate. How do you rotate in Direct3D using a vector? The way I'm doing it isn't working! I can't do anything because the object won't rotate.
RotateObjectDirection is very wrong. If D3D has a function to transform a vector, use it. Otherwise, the code should look like this.
	vRot.x = ( xRot._11 * lpObject->DIR.x + xRot._21 * lpObject->DIR.y + xRot._31 * lpObject->DIR.z ) ;	vRot.y = ( xRot._12 * lpObject->DIR.x + xRot._22 * lpObject->DIR.y + xRot._32 * lpObject->DIR.z ) ;	vRot.z = ( xRot._13 * lpObject->DIR.x + xRot._23 * lpObject->DIR.y + xRot._33 * lpObject->DIR.z ) ; 


Note: You can simplify this. Since this is a rotation around the Y axis, the Y value does change and many of the elements in the rotation matrix are always 0 or 1.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
fuzinavl
fuzinavl
no need to get overly complicated for a simple asteroids game.
Fixed time slices are ok for beginner coders' games

Force = mass * acceleration
therefore, A = M / F

F = engine thrust force
M = ship mass
angle = the angle at which ship's nose is pointing
A = acceleration (change in velocity over time)
V = ship's velocity
P = ship's position in space

Every Game loop do:

Get input for "angle" ( right arrow pressed adds 0.1? to the angle)
(left arrow pressed subtracts 0.1? to the angle)
Get input For "F" ( if thrusters = on, F = 1400?, else F=0)

A.x = cos(angle) * (M/F)
V.x += A.x
P.x += V.x

A.y = sine(angle) * (M/F)
V.y += A.y
P.y += V.y

// an now we enforce the speed limit... C^2 = A^2 + B^2

float ship_speed = sqrt(V.x^2 + V.y^2);

if ( ship_speed > max_speed )
{
V.x *= max_speed / ship_speed;
V.y *= max_speed / ship_speed;
}

ta-da !

[Edited by - fuzinavl on February 19, 2005 10:55:17 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.