Berechnung von Trägheitstensoren

10

Eine komplexe und langwierige Frage, die ich, wie ich zugeben muss, noch nicht ganz gut verstehe, also werde ich versuchen, sie so gut wie möglich zu erklären.

Kurzversion : Gibt es eine allgemeine c ++ / physx-Formel zur Berechnung von Trägheitstensoren basierend auf einer Objektform?

Lange Version: Für unsere Physik müssen wir x-, y- und z-Trägheitstensoren angeben. Derzeit ist die Art und Weise, wie wir es tun, so ziemlich nur ein Verhältnis, das auf der Masse basiert. Wenn also ein Objekt auf der X-Achse lang und auf Y und Z dünn ist und die Masse 10000 beträgt, setzen wir Z und Y auf 7000 und X auf 3000. (Dies ist nicht genau, sondern nur, um eine Idee zu geben.)

Dies funktioniert relativ gut, aber unser größtes Problem ist, dass wir bei einer Gelenkinstabilität irgendwo Tensoren erraten müssen, bis wir herausgefunden haben, was am besten funktioniert. Dies kann sehr zeitaufwändig werden, wenn wir eine sehr große Physiksimulation haben und eines von mehr als 20 Gelenken dazu führt, dass alle anderen an Stabilität verlieren.

Ich arbeite an einer Funktion, die den Begrenzungsrahmen eines Objekts nimmt und hoffentlich relativ genaue Tensoren berechnet. Ich habe einige der Berechnungen von http://en.wikipedia.org/wiki/List_of_moment_of_inertia_tensors übernommen und eine Funktion erstellt, die im Wesentlichen wie folgt für ähnliche Rotationen unten funktioniert.

Fester Quader mit Breite w, Höhe h, Tiefe d und Masse m Geben Sie hier die Bildbeschreibung ein

Oder wenn die Rotation zu Ende ist, wie folgt:

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Dies scheint mir Ergebnisse zu liefern, die denen ähneln, die wir bisher durchgeführt haben, aber ich möchte nicht auf diese Weise wechseln, ohne sicherzustellen, dass sie für den allgemeinen Gebrauch funktionieren. Unten ist der Code für meine Funktion basierend auf dem ersten Bild mit einem Würfel und einem mittleren Drehpunkt.

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

Ich kann nicht garantieren, dass dies der richtige Weg ist (da der genaueste Weg darin besteht, die tatsächliche Form anstelle eines Begrenzungsrahmens zu verwenden), und ich bin mit Trägheitstensoren und der Mathematik nicht sehr vertraut, aber es scheint Zahlen zurückzugeben ziemlich ähnlich zu dem, was wir benutzt haben. Weiß hier jemand zufällig, ob es einen besseren Weg gibt, dies zu tun?

Mungoid
quelle
3
Wenn Sie Ihr Objekt in Tetraeder zerlegen können, sollten Sie in der Lage sein, die Linearität des Tensors zusammen mit der Grundformel für das Trägheitsmoment eines Tetraeders (dies können Sie beispielsweise bei Wolfram Alpha finden) zu verwenden, um eine genaue Zahl zu berechnen Tensor. Mein Anliegen bei der Bounding-Box-Methode wäre, dass es wirklich davon abhängt, wie viel von Ihrem BB das Objekt füllt. Stellen Sie sich zum Beispiel den Unterschied zwischen einem fetten Ellipsoid und einer schlanken Schraubenfeder vor.
Steven Stadnicki
Danke für die Eingabe. Und Sie haben Recht, mein Hauptproblem tritt auf, wenn es beispielsweise ein Objekt in A-Form gibt. Der BB lässt die Tensoren falsch zurückkommen. Ich werde Ihre Informationen überprüfen, danke!
Mungoid
Gern geschehen - wenn Sie möchten, dass ich dies genauer erläutere, sollte ich in der Lage sein, daraus eine richtige Antwort zu erstellen, aber das sollte ausreichen, um Ihnen den Einstieg zu erleichtern.
Steven Stadnicki
Wenn Sie dazu bereit wären, wäre das großartig! Ich habe versucht, dies für eine Weile herauszufinden, aber ich bin noch ein bisschen jung in diesem Bereich, so dass ich mich immer mehr verwirrt = =)
Mungoid

Antworten:

7

Ich wollte vorschlagen, dass dies ein schwieriges Problem ist, da die üblichen Formulierungen, die auf der Verwendung des Greenschen Theorems zur Umwandlung von Volumenintegralen in Oberflächenintegrale basieren, nicht zutreffen und Sie tatsächlich eine tetraedrische Zerlegung Ihrer Figur bereitstellen müssen - aber es dreht sich heraus, dass das nicht richtig ist. Solange Ihre Form eine gleichmäßige Dichte aufweist (was vermutlich ohnehin schon eine Annäherung ist und für die meisten Umstände durchaus vernünftig ist), können die Volumenintegrale zu Oberflächenintegralen vereinfacht und letztere noch weiter vereinfacht werden. Besser noch, es scheint einen ziemlich gut aussehenden Algorithmus und Code im Internet zu geben, um dies zu tun. Schauen Sie sich http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html an, Brian Mirtichs Seite, die seine Algorithmen zur Berechnung von Momenten und Schwerpunkt beschreibt. Es sollte so ziemlich alle Ihre Bedürfnisse an dieser Front abdecken. Beachten Sie, dass Sie dies einmal tun möchten, entweder als Werkzeug beim Exportieren der Form oder beim Importieren, aber nicht bei jedem Frame. Speichern Sie einfach den Trägheitstensor um den Schwerpunkt zusammen mit den restlichen Forminformationen. Wenn Sie den Tensor jemals für Trägheitsmomente um eine andere Achse finden müssen, können Sie ihn anhand der Standardsätze ableiten.

Hoffentlich sollte dies das abdecken, was Sie brauchen - wenn es mehr gibt, bei dem ich helfen kann, lassen Sie es mich einfach wissen!

Steven Stadnicki
quelle
4

Ich habe das noch nie selbst gemacht, aber wenn ich eine schnelle Lösung für beliebige Netze schreiben müsste, würde ich wahrscheinlich genug Massepunkte innerhalb des Objekts erzeugen, um es zu approximieren und die Trägheitstensoren daraus zu berechnen.

Die Punkte könnten gleichmäßig innerhalb des Begrenzungsrahmens der Form erzeugt und dann diejenigen verworfen werden, die außerhalb der tatsächlichen Form liegen. Dies würde das Problem darauf reduzieren, nur zu überprüfen, ob sich ein Punkt innerhalb einer Form befindet.

msell
quelle
0

Für die meisten Spieleanwendungen (dh "Sprengstoff") ist es wahrscheinlich gut genug, nur die oben angegebene Gleichung für einen rechteckigen Körper zu verwenden. Vorausgesetzt, das Objekt ist achsenausgerichtet und keine Diagonale über dem Begrenzungsrahmen, sollte dies funktionieren. Einige Spielphysik-Engines wie ODE verwenden nur die Begriffe auf der Hauptdiagonale des Trägheitstensors. Für sie müssen Ihre Objekte mindestens grob achsenausgerichtet sein, damit sie richtig funktionieren.

Ich habe Mirtichs Algorithmus 1997 in Falling Bodies verwendet. Er funktioniert gut, aber Sie müssen eine saubere Geometrie haben - ein topologisch korrektes geschlossenes, sich nicht selbst schneidendes Netz. Wenn es Löcher gibt, führt die Trägheitsberechnung zu völlig falschen Ergebnissen. Ich habe nur konvexe Geometrie verwendet, also habe ich zuerst QHull ausgeführt, um eine konvexe Hülle für Kollisionszwecke zu erhalten, und dann die Trägheit daraus berechnet.

John Nagle
quelle