我一直在研究如何施加摩擦力,并且有一部分我被困住,这就是如何将摩擦力应用于速度(如果实际上我正在计算正确的摩擦力)。
当我在表面上有一个球,法线为(0,1,0),当前速度为(2,0,0)时,我会将我的摩擦力计算为(0,-0.3, 0)。但是,我不明白的是如何正确地将其应用于我的速度。如果我简单地减去它,那么我的速度将是(2,-0.3,0),但是,摩擦是否应该导致x分量更小?
这是我目前的代码,如果有人可以请一看,我会非常感激。有一些优化要做,我知道这一点。
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;
}
}
我在此摩擦函数开始时使总力为零,因为如果存在摩擦,则之前的力(重力)不应该影响以后的速度。 (...对吧?)
答案 0 :(得分:4)
您的代码存在许多问题。所以,除了回答你的实际问题之外,我还要介绍它们。首先,
D3DXVECTOR3 forceAndVelocity = mTotalForces + m_vVelocity;
是不正确的,因为力和速度在概念上非常不同。这体现在他们的不同单位,因此无法添加。从下一行开始,
float fVelocityMagnitude = sqrt((forceAndVelocity.x * forceAndVelocity.x) + ...
我相信你希望forceAndVelocity
严格要求速度。
我将重做第一个if
语句,如下所示,
float fFrictionCoefficient = 0.0f;
if(fVelocityMagnitude == 0.0f)
{
float fFrictionCoefficient = m_fStaticFrictionCoefficient;
}
else if(fVelocityMagnitude > 0.0f)
{
float fFrictionCoefficient = m_fKineticFrictionCoefficient;
}
我放弃了矢量计算,因为它们与法线不垂直平行。
摩擦力的大小是摩擦系数乘以法向力的大小,所以
float fFrictionForceMagnitude = fFrictionCoefficient
* sqrt(D3DXVec3Dot(&vSurfaceNormal, &vSurfaceNormal));
在第二个if
声明中,您再次比较力和速度,您要做的是确定何时可以克服静摩擦力。基本上,您需要确定所有其他力是否超过摩擦力,因此您需要将无摩擦力的总力量与摩擦力的大小进行比较。所以,我会将if
块重做为
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;
}
最后一行是您问题的答案。摩擦力与速度相反,因此它与速度方向相反,其中m_vVelocity / fVelocityMagnitude
是标准化速度。注意,这不会直接影响速度,而是你的速度
D3DXVECTOR3 m_vVelocity = mTotalForces * time / mass;
其中mass
是对象的质量;
答案 1 :(得分:1)
首先,您的摩擦力应与表面相切,并与速度矢量方向一致。所以在你的情况下,你的力矢量将是(-0.3,0,0)。然后你的摩擦是一种力量,所以你不能将它添加到这样的速度。你的力量会影响速度。这项工作随着时间而变化,实际上可能与你的速度成正比。
答案 2 :(得分:0)
动态摩擦总是平行于接触表面施加,即垂直于法线,而不是垂直于正常。