2014-07-10 1 views
3

J'ai une forme de boîte sur une forme de bord. Maintenant, j'applique une impulsion sur la boîte, afin qu'elle puisse sauter. Mais quand il est atterri sur le sol, il ne devrait plus bouger. J'ai donc fixé la restitution 0 de la boîte. Et la friction de la forme du bord et de la forme de la boîte à 1. Mais il glisse facilement sur le sol. Comment éviter tout glissement?Box2d régler le frottement au sol au maximum - pas de glissement

+0

Box2D n'est pas faite pour la vitesse, pas pour la précision. Le frottement et la restitution ne fonctionnent pas à 100% et vous ne devriez pas vous y attendre. Il y aura souvent un petit rebond lorsque les restitutions sont à la fois zéro, et un tout petit peu de glissement quand les frottements sont tous les deux. Cependant, il ne devrait pas glisser facilement, donc il manque peut-être quelque chose dans votre configuration. – iforce2d

+0

J'ai changé la friction à 100, et cela fonctionne au besoin. Mais je ne sais pas quel est le maximum, de sorte que je puisse régler le maximum et être sûr qu'il ne glisse jamais, même si la force est très grande. Devrais-je définir float max value à partir des limites numériques (C++)? – Narek

+1

Je pense que le max est destiné à être 1, mais comme je le dis, il n'est pas précis du tout. Si vous pouvez obtenir les résultats souhaités en modifiant les chiffres, changez-les en fonction de vos besoins. – iforce2d

Répondre

0

Comme vous l'avez découvert, vous pouvez empêcher le glissement en augmentant suffisamment la friction.

En ce qui concerne la valeur maximale que vous pouvez attribuer au frottement, il n'y a pas de maximum documenté pour la valeur de frottement. Cela dit, il y a certaines limites à ce que peut être la valeur de friction maximale.

L'essai std::numeric_limits<float>::infinity() en tant que première valeur de frottement dans le test VaryingFriction, aboutit à la première plate-forme que le cube de friction infini frappe, disparaissant. Oups! Pas le résultat que je voudrais.

Un examen des Box2D 2.3.2 C++ source code révèle les variables pertinentes de friction comme:

  • La variable membre m_friction de b2Fixture. La variable membre m_friction de b2Contact.
  • La variable membre friction de b2ContactVelocityConstraint.

Ceux-ci sont définis comme étant des cas de type float32 qui à son tour est de type float - a single precision floating-point type. Cela nous donne une limite supérieure maximale de ce qui suit peut nous donner (sans trop-plein) de:

std::numeric_limits<float>::max() 

Toutefois variable membre m_friction de b2Contact est essentiellement le résultat de la racine carrée du produit des appareils : frictions

std::sqrtf(m_fixtureA->m_friction * m_fixtureB->m_friction) 

donc une valeur de fixation donné m_friction doit être inférieure à la racine carrée du flotteur max afin d'éviter un débordement potentiel de ce produit. À savoir, nous obtenons un cadre supérieur plus réaliste lié à ce que le frottement de tout b2Fixture peut provenir:

std::sqrtf(std::numeric_limits<float>::max()) 

Cela pourrait être assez bien s'il n'y avait pas ce qui se passe alors avec la variable membre friction de b2ContactVelocityConstraint; il est multiplié (en b2ContactSolver::SolveVelocityConstraints()) par un autre flottant - le normalImpulse de chaque point de contrainte de vitesse. La racine carrée de float-max peut donc être trop élevée pour éviter tout risque de débordement.

Et le débordement peut signifier ce qui se passe en utilisant l'infini pour le frottement: oups! Alors qu'un corps qui disparaît en raison de l'utilisation d'une valeur de friction trop élevée peut être un bug, à moins de fixer le code source de la bibliothèque, je pense que nous sommes coincés avec la racine carrée de la valeur float max comme limite supérieure risqué. Incidemment, j'ai déposé un issue à ce sujet avec un moyen que j'ai trouvé pour le réparer.

En règle générale, j'augmenterais le frottement d'un appareil jusqu'à ce qu'il n'y ait plus de glissement, puis je le laisserais juste là.

OTOH, il existe d'autres moyens de prévention de glissement (en plus la friction) upping comme ceux-ci ...

  1. Changer le type du corps. Si vous réglez le corps sur statique après une collision avec le sol, il ne bougera pas physiquement du tout. Pas jusqu'à ce que vous le changiez en dynamique.
  2. Créer un joint lorsque la boîte entre en collision avec le sol pour lier la boîte au sol.
Questions connexes