Jump to content
  • Advertisement
Sign in to follow this  
mmurphy

Calculating and applying friction

This topic is 2554 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?)

Share this post


Link to post
Share on other sites
Advertisement
The problem here is that friction should be in the same direction as the velocity, so you want the change in velocity due to kinetic friction to be equal to the velocity vector multiplied by the kinetic friction coefficient, but in the opposite direction.

Share this post


Link to post
Share on other sites
Some general thoughts about the problem:

Friction is a force and you should apply it as a force. That means it directly affects the object's acceleration (mass enters here). And acceleration then modifies your velocity.

Friction force is a force that always acts against the actual movement - against the actual velocity. That's regarding the direction. You compute the magnitude of friction. Take the velocity vector, normalise it, reverse it (friction acts against velocity) and multiply by the friction magnitude => that's the friction force vector.

Friction is a passive force, it will never make your object move "more", it will just be slowing it. So, when your velocity is reaching zero, you must be careful with the above because you don't want the friction force to actually start moving your object the other direction.
Friction however can be a contributive force. Imagine a freely moving object which you suddenly want to stop by a force acting against the movement - friction will act in the same direction as your force and will help you.

Static friction shouldn't be applied only when velocity is exactly 0, you should give some small range there.
The direction of static friction is the same as with the dynamic friction, but you cannot get it from the actual velocity vector as the object is static (not moving). Static friction acts against the force that's trying to make the object moving. If the static friction is bigger, you'll get no movement at all. Otherwise it simply lowers the action force. And when the object starts to move, you must transition from static to dynamic.

Share this post


Link to post
Share on other sites

Take the velocity vector, normalise it, reverse it (friction acts against velocity) and multiply by the friction magnitude => that's the friction force vector.


So

mTotalForces = (-1.0f * vSurfaceNormalized) * fFrictionForceMagnitude; ?

Am I calculating my friction for magnitude correctly though? I am doing

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

but that will alsways be zero. my surface is (0, 1, 0) and my forceAndVelocity is equal to (2, 0, 0). Velocity is (2, 0, 0) and force (mTotalForces) was previously (0, -9.8, 0) but got zeroed out at the top of the function since gravity should not influence this i thought

Share this post


Link to post
Share on other sites
[color=#1C2837][size=2]Static friction shouldn't be applied only when velocity is exactly 0, you should give some small range there. <br style="color: rgb(28, 40, 55); font-size: 13px; line-height: 16px; text-align: left; background-color: rgb(250, 251, 252); ">[color=#1C2837][size=2]

The direction of static friction is the same as with the dynamic friction, but you cannot get it from the actual velocity vector as the object is static (not moving). Static friction acts against the force that's trying to make the object moving. If the static friction is bigger, you'll get no movement at all. Otherwise it simply lowers the action force. And when the object starts to move, you must transition from static to dynamic.

[/quote]

This is extremely helpful. You need to contemplate the situation in which you're trying to apply friction. For example, if a character is lifting a board with a box on it to move it, you're working with static friction (f[sub]s[/sub]= u[sub]s[/sub] F[sub]N[/sub] [u[size="1"]s : coefficient of static friction, F[sub]N[/sub]: Normal Force]). Until the static friction is trumped by the opposing force, the box would remain stationary. At the point that is DOES exceed the force of static friction, you have then transitioned into the brave new world of kinetic friction as it moves down the board, (f[sub]k[/sub]= u[sub]k[/sub] F[sub]N[/sub] [u[size="1"]s : coefficient of static friction, F[sub]N[/sub]: Normal Force]). Those are your two formulas for calculating the magnitudes. Your normal force is calculated (in relevance to friction, since it assumes an object is on a mass moving in a linear motion) by the mass of the object multiplied by gravity in the environment. Depending on your surfaces, you then set your coefficients. Although there are easier ways to do it in code, getting a basis on WHAT you're trying to accomplish would be extremely helpful.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!