Расчет и применение трения - PullRequest
3 голосов
/ 09 декабря 2011

Я изучал, как применить трение, и есть часть, на которой я застрял, - как применить это трение к скорости (если на самом деле я правильно рассчитываю силу трения).

Когда у меня есть шар на поверхности, с нормалью (0, 1, 0), с текущей скоростью (2, 0, 0), тогда я вычислю свою силу трения как (0, -0.3, 0).Однако я не понимаю, как правильно применить это к моей скорости.Если я просто вычту его, то моя скорость будет (2, -0,3, 0), однако, разве не должно быть трение, чтобы компонент х был больше меньше?

Вот мой текущий код, еслиКто угодно может взглянуть на меня, я был бы очень признателен.Есть некоторые оптимизации, которые мне известны.

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;
    }
}

Я делаю полную силу равной нулю в начале этой функции трения, потому что если есть трение, то предыдущая сила (сила тяжести) должнане влияет на скорость позже.(... верно?)

Ответы [ 3 ]

4 голосов
/ 09 декабря 2011

Ваш код имеет ряд проблем.Итак, я собираюсь пройтись по ним, в дополнение к ответу на ваш настоящий вопрос.Во-первых,

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 голос
/ 09 декабря 2011

Прежде всего, ваше трение должно быть касательным к вашей поверхности, наряду с направлением вектора скорости. Так что в вашем случае ваш вектор силы будет (-0,3,0,0). Тогда ваше трение - это сила, поэтому вы не можете прибавить ее к такой скорости. Ваша сила выполняет работу, которая влияет на скорость. Эта работа со временем меняется и может быть пропорциональна вашей скорости.

0 голосов
/ 09 декабря 2011

Динамическое трение всегда применяется параллельно поверхности контакта, то есть перпендикулярно нормали, а не вдоль нормали.

...