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

Basic physics simulation not working

Started by stannisbaratheon Jul 30, 2012 at 11:27 PM 7 replies 1.6k views
Original Post
stannisbaratheon
stannisbaratheon
I'm making a simple simulation of a ball thrown up in the air (ignoring air resistance). When the ball reaches it's maximum height it stays there for about a second. Surely this isn't right (although it does come down again)?


double time=0;
double yspeed = 70,yacc =5;

while (true)
{
yacc = yacc - (9.81/50); //remove a 50th of deacceleration due to gravity
yspeed = yspeed + (yacc/50); //add acceleration to speed
ballpos.y = ballpos.y - (yspeed/50); //change ballposition to reflect speed (ball pos starts at bottom of screen)


SDL_BlitSurface (background,NULL,screen,NULL);
SDL_BlitSurface (block,NULL,screen,&ballpos);
SDL_Flip(screen);

time = time + 0.02;
SDL_Delay(20); //50 fps

}
Cornstalks
Cornstalks
If you're going for more realistic physics, your equations are wrong. First, the acceleration doesn't change. There's a constant -9.8 m/s acceleration due to gravity. You shouldn't be modifying the acceleration.

Velocity v at time t is given by (where v(0) is the initial velocity and a is a constant acceleration (-9.8 in this case due to graivity)):
v(t) = v(0) + a * t

Position x at time t is given by (where x(0) is your starting position, v(0) is your starting velocity, and a is your constant accelation):
x(t) = x(0) + v(0) * t + (1 / 2) * a * t [sup]2[/sup]

If you want non-constant acceleration, you have to do some calculus and integrate things, so you'd use an integrator like Verlet integration or semi-implicit Euler integration.
stannisbaratheon
stannisbaratheon

If you're going for more realistic physics, your equations are wrong. First, the acceleration doesn't change. There's a constant -9.8 m/s acceleration due to gravity. You shouldn't be modifying the acceleration.

Velocity v at time t is given by (where v(0) is the initial velocity and a is a constant acceleration (-9.8 in this case due to graivity)):
v(t) = v(0) + a * t

Position x at time t is given by (where x(0) is your starting position, v(0) is your starting velocity, and a is your constant accelation):
x(t) = x(0) + v(0) * t + (1 / 2) * a * t [sup]2[/sup]

If you want non-constant acceleration, you have to use an integrator, like Verlet integration or semi-implicit Euler integration.


Hmm. Are you sure? The ball going up has it's own initial acceleration (say 10 m/s squared) but gravity slows this acceleration by 9.81 m/s squared. So after a second the acceleration is less than 1 m/s squared. No?
jefferytitan
jefferytitan
Exactly, the ball has an initial velocity, the only acceleration is due to gravity. I assume that in your code the acceleration reaches 0 for a time, and this is why it stops moving. To be technically correct, at the moment you throw it, you are applying a force to the ball, which causes acceleration. But the acceleration due to your hand only occurs while your hand is in contact with the ball, e.g. for a fraction of a second. After that the only force on it is due to gravity (excluding air resistance etc).
Cornstalks
Cornstalks

Hmm. Are you sure? The ball going up has it's own initial acceleration (say 10 m/s squared) but gravity slows this acceleration by 9.81 m/s squared. So after a second the acceleration is less than 1 m/s squared. No?

I'm positive. Using classical physics and Newton's equations, F = ma (force = mass * acceleration).

(Here F[sub]ball[/sub] is the force acting all the ball, which has mass m[sub]ball[/sub] and acceleration a[sub]ball[/sub])
F[sub]ball[/sub] = m[sub]ball[/sub] * a[sub]ball[/sub]
a[sub]ball[/sub] = (F[sub]ball[/sub] / m[sub]ball[/sub])

So what is F[sub]ball[/sub]? According to Newton's law of universal gravitation, the force of gravity between two objects is:

F[sub]gravity[/sub] = G * (m[sub]1[/sub] * m[sub]2[/sub]) / (r[sup]2[/sup])

Where F[sub]gravity[/sub] is the force of gravity on two objects, one with mass m[sub]1[/sub] and the other with mass m[sub]2[/sub], separated by a distance of r (G is the gravitational constant). This force is applied to both objects, so technically the ball falls to the earth, and the earth "falls" to the ball (but since the earth is sooooooo massive, it barely (if at all) moves towards the ball, because it accelerates sooo slowly because of it's large mass).

Since gravity is the only force acting on the ball, F[sub]ball[/sub] = F[sub]gravity[/sub], which means (from the second equation from above):
a[sub]ball[/sub] = G * (m[sub]ball[/sub] * m[sub]earth[/sub]) / (r[sup]2[/sup]) / m[sub]ball[/sub]

Simplifying yields:
a[sub]ball[/sub] = G * m[sub]earth[/sub] / r[sup]2[/sup]

Since G doesn't change, m[sub]earth[/sub] doesn't change, and r virtually doesn't change (yeah, the ball moves a few meters, but still, that's doesn't make a difference because it's still thousands of kilometers from the earth's center), then a[sub]ball[/sub] is constant. If you plug in values, you'll find a[sub]ball[/sub] ~= -9.8m/s[sup]2[/sup].

Acceleration is caused by a force. Since a constant force of gravity is being applied, and no other force, the acceleration of the ball is constant.
stannisbaratheon
stannisbaratheon

[quote name='stannisbaratheon' timestamp='1343692131' post='4964651']
Hmm. Are you sure? The ball going up has it's own initial acceleration (say 10 m/s squared) but gravity slows this acceleration by 9.81 m/s squared. So after a second the acceleration is less than 1 m/s squared. No?

I'm positive. Using classical physics and Newton's equations, F = ma (force = mass * acceleration).

(Here F[sub]ball[/sub] is the force acting all the ball, which has mass m[sub]ball[/sub] and acceleration a[sub]ball[/sub])
F[sub]ball[/sub] = m[sub]ball[/sub] * a[sub]ball[/sub]
a[sub]ball[/sub] = (F[sub]ball[/sub] / m[sub]ball[/sub])

So what is F[sub]ball[/sub]? According to Newton's law of universal gravitation, the force of gravity between two objects is:

F[sub]gravity[/sub] = G * (m[sub]1[/sub] * m[sub]2[/sub]) / (r[sup]2[/sup])

Where F[sub]gravity[/sub] is the force of gravity on two objects, one with mass m[sub]1[/sub] and the other with mass m[sub]2[/sub], separated by a distance of r (G is the gravitational constant). This force is applied to both objects, so technically the ball falls to the earth, and the earth "falls" to the ball (but since the earth is sooooooo massive, it barely (if at all) moves towards the ball, because it accelerates sooo slowly because of it's large mass).

Since gravity is the only force acting on the ball, F[sub]ball[/sub] = F[sub]gravity[/sub], which means (from the second equation from above):
a[sub]ball[/sub] = G * (m[sub]ball[/sub] * m[sub]earth[/sub]) / (r[sup]2[/sup]) / m[sub]ball[/sub]

Simplifying yields:
a[sub]ball[/sub] = G * m[sub]earth[/sub] / r[sup]2[/sup]

Since G doesn't change, m[sub]earth[/sub] doesn't change, and r virtually doesn't change (yeah, the ball moves a few meters, but still, that's doesn't make a difference because it's still thousands of kilometers from the earth's center), then a[sub]ball[/sub] is constant. If you plug in values, you'll find a[sub]ball[/sub] ~= -9.8m/s[sup]2[/sup].

Acceleration is caused by a force. Since a constant force of gravity is being applied, and no other force, the acceleration of the ball is constant.
[/quote]

Ah ok, I think I understand now. How would you go about representing tiny changes (<1pixel) in distances in SDL? i.e. when the ball starts to drop it's velocity is tiny but constantly adding these distances to the ball's position doesn't work (because SDL_rect only stores integers, not floats).
BitMaster
BitMaster
In general the object's internal state would be stored as floats and the renderer would then map these floats to screen coordinates. In the most trivial case it could as simple as int screenPosX = static_cast<int>(posX);or it could be elaborate with a camera that can move around and zoom (even in a purely 2D game) with just a little bit of extra math.
Cornstalks
Cornstalks

Ah ok, I think I understand now. How would you go about representing tiny changes (<1pixel) in distances in SDL? i.e. when the ball starts to drop it's velocity is tiny but constantly adding these distances to the ball's position doesn't work (because SDL_rect only stores integers, not floats).

No clue, as I've never worked with SDL. But you'd probably want to do what BitMaster said and just use separate (float) variables for tracking the position and stuff, and then copy these over to the SDL_rect when it's time to draw. This is also nice because it allows you to separate your updating from your drawing, and makes some things like interpolation when rendering a bit easier.

As a useless tangential factoid, if you're changing acceleration, it's called "jerk" (like when you "jerk" on something, you change it's acceleration). Changing position is velocity, changing velocity is acceleration, and changing acceleration is jerk (and it's the joke behind shirts like these).

Topic Locked

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

Sign in to reply to this topic.