Calcul des tenseurs d'inertie

10

Un peu d'une question complexe et longue que, je l'admets, je ne comprends pas encore très bien, donc je vais essayer de l'expliquer du mieux que je peux.

Version courte: Existe - t-il une formule générale c ++ / physx pour calculer les tenseurs d'inertie en fonction de la forme d'un objet?

Version longue: Pour notre physique, nous devons spécifier les tenseurs d'inertie x, y et z. Actuellement, la façon dont nous le faisons est à peu près juste un rapport basé sur la masse. Donc, si un objet est long sur l'axe X et mince sur Y et Z, et que la masse est de 10000, nous allons régler Z et Y sur 7000 et X sur 3000. (Ce n'est pas exact, mais juste pour donner une idée)

Cela fonctionne relativement bien, mais notre plus gros problème est lorsqu'il y a une instabilité articulaire quelque part, nous devons continuer à deviner les tenseurs jusqu'à ce que nous trouvions ce qui fonctionne le mieux. Cela peut prendre beaucoup de temps si nous avons une très grande simulation physique et qu'une articulation sur 20+ entraîne une perte de stabilité pour toutes les autres.

Je travaille sur une fonction qui prendra la boîte englobante d'un objet et, espérons-le, calculera des tenseurs relativement précis. J'ai pris quelques calculs à partir de http://en.wikipedia.org/wiki/List_of_moment_of_inertia_tensors et créé une fonction qui fonctionne essentiellement comme la suivante pour des rotations similaires ci-dessous.

Cuboïde solide de largeur w, hauteur h, profondeur d et masse m entrez la description de l'image ici

Ou si la rotation est sur une extrémité, comme ceci:

entrez la description de l'image ici entrez la description de l'image ici

Donc, cela semble me donner des résultats similaires à la façon dont nous l'avons fait, mais je ne veux pas passer à cette méthode sans m'assurer qu'elle fonctionnera pour une utilisation générale. Voici le code de ma fonction basé sur la première image avec un cube et un pivot central.

NxVec3 CalculateInertiaTensor( VisBoundingBox_cl boundingBox, float m )
{
    float width = boundingBox.GetSizeX();
    float height = boundingBox.GetSizeZ();
    float depth = boundingBox.GetSizeY();

    float xTensor = 0.083f * m*(height*height + depth*depth);
    float yTensor = 0.083f * m*(width*width + depth*depth);
    float zTensor = 0.083f * m*(width*width + height*height);

    return NxVec3(xTensor, yTensor, zTensor);
}

Je ne peux pas garantir que c'est la bonne façon de le faire (car la façon la plus précise est d'utiliser la forme réelle au lieu d'une boîte englobante) et je ne suis pas très familier avec les tenseurs d'inertie et les mathématiques, mais il semble renvoyer des nombres assez similaire à ce que nous utilisions. Est-ce que quelqu'un ici sait s'il existe une meilleure façon de procéder?

Mungoid
la source
3
Si vous pouvez décomposer votre objet en tétraèdres, vous devriez pouvoir utiliser la linéarité du tenseur ainsi que la formule de base pour le moment d'inertie d'un tétraèdre (vous pouvez le trouver avec Wolfram Alpha, par exemple) pour calculer une valeur exacte tenseur. Ma préoccupation avec la méthode de la boîte englobante serait qu'elle dépend vraiment de la quantité de BB que l'objet remplit; imaginez la différence entre un gros ellipsoïde et un mince ressort hélicoïdal, par exemple.
Steven Stadnicki
Merci pour la contribution. Et vous avez raison, mon principal problème survient quand il y a, disons, un objet en forme de «A», le BB fera revenir les tenseurs de manière incorrecte. Je vérifierai vos informations, merci!
Mungoid
Je vous en prie - si vous souhaitez que j'explique cela plus en détail, je devrais être en mesure de construire une réponse appropriée, mais cela devrait être suffisant pour vous aider à démarrer.
Steven Stadnicki
Si vous le vouliez, ce serait génial! J'essaie de comprendre cela depuis un certain temps, mais je suis encore un peu novice dans ce domaine, donc je
finis

Réponses:

7

J'allais suggérer que c'est un problème difficile parce que les formulations habituelles basées sur l'utilisation du théorème de Green pour convertir les intégrales de volume en intégrales de surface ne s'appliquent pas, et donc vous devez réellement fournir une décomposition tétraédrique de votre figure - mais cela tourne que ce n'est pas correct. Tant que votre forme est de densité uniforme (qui est une approximation que vous faites déjà de toute façon, probablement et parfaitement raisonnable pour la plupart des circonstances), les intégrales de volume peuvent être simplifiées en intégrales de surface, et ces dernières sont encore plus simplifiées. Mieux encore, il semble y avoir un algorithme et un code assez beaux sur le net pour ce faire; jetez un œil à http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html, La page de Brian Mirtich décrivant ses algorithmes de calcul des moments et du centre de masse. Il devrait couvrir à peu près tous vos besoins sur ce front. Notez que c'est quelque chose que vous voudrez faire une fois, soit comme outil lors de l'exportation de la forme ou au moment de l'importation, mais pas quelque chose dont vous aurez besoin pour faire chaque image; il suffit de stocker le tenseur d'inertie autour du centre de masse avec le reste des informations de forme, et si jamais vous avez besoin de trouver le tenseur pour des moments d'inertie autour d'un autre axe, vous pouvez utiliser les théorèmes standard pour le dériver.

J'espère que cela devrait couvrir ce dont vous avez besoin - s'il y a plus que je peux essayer d'aider, faites le moi savoir!

Steven Stadnicki
la source
4

Je ne l'ai jamais fait moi-même, mais si je devais écrire une solution rapide pour les maillages arbitraires, je générerais probablement suffisamment de points de masse à l'intérieur de l'objet pour l'approcher et calculer les tenseurs d'inertie à partir de ceux-ci.

Les points peuvent être générés uniformément à l'intérieur du cadre de délimitation de la forme, puis éliminer ceux qui se trouvent en dehors de la forme réelle. Cela réduirait le problème à simplement vérifier si un point se trouve à l'intérieur d'une forme.

msell
la source
0

Pour la plupart des applications de jeu (c'est-à-dire "faire exploser des trucs"), l'utilisation de l'équation pour un solide rectangulaire donnée ci-dessus est probablement assez bonne. À condition que l'objet soit aligné sur l'axe, pas une diagonale à travers le cadre de sélection, cela devrait fonctionner. Certains moteurs de physique des jeux, comme ODE, n'utilisent que les termes sur la diagonale principale du tenseur d'inertie. Pour eux, vos objets doivent être au moins à peu près alignés sur l'axe pour fonctionner correctement.

J'ai utilisé l'algorithme de Mirtich dans Falling Bodies en 1997. Cela fonctionne bien, mais vous devez avoir une géométrie propre - un maillage fermé non auto-intersecté fermé topologiquement correct. S'il y a des trous, le calcul de l'inertie produira des résultats totalement faux. J'ai utilisé uniquement la géométrie convexe, j'ai donc exécuté QHull pour obtenir une coque convexe à des fins de collision, puis calculé l'inertie à partir de cela.

John Nagle
la source