Alex Rivera | Logout

How do I apply gravity to my bouncing ball application?

Asked 2008-12-04T21:42:31.933
11

I've written a fairly simple java application that allows you to drag your mouse and based on the length of the mouse drag you did, it will shoot a ball in that direction, bouncing off walls as it goes.

Here is a quick screenshot:
alt text http://img222.imageshack.us/img222/3179/ballbouncemf9.png

Each one of the circles on the screen is a Ball object. The balls movement is broken down into an x and y vector;

public class Ball {
    public int xPos;
    public int yPos;
    public int xVector;
    public int yVector;

    public Ball(int xPos, int yPos, int xVector, int yVector) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.xVector = xVector;
        this.yVector = yVector;
    }

    public void step()
    {
        posX += xVector;
        posY += yVector;

        checkCollisions();
    }

    public void checkCollisions()
    {
        // Check if we have collided with a wall
        // If we have, take the negative of the appropriate vector
        // Depending on which wall you hit
    }

    public void draw()
    {
        // draw our circle at it's position
    }
}

This works great. All the balls bounce around and around from wall to wall.

However, I have decided that I want to be able to include the effects of gravity. I know that objects accelerate toward the earth at 9.8m/s but I don't directly know how this should translate into code. I realize that the yVector will be affected but my experimentation with this didn't have the desired effect I wanted.

Ideally, I would like to be able to add some gravity effect to this program and also allow the balls to bounce a few times before settling to the "ground."

How can I create this bouncing-elastic, gravity effect? How must I manipulate the speed vectors of the ball on each step? What must be done when it

Edit
Report

2 Answers

13

When the balls are all rolling around on the ground, yes, check to see if the velocity is below a certain minimum value and, if so, set it to zero. If you look at the physics behind this type of idealized motion and compare with what happens in the real world, you'll see that a single equation cannot be used to account for the fact that a real ball stops moving.

BTW, what you're doing is called the Euler method for numerical integration. It goes like this:

  • Start with the kinematic equations of motion:
    x(t) = x0 + vx*t + 0.5*axt^2
    y(t) = y0 + vy
    t + 0.5*ayt^2
    vx(t) = vx0 + ax
    t
    vy(t) = vy0 + ay*t
    Where x and y are position, vx and vy are velocity, ax and ay are acceleration, and t is time. x0, y0, vx0, and vy0 are the initial values. This describes the motion of an object in the absence of any outside force.

  • Now apply gravity:
    ay = -9.8 m/s^2
    To this point, there's no need to do anything tricky. We can solve for the position of each ball using this equation for any time.

  • Now add air friction: Since it's a spherical ball, we can assume it has a coefficient of friction c. There are typically two choices for how to model the air friction. It can be proportional to the velocity or to the square of velocity. Let's use the square:
    ax = -cvx^2
    ay = -c
    vy^2 - 9.8
    Because the acceleration is now dependent on the velocity, which is not constant, we must integrate. This is bad, because there's no way to solve this by hand. We'll have to integrate numerically.

  • We take discrete time steps, dt. For Euler's method, we simply replace all occurances of t in the above equations with dt, and use the value from the previous timestep in place of the initial values, x0, y0, etc. So now our equations look like this (in pseudocode):

    // Save previous values
    xold = x;
    yold = y;
    vxold = vx;
    vyold = vy;

    // Update
answered 2008-12-05T17:45:54.220
0

I agree with what "Bill K" said, and would add that if you want them to "settle" you will need to reduce the x and y vectors over time (apply resistance). This will have to be a very small amount at a time, so you may have to change your vectors from int to a floating point type, or only reduce them by 1 every few seconds.

answered 2008-12-04T21:55:07.603

Your Answer