3
votes

I have been researching how to apply friction and there is a part I am stuck on, which is how to apply that friction to the velocityy (if in fact I am calculating the friction force correctly that is).

When I have a ball on a surface, with a normal of (0, 1, 0), with a present velocity of (2, 0, 0) then I will calculate my friction force as (0, -0.3, 0). However, what I don't understand is how to properly apply that to my velocity. If I simply, subtract it then my velocity will be (2, -0.3, 0), however, shouldn't the friction be cause the x component to be more less?

Here is my current code, if anyone could please take a look at I would greatly appreciate it. There are some optimizations to be made, I am aware of that.

mTotalForces = D3DXVECTOR3(0.0f, 0.0f, 0.0f);

D3DXVECTOR3 vSurfaceNormalized;
D3DXVec3Normalize(&vSurfaceNormalized, &vSurfaceNormal);
D3DXVECTOR3 vFrictionForce(0.0f, 0.0f, 0.0f);

D3DXVECTOR3 forceAndVelocity = mTotalForces + m_vVelocity;
float fVelocityMagnitude = sqrt((forceAndVelocity.x * forceAndVelocity.x) + (forceAndVelocity.y * forceAndVelocity.y) + forceAndVelocity.z * (forceAndVelocity.z));
float fFrictionForceMagnitude = 0.0f;
float fFrictionForce = 0.0f;

if(fVelocityMagnitude == 0.0f)
{
    fFrictionForce = m_fStaticFrictionCoefficient;

    D3DXVECTOR3 vStaticFriction = -m_fStaticFrictionCoefficient * vSurfaceNormalized;
    vFrictionForce = vStaticFriction;
}
else if(fVelocityMagnitude > 0.0f)
{
    fFrictionForce = m_fKineticFrictionCoefficient;

    D3DXVECTOR3 vKineticFriction = -m_fKineticFrictionCoefficient * vSurfaceNormalized;
    vFrictionForce = vKineticFriction;
}


{
    float fFrictionForceMagnitude = abs(fFrictionForce * D3DXVec3Dot(&vSurfaceNormalized, &forceAndVelocity));

    if(fFrictionForceMagnitude > fVelocityMagnitude)
    {
        fFrictionForceMagnitude = 0.0f;
        m_vVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    }
    else
    {
        m_vVelocity -= vFrictionForce;
    }
}

I make the total force zero at the start of this friction function because if there is friction, then the previous force (gravity) should not influence the velocity later. (... right?)

3
Why would your friction force be in the y direction if your ball is moving in the x direction along a surface in the x-z plane? - Oliver Charlesworth
Your physics is a little off. give this a read: hyperphysics.phy-astr.gsu.edu/hbase/frict2.html - Nope
@ Oli Charlesworth, that is what I am trying to figure out ... I agree, it should be in the x direction - mmurphy

3 Answers

4
votes

Your code has a number of problems. So, I'm going to step through them, in addition to answering your actual question. First,

D3DXVECTOR3 forceAndVelocity = mTotalForces + m_vVelocity;

is incorrect as force and velocity are conceptually very different. This is embodied in their different units, so they can not be added. From the next line,

float fVelocityMagnitude = sqrt((forceAndVelocity.x * forceAndVelocity.x) + ...

I believe you want forceAndVelocity to be strictly velocity.

I'd redo the first if statement as follows,

float fFrictionCoefficient = 0.0f;
if(fVelocityMagnitude == 0.0f)
{
    float fFrictionCoefficient = m_fStaticFrictionCoefficient;
}
else if(fVelocityMagnitude > 0.0f)
{
    float fFrictionCoefficient = m_fKineticFrictionCoefficient;
}

I dropped the vector calculations as they were parallel to the normal not perpendicular.

The magnitude of the friction is the coefficient of friction times the magnitude of the normal force, so

float fFrictionForceMagnitude = fFrictionCoefficient 
                        * sqrt(D3DXVec3Dot(&vSurfaceNormal, &vSurfaceNormal));

In the second if statement, you're again comparing force and velocity, and what you're trying to do is determine when static friction may be overcome. Essentially, you need to determine if all other forces exceed the friction, so you need to compare the magnitude of the total forces without friction to the magnitude of the friction force. So, I'd redo the if block as

float fForceMagnitude = sqrt(D3DXVec3Dot(&mTotalForces, &mTotalForces));

if(fFrictionForceMagnitude > fForceMagnitude)
{
    float m_vVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}
else
{
    float mTotalForces -= fFrictionForceMagnitude * m_vVelocity / fVelocityMagnitude;
}

where the last line is the answer to your question. The friction force opposes velocity, so it is opposite in direction to your velocity, where m_vVelocity / fVelocityMagnitude is the normalized velocity. Note, this doesn't directly affect the velocity, instead your velocity is

D3DXVECTOR3 m_vVelocity = mTotalForces * time / mass;

where mass is the mass of the object;

1
votes

First of all, your friction should be tangential to your surface, alongside the direction of the velocity vector. So in your case, your force vector would be (-0.3,0,0). Then your friction is a force so you can't add it to a velocity just like this. Your force performs a work that affects the velocity. That work changes over time and could be actually proportional to your velocity.

0
votes

Dynamic friction is always applied parallel to the surface of contact, that is, perpendicular to the normal, not along the normal.