Estoy tratando de simular (para un juego educativo) el conocido efecto de que los objetos giratorios con tres momentos de inercia desiguales son inestables cuando giran alrededor del eje central.
Algunas explicaciones de este efecto se dan aquí:
La mayor parte de estas matemáticas están, por desgracia, por encima de mi cabeza (aunque lo estoy intentando). Pero para mis propósitos, necesito algo más que "es la forma de un oscilador armónico" o "no es un oscilador armónico"; Necesito reproducir realmente el efecto en la simulación.
Intenté esto usando el motor de física incorporado de Unity aquí:
Puede probarlo usted mismo si tiene (o instala) el complemento Unity gratuito; muestra un bloque de 1x4x7 de densidad uniforme, girando alrededor de su eje central. Con el botón "Poke" puede inducir un pequeño par aleatorio. Tocar el bloque repetidamente puede torcer su eje, pero una vez que dejas de tocarlo, el eje permanece fijo y gira constantemente en cualquier dirección. En ningún caso he podido hacerlo rodar (como se ve en este vídeo de una baraja de cartas, o este de alguna simulación).
Y su falta de caídas tiene mucho sentido para mí. Según tengo entendido, el estado de un cuerpo rígido se define por su posición, velocidad, orientación y velocidad angular. En ausencia de fuerzas externas, la velocidad y la velocidad angular deben permanecer sin cambios. La velocidad angular se puede describir como un eje y una velocidad de rotación. Entonces, sin ninguna fuerza externa actuando sobre él, ¿cómo puede cambiar el eje de rotación?
Claramente, falta algo tanto en mi comprensión intuitiva como en el motor de física dentro de Unity. No te concentres demasiado en lo último; Puedo programar mi propio motor de física, si entiendo lo que debería hacer. ¿Cuál es la parte clave que me falta, que explica cómo (y de qué manera) el eje de rotación puede cambiar sin ninguna fuerza externa? En pseudocódigo, estilo de integración de Euler directo simple, ¿cómo se simularía esto?
, y es constante en ausencia de fuerzas externas. Lo que creo que te estás perdiendo es que gira con el cuerpo rígido, por lo que no es constante en general y tampoco lo es .
Jugué con su ejemplo en línea, y la velocidad angular parece permanecer siempre constante cuando no estoy empujando el bloque, lo cual es consistente con un tensor de inercia que es un múltiplo escalar de la identidad. Nunca he usado Unity, pero parece admitir tensores de inercia arbitrarios a través de Rigidbody.inertiaTensor y Rigidbody.inertiaTensorRotation , por lo que tal vez solo necesite configurarlos correctamente.
Si termina teniendo que desarrollar su propia física, aquí hay un pseudocódigo ingenuo, no probado y potencialmente incorrecto:
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);
}
Pedro Shor
floris
joe strout
joe strout