Ich versuche (für ein Lernspiel) den bekannten Effekt zu simulieren, dass rotierende Objekte mit drei ungleichen Trägheitsmomenten instabil werden, wenn sie um die Mittelachse gedreht werden.
Einige Erklärungen zu diesem Effekt finden Sie hier:
Das meiste dieser Mathematik geht leider über meinen Kopf (obwohl ich es versuche). Aber für meine Zwecke brauche ich mehr als nur „ist die Form eines harmonischen Oszillators“ oder „ist kein harmonischer Oszillator“; Ich muss den Effekt tatsächlich in der Simulation reproduzieren.
Ich habe dies mit der integrierten Physik-Engine von Unity hier versucht:
Sie können es selbst ausprobieren, wenn Sie das kostenlose Unity-Plugin haben (oder installieren); es zeigt einen 1x4x7-Block mit einheitlicher Dichte, der sich um seine Mittelachse dreht. Mit der "Poke"-Taste können Sie ein kleines zufälliges Drehmoment induzieren. Wiederholtes Stoßen des Blocks kann seine Achse schief schlagen – aber sobald Sie aufhören, ihn zu stoßen, bleibt die Achse an Ort und Stelle und dreht sich stetig um die jeweilige Richtung. Unter keinen Umständen konnte ich es zum Fallen bringen (wie in diesem Video eines Kartenspiels oder in diesem einer Simulation zu sehen).
Und sein Mangel an Taumeln macht für mich absolut Sinn. So wie ich es verstehe, wird der Zustand eines starren Körpers durch seine Position, Geschwindigkeit, Orientierung und Winkelgeschwindigkeit definiert. Ohne äußere Kräfte sollten Geschwindigkeit und Winkelgeschwindigkeit unverändert bleiben. Die Winkelgeschwindigkeit kann als Achse und Rotationsgeschwindigkeit beschrieben werden. Wie kann sich also die Rotationsachse ändern, ohne dass äußere Kräfte darauf einwirken?
Offensichtlich fehlt sowohl meinem intuitiven Verständnis als auch der Physik-Engine in Unity etwas. Konzentrieren Sie sich nicht zu sehr auf Letzteres; Ich kann meine eigene Physik-Engine programmieren, wenn ich verstehe, was sie tun soll. Was ist der Schlüssel, den ich vermisse, der erklärt, wie (und auf welche Weise) sich die Rotationsachse ohne äußere Kraft ändern kann? Wie würde man dies in Pseudocode simulieren, einfacher Vorwärts-Euler-Integrationsstil?
, Und ist ohne äußere Kräfte konstant. Das bisschen, was ich denke, dass Sie vermissen, ist das dreht sich mit dem starren Körper, ist also im Allgemeinen nicht konstant und ist es auch nicht .
Ich habe mit Ihrem Online-Beispiel gespielt, und die Winkelgeschwindigkeit scheint immer konstant zu bleiben, wenn ich nicht in den Block stoße, was mit einem Trägheitstensor übereinstimmt, der ein skalares Vielfaches der Identität ist. Ich habe Unity noch nie verwendet, aber es scheint beliebige Trägheitstensoren über Rigidbody.inertiaTensor und Rigidbody.inertiaTensorRotation zu unterstützen , also müssen Sie diese vielleicht nur richtig einstellen.
Wenn Sie am Ende Ihre eigene Physik würfeln müssen, hier ist ein naiver, ungetesteter und möglicherweise falscher Pseudocode:
const double time_step = ...;
const Quaternion L = {0, Lx, Ly, Lz}; // angular momentum
const double K1 = 1/I1, K2 = 1/I2, K3 = 1/I3; // reciprocals of principal-axis moments of inertia; no idea if there's a standard letter for this
Quaternion orientation = {1, 0, 0, 0};
while (1) {
Quaternion transformed_L = conjugate(orientation) * L * orientation;
Quaternion transformed_omega = {0, K1 * transformed_L.i, K2 * transformed_L.j, K3 * transformed_L.k};
Quaternion omega = orientation * transformed_omega * conjugate(orientation);
orientation = quaternion_exp(time_step * omega) * orientation;
// ... or orientation = normalize((1 + time_step * omega) * orientation);
// ... or orientation = normalize((1 + time_step * omega + 0.5 * (time_step * omega)**2) * orientation);
output(orientation);
}
Peter Schor
Floris
Joe Strout
Joe Strout