Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying gravity to objects

Tags:

c++

opengl

glut

I'm having trouble with implementing gravity on objects.

I have a bunch of circle objects that I'm drawing using OpenGL. I'm using delta-x and delta-y to move the circles (balls). I'm trying to add a gravitational constant to the y coordinate each frame so it simulates being pulled downward, but I'm not sure exactly how to do that.

Here's the relevant code:

class Ball
{
    public:
        double x;
        double y;
        double radius;
        double deltaX;
        double deltaY;
};


std::vector<Ball> gAllBalls;  // a vector of balls with random positions and delta-values
double gGravity = ?;  // gravitational constant - I know it's 92 m/s^s, but I don't know how to apply that to deltaX and deltaY


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    for (auto &thisBall : gAllBalls)
    {
        // draw
        glColor3d(thisBall.red, thisBall.green, thisBall.blue);
        DrawCircle(thisBall.x, thisBall.y, thisBall.radius);

        // gravity - not working
        if (thisBall.y + thisBall.radius < gScreenHeight - gGravity)
        {
            thisBall.y += gGravity;
        }

        // wall bouncing
        if (thisBall.y + thisBall.radius + thisBall.deltaY >= gScreenHeight)  // up
        {
            thisBall.deltaY = -thisBall.deltaY;
        }

        if (thisBall.y + thisBall.deltaY - thisBall.radius < 0)  // down
        {
            thisBall.deltaY = -thisBall.deltaY;
        }

        if (thisBall.x + thisBall.deltaX - thisBall.radius < 0) // left
        {
            thisBall.deltaX = -thisBall.deltaX;
        }

        if (thisBall.x + thisBall.radius + thisBall.deltaX >= gScreenWidth)  // right
        {
            thisBall.deltaX = -thisBall.deltaX;
        }

        // move
        thisBall.x += thisBall.deltaX;
        thisBall.y += thisBall.deltaY;
    }
    glutSwapBuffers();
    glutPostRedisplay();
}

A big problem I'm having is that I don't know how to calculate the gravity, since I'm using deltaX and deltaY instead of having separate speed and distance variables to calculate 92 m/s^2. However, no matter what I set the gravity to, the balls don't behave like they should - regardless of gravity strength, so there has to be something else wrong, but I don't know what.

like image 710
Grav Avatar asked Jun 03 '26 21:06

Grav


1 Answers

I think the problem here is the physics, rather than the programming technique. In your case, I would change the 'delta' members of your Ball class to 'speed', since they are a unit of distance that change the position of your object per cycle (time), however this is just a suggestion to make it easier to visualize...

class Ball
{
    public:
        double x;
        double y;
        double radius;
        double speedX;
        double speedY;
};

In second place, I in your code, you are changing the 'y' member, rather than the speed, and since gravity changes speed, hence the problem. Try doing that, and for debugging purposes, I would try with punctual objects (no radius, just plain (x,y) coordinates).

So, to conclude, I would simply change your gravity code to the following:

  // gravity - 'fixed'
  if (thisBall.y + thisBall.radius < gScreenHeight - gGravity)
  {
      thisBall.speedY -= gGravity; //notice the '-'
  }

The value of gravity should be absolute and positive, so as to keep things as simple as posible. If you try this, you should have an ideal simple physics simulator, with a ball of constant speedX (only changing its direction, not magnitude). Please try this, and let me know how it went, good luck, keep it up =)

like image 101
J3STER Avatar answered Jun 06 '26 09:06

J3STER



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!