Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411505 Posts in 69374 Topics- by 58429 Members - Latest Member: Alternalo

April 25, 2024, 07:20:42 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)How to calculate the next position of a ball rolling against a slope?
Pages: [1]
Print
Author Topic: How to calculate the next position of a ball rolling against a slope?  (Read 897 times)
jeanmilost
Level 0
*


View Profile
« on: July 31, 2018, 06:37:06 AM »

For a small game project, I need a simple solution to calculate the next position of a ball rolling against a slope. The result doesn't need to be the exact replication of the reality, a rough system may be sufficient, as long as the ball reacts roughly as a real rolling ball. I tried to resolve that by myself, however my skills in physics are very limited. Even after searching on the web, I could not figure out the complete process to achieve a such calculation.

Here are the information I know for the calculation:
  • I know the elapsed time since the last drawn frame
  • I know the polygon below the ball, from which I can deduce the slope
  • I know the gravitation and friction forces, which are constants

What I need is the next ball position based on the physics forces applied on it. I would be thankful if somebody can explain to me:
  • Which physics formulas should be used to achieve a such calculation
  • A simple example, if possible in C++, but may be in pseudo-code or in another language, showing how to calculate this position from the above values
  • At least a direction about which physical laws should be used to resolve the system, which I can then search on the web

NOTE I know that several physical engine exist, like Bullet or Box2d. I don't want to use them for now, I want to understand first how physics may work in a scene. So, please, don't provide a such solution.

Regards
Logged
verdog
Level 0
**



View Profile WWW
« Reply #1 on: July 31, 2018, 07:32:06 AM »

This isn't quite the same, but it might help:

https://stackoverflow.com/a/573206

This post is about a ball bouncing off of an arbitrarily angled wall. It takes into account the friction and elasticity of the bounce. Maybe you could try thinking of thinking of a rolling ball as something that's constantly bouncing against a wall. I feel like you might be able to get away with starting with this idea, and then adding a constant gravitational force.
Logged

d.c.elington
Level 0
*


View Profile
« Reply #2 on: July 31, 2018, 08:14:48 AM »

Hi,

You need to integrate Newton's second law of motion https://en.wikipedia.org/wiki/Newton%27s_laws_of_motion

At each frame, given the forces on the ball, using Vectors you get:
Acceleration = (Sum of Forces) / (ball mass)

Then using the simplest integration methods (Euler), with dt the elapsed time,
Velocity = Velocity + (Acceleration * dt)

and finally:
Position = Position + (Velocity * dt)

Please note that above is a very crude approach that can lead to rapidly accumulating errors especially if dt is not small enough. For more accurate methods you can have a look at https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods

Also in your particular case IMHO it would be easier to work in 2D in the plane where the ball is rolling (are you familiar with transforms?) and so you would have to project Gravity into this plane, which depends on the slope you mention (if alpha is the angle from the horizontal then in-plane gravity magnitude = gravity magnitude * sine(alpha)). Drag is opposed to Velocity so can be modeled as -(drag magnitude) * Velocity.  

Hope it helps! Wink
« Last Edit: July 31, 2018, 09:25:24 AM by d.c.elington » Logged
jeanmilost
Level 0
*


View Profile
« Reply #3 on: July 31, 2018, 06:16:38 PM »

Finally I found an acceptable solution, based on the following article: http://www.golf-simulators.com/physics.htm (search the "Rolling on inclined planes " part)

I'm aware that it is anything but perfect, but it works sufficiently well in my small simulation. Thanks to all which taken a time to post an answer, this really helped me. Smiley

Here is my solution:
Code:
//---------------------------------------------------------------------------
void csrPhysicsGravity(float mass, float* pF)
{
    // the formula for the gravitation is F = m * g
    *pF = mass * M_CSR_Gravitation;
}
//---------------------------------------------------------------------------
void csrPhysicsRoll(const CSR_Vector3* pSlopeDir,
                          float        mass,
                          float        friction,
                          float        elapsedTime,
                          CSR_Vector3* pVelocity)
{
    float       gravity;
    float       thetaX;
    float       thetaZ;
    float       ffx;
    float       ffz;
    CSR_Vector3 xDir;
    CSR_Vector3 zDir;
    CSR_Vector3 acceleration;

    // calculate the gravity force to apply to the body
    csrPhysicsGravity(mass, &gravity);

    xDir.m_X = 1.0f;
    xDir.m_Y = 0.0f;
    xDir.m_Z = 0.0f;

    // calculate the slope angle on the x axis
    csrVec3Dot(&xDir, pSlopeDir, &thetaX);

    zDir.m_X = 0.0f;
    zDir.m_Y = 0.0f;
    zDir.m_Z = 1.0f;

    // calculate the slope angle on the z axis
    csrVec3Dot(&zDir, pSlopeDir, &thetaZ);

    // the angles should always be positive
    thetaX = fabs(thetaX);
    thetaZ = fabs(thetaZ);

    // calculate the friction force to apply to the body (using the formula a = dv / dt)
    if (elapsedTime)
    {
        ffx = (pVelocity->m_X / (elapsedTime * 1.0f)) * friction;
        ffz = (pVelocity->m_Z / (elapsedTime * 1.0f)) * friction;
    }
    else
    {
        ffx = 0.0f;
        ffz = 0.0f;
    }

    // calculate the body acceleration (using the formula a = ((m * g * sin(theta)) - Ff) / m)
    acceleration.m_X = ((gravity * thetaX) - ffx) / mass;
    acceleration.m_Z = ((gravity * thetaZ) - ffz) / mass;

    // calculate the final body velocity (using the formula v = v + (a * dt))
    pVelocity->m_X += (acceleration.m_X * elapsedTime);
    pVelocity->m_Z += (acceleration.m_Z * elapsedTime);
}
//---------------------------------------------------------------------------
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic