Sign in to follow this  
limpacp

Gravity in 2d space

Recommended Posts

Hello. I'm stuck in gravity calculations, please help: I have 2D space with ball that moving across this space and one gravity point. When ball riches the edge, it jumps aside. So the ball will never moving away from this 2D space. I need to add gravity caculations to the ball movement. But i don't know how. Can you help me ? So info: i have the angle for ball movement (0-359 dgr). Ball moving by calculating delta x and y using next formula: dx = cos( -angle * pi/180 ) * speed; dy = sin( -angle * pi/180 ) * speed; ball.move(dx,dy) I know the angle to the gravity point for each ball position and gravity force value. I think that changing the angle to the gravity point and speed is the best solution, but how? Thanks!

Share this post


Link to post
Share on other sites
Using Vectors is the best way as mentioned above.

If you know the speed and direction of the ball, you can calculate the velocity of the ball in the same way as you did with dx and dy

Assuming pixels go down-positive and vectors go up-positive


INIT_GRAVITY:

VECTOR acc_g; //Acceleration due to gravity
acc_g.y = -ACC_DUE_TO_GRAVITY; //this should be some constant value

ENDINIT;


GAMELOOP:

vel.x = cosd( angle ) * speed; //cosine in degrees
vel.y = sind( angle ) * speed; //sine in degrees

if( ball.y <= floor.y ){ //Ball is not already on the floor
vel = vel + acc_g; //Increase velocity downwards (by adding negative acc)
}


ball.x += vel.x //Update position of the ball
ball.y -= vel.y //Negate because pixels and vectors are oppositely signed for Y axis

if( ball.y > floor.y ){ //The new position is below floor line
ball.y = floor.y; //Keep ball on the floor
}

ENDLOOP;



Of course, there are a lot of things that can and should be improved in this code but I tried to keep it as consistent as possible with your example. Things like calculating time elapsed in the given frame (dt) and calculating velocities and acceleration with respect to time is better than per unit frame, because frame rate may vary. But this pseudocode should give you a basic idea of what can be done with your simple code.

Share this post


Link to post
Share on other sites
Verminox: to me, limpacp sounds like he wants a center of gravity, not a uniform downward force. Of course, this doesn't really change the logic of the calculations, just keep the speed as a (dx,dy) pair that's easy to manipulate when there are forces that can change both the direction and speed of the velocity.

Something like this ...

... main loop ...
vel.x+=c*(x0-x)/sqrt((x-x0)^2+(y-y0)^2)^3; // Gravitational effect from (x0,y0)
vel.y+=c*(y0-y)/sqrt((x-x0)^2+(y-y0)^2)^3;
ball.x+=vel.x; // Adjust velocity vector
ball.y+=vel.y;
if ((ball.x < 0) && (ball.x > screenWidth)) vel.x=-vel.x; // Bounce off the sides
if ((ball.y < 0) && (ball.y > screenHeight)) vel.y=-vel.y;
... main loop continues ...




edit: professional hazard, omitted a couple of *'s

[Edited by - Darkstrike on October 7, 2006 1:12:36 PM]

Share this post


Link to post
Share on other sites
Ahh yes.. I did not read the post properly. My bad. And yes it is much better to use Vector(x,y) than Vector(r,theta).

When you start adding/subtracting/dot-multiplying/normalizing vectors you will realise how hard and performance costly it is to maintain* a polar system for vectors. If at any given time you only know the polar position of a vector and not its components, simply resolve it using:
x = r * cos(theta);
y = r * sin(theta);


* I found out the hard way =(

Share this post


Link to post
Share on other sites
Darkstrike: What's with the complex equation for gravity from a point?

Unless I am mis-understanding the concept (doesn't it mean a force of attraction to a given poin?)... it can be easily done by using the basic principle:

Acceleration towards point = Force of attraction / mass of body

Since this is simple simulation and the assumed constant of "Attraction" is just an acceleration... here is what we will do.


GIVEN:
POINT (x0,y0); // Point of Gravity
SCALAR pull; // In terms of Acceleration
POINT (x,y); // Position of ball
VECTOR vel; // Velocity of ball (Resolve if only polar known)

CALCULATION:

// Define function for normalization
FUNCTION VECTOR::Normalize(){
SCALAR magnitude = sqrt( this.x^2 + this.y^2 );
this.x = this.x / magnitude;
this.y = this.y / magnitude;
}

VECTOR g; // Find a vector from gravity to ball
g.x = (x-x0);
g.y = -(y-y0); // Change signs for pixels to vector

g.Normalize(); // Make it a unit vector

VECTOR acc = g * (-pull); // Acceleration is from ball to gravity with a magnitude of 'pull'

vel = vel + acc; // Add the two vectors (simply add x and y components of each)

x = x + vel.x; // Update position of ball
y = y - vel.y; // Subtract due to oppositely signed Y axis for pixels and vectors

if( x < 0 OR x > width ){
vel.x = -vel.x; // Bounce
}

if( y < 0 OR y > height ){
vel.y = -vel.y; // Bounce
}

END

Share this post


Link to post
Share on other sites
If a constant force is wanted, sure, it's just that for me "gravity" automatically means the classical F=G*m_1*m_2/r^2 force, so I'm just scaling your g accordingly.

edit: oh yes, and my snippet also assumes the same orientation of the y axis. As long as orientation is not important, it's the same, but if this is not the case, then Verminox's sign juggling is definitely needed.

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