Skip to main content
GameDev.net gamedev.net
🔒 Locked

Vector Physics (2D so far)

Started by Andos Dec 25, 2003 at 12:46 PM 3 replies 2k views
Original Post
Andos
Andos
Hey I''m playing around with vector physics and i was looking for some resources on this topic. Google didn''t gave me any good results. Here is what i want to do: Make objects be affected by all the forces on them. Gravity and other forces. So this gives me some questions: •How can I convert spring forces into a force vector. Like if i pull the spring, a vector with a force would make it go towards it''s original position. The more i pull the spring the bigger the vector would be. If i push the spring, the vector would go the opposite way. •How can i smooth out the movement vector for example i have an object with an upwards pointed vector and i want gravity to slowly take the speed from the object and make it accelerate towards earth. Is it enough to say Gravity vector = (0,-50) and then the new movement vector of the object would be (0,x+(-50/100.0)) where i can control the strength og the gravity by dividing with 100. Is this just this? I''m not home right now so i can''t test it. Maybe later i would piece it together to a simple physics engine.
quasar3d
quasar3d
chris hecker has some very good tutorials about this. The first 3 articles are about 2D, and in the last one extends it to 3D.

http://www.d6.com/users/checker/dynamics.htm

My Site

[edited by - Quasar3D on December 25, 2003 3:09:32 PM]
idinkin
idinkin
Hi Andos,
The best way I found is to create virtual boxes around every object and to apply the forces to the box, then every frame to calculate and update the position of vertices in the box. Create your mechanics class, make it able to add new forces, update the forces applied to the boxes in your scene.

For instance, gravity. You add the force to the physics engine of yours (the class ). Then the class gets the list of the objects in your scene. Every box of the objects you sent to the physics class have their previous acceleration. Now you calculate the new acceleration by applying the gravity vector to the object. You just summ all the forces that apply to this object. The summ force will have it''s magnitude and direction. The direction of the accelration will be the same direction summ force has. And the magnitude(m/s^2) of the acceleration will be from the follwing formula:

summforce=mass * acceleration
=> acceleration = summforce / mass.

Oh i forgot each object must have the mass in it''s class too.

That''s all.
Hope this makes sense.
Ilya



It does not matter what you will reach in your life, but the way you will reach it
Sometimes movement is a result of a kick in the ass!
Andos
Andos
Thanks for the resources but i think I will stick to single point physics

Actually I just created my first physics engine where i have an object move on the screen. The gravity angle and strength can now easily be changed by changing two values (the gravity vector) and if i hold the mouse button down on my screen the curser acts like a magnet to the object.

I''m gonna try to figure out how to do the spring force -> vector method by trying but if you have an idea on how this could be made then you are welcome to tell me how

The articles on theese pages was kinda hard and i didn''t understand much of them becuse i''m only on my first year in "high school" and we haven''t really learned about vectors yet, so i''m quite surprised that the maths for single point vector physics wasn''t that hard at all.
oliii
oliii
I''ve got an hour to kill, so...

since you understand vectors, it should be simple to explain some simple particle/newton physics.

So, you have a particle, composed of various attributes. For a simple particle, you can limit those attributes to

- Vector Position (meters)
- Vector Velocity (meters per second)
- Vector Acceleration (meters per second2)
- Vector NetForce (Newtons)
- float Mass (kilograms)


and Newton''s Laws state

1) An object at rest tends to stay at rest and an object in motion tends to stay in motion with the same speed and in the same direction unless acted upon by an unbalanced force.

2) The acceleration of an object as produced by a net force is directly proportional to the magnitude of the net force, in the same direction as the net force, and inversely proportional to the mass of the object.

3) For every action there is an equal and opposite reaction.


the law number 2 simply says
particle.Acceleration = Particle.NetForce / Particle.Mass;

velocity is the rate of change of the particle position through time. Acceleration is the rate of change of the particle velocity through time.

so, given a time change dt

Particle.Position = Particle.Position + Particle.Velocity * dt
Particle.Velocity = Particle.Velocity + Particle.Acceleration * dt

this is called a euler integration, and is the simplest way to calculate the motion of objects in space.

in code, to update a particle''s attributes




//--------------------------------------------------

// add an instantaneous force to a particle

//--------------------------------------------------

void CParticle::AddForce(Vector Force)
{
NetForce += Force;
}

//--------------------------------------------------

// update particle''s physical attributes

//--------------------------------------------------

void CParticle::Update(float dt)
{
Acceleration = NetForce / Mass; // calcualte acceleration

Velocity += Acceleration * dt; // update velocity

Position += Velocity * dt; // update position

NetForce = (0, 0, 0) // reset instantaneous forces

}


dt, is the time elapsed since you last called the CParticle::Update(). To simplify, you can use a fixed timestep, so dt = 0.0166666 ( = 1.0f / 60 hertz = 1.0f / 60 fps).

The NetForce is the sum of the instantaneous forces acting on the particle during time dt. So you need to reset it to 0 when you finished.

the earth gravity is also considered a constant, g = (0/0f, -9.81f, 0.0f). Note that ''g'' is not a force, but more like an acceleration field, that provides an object with a constant vertical acceleration, whatever the mass of the particle. So, the force acting on the particle from the gravity will be Fgravity = (0.0f, -9.81f, 0.0f) * particle.Mass;

to update a number of particles in your simulation, where all particles are influenced by gravity



float dt = 1.0f / 60.0f;
Vector Gravity(0.0f, -9.81f, 0.0f);

void UpdatePhysics()
{
//-----------------------------------------------

// set instantaneous forces on the particles

//-----------------------------------------------

for(int i = 0; i < iNumParticles; i ++)
Particle[i].AddForce(Gravity * Particle[i].Mass);


//-----------------------------------------------

// update the particles positions

//-----------------------------------------------

for(int i = 0; i < iNumParticles; i ++)
Particle[i].Update(dt);
}


the particles will fall under the gravity, and keep on accelerating downwards.




for a spring that links two particles...

a spring has a rest length, where, when the particles'' distance is equal the rest length, the spring force is (0, 0, 0).

the spring force is calculated that way

|Fspring| = kspring(L - Lrest)

the force from the spring is directed along the spring segment, and pull/push the particles until their distance is equal to the rest length of the spring.

to model a spring linking two particles



float dt = 1.0f / 60.0f;
Vector Gravity(0.0f, -9.81f, 0.0f);

//-----------------------------------------------

// particles

// A : position(0, 0, 0), mass = 100 kgs

// B : position(4, 0, 0), mass = 20 kgs

//-----------------------------------------------

CParticle A(Vector(0.0f, 0.0f, 0.0f), 100.0f);
CParticle B((4.0f, 0.0f, 0.0f), 20.0f);

//-----------------------------------------------

// spring

// rest length = 2 meters

// k = 500 Newtons / meters

//-----------------------------------------------

float restLength = 2.0f; // rest length of 2 meters

float k = 500.0f; // stiffness of the spring


void UpdatePhysics()
{
//-----------------------------------------------

// calculate the spring force

//-----------------------------------------------

Vector L = B.Position - A.Position; // segment [A, B]

float f = k * (L.Length()-restLength); // spring force

Vector Dir = L / L.Length(); // direction of the spring


Vector SpringForce = Dir * f; // spring force vector


A.AddForce( SpringForce); // add spring force to particle A

B.AddForce(-SpringForce); // add spring force to particle B


//-----------------------------------------------

// update the particles positions

//-----------------------------------------------

A.Update(dt);
B.Update(dt);
}


you can play around, with linking more particles, making some of them immovable (no force can act on them), ect... You will need some damping as well, so that the motion looses energy to keep everything stable, and you may want to switch to a more stable integration method, so you can have springs with infinite stiffness (like metal beams), particle physics and verlet integration.


Everything is better with Metal.

Topic Locked

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

Sign in to reply to this topic.