3
\$\begingroup\$

I'm writing a small 3D physics engine, and I am trying to get the angular velocity vector of two shapes, specifically two cubes.

For deeper understanding I have divide the motion to linear and angular motion.

For the angular motion I have done a few steps.

I calculated the inertia tensor matrix which is 3x3 so I could get the torque as follows:

$$\tau=I\alpha \\ \begin{bmatrix} \tau_x \\ \tau_y \\ \tau_z \end{bmatrix} = \begin{bmatrix} I_{xx} & I_{xy} & I_{xz} \\ I_{xy} & I_{yy} & I_{yz} \\ I_{xz} & I_{yz} & I_{zz} \end{bmatrix} \begin{bmatrix} \alpha_x \\ \alpha_y \\ \alpha_z \end{bmatrix} \\ \tau_x = I_{xx}\alpha_x+I_{xy}\alpha_y+I_{xz}\alpha_z \\ \tau_y = I_{xy}\alpha_x+I_{yy}\alpha_y+I_{yz}\alpha_z \\ \tau_z = I_{xz}\alpha_x+I_{yz}\alpha_y+I_{zz}\alpha_z $$

And for calculating the matrix I have used: $$I= \begin{bmatrix} m(y^2+z^2) & -mxy & -mxz \\ -mxy & m(x^2+z^2) & -myz \\ -mxz & -myz & m(x^2+y^2) \end{bmatrix} $$

Using the formulas described here, I could get the impulse and the final angular velocities for all shapes as follows:

Impulse: \$j= -(1+e) \frac{(v_a-v_b)•n + (r_a×n)•\omega a - (r_b×n)•\omega_b}{ 1/m_a+1/m_b+(r_a×n)•([I_a]^{-1}(r_a×n))+(r_b×n)•([I_b]^{-1}(r_b×n))}\$
Final velocity of object a:\$\vec V_{af} =Vai-J/Ma\$
Final velocity of object b:\$\vec V_{bf} =Vbi-J/Mb\$
Final angular velocity of object a:\$w_{af}=wai-[Ia]^{-1}(J x ra) \$
Final angular velocity of object b:\$w_{bf}=wbi-[Ib]^{-1}(J x rb) \$

So my question is: how could I calculate the rotational angular which each object should rotate and for how long it should last?

\$\endgroup\$
5
+50
\$\begingroup\$

The angular velocity vector you've computed using the method you've shown gives you two things:

  • The direction the vector points is the axis of rotation
  • The magnitude of the vector is the speed of rotation (typically in radians per second)

So, to rotate the object, you can take:

// Separate axis and speed into separate variables.
float angularSpeed = angularVelocity.Length;
Vector3 axis = angularVelocity / angularSpeed;

// Compute how far the object rotates in the time 
// duration of the current simulation step.
float angularIncrement = angularSpeed * deltaTime;

Then construct a rotation matrix from the axis and angle, or a quaternion like so:

Quaternion rotationIncrement;
rotationIncrement.xyz = Sin(angularIncrement/2f) * axis;
rotationIncrement.w = Cos(angularIncrement/2f);

This lets you rotate the objects frame-by-frame according to their angular velocities.

As for "how long" to rotate them, in Newtonian physics, "an object in motion tends to stay in motion," so they'll keep spinning this way like a gyroscope or an asteroid tumbling in space until another collision or force acts on them to cancel the spin.

In games, we'll often simulate friction by applying a damping to the angular velocity, multiplying it by a constant less than one each frame so that the rotation will eventually slow to [low enough to round down to] nothing.

\$\endgroup\$
  • \$\begingroup\$ So helpful ,Thank you! \$\endgroup\$ – Abdulrahman Jul 1 at 16:57
  • \$\begingroup\$ math.stackexchange.com/questions/1517036/… I don't think you and I even speak the same language. Damn, you're smart. \$\endgroup\$ – Evorlor Jul 5 at 15:59
  • \$\begingroup\$ I'm happy to explain anything that's not making sense, @Evorlor — most of it's just terminology or patterns that become familiar after you've seen them a few times. \$\endgroup\$ – DMGregory Jul 5 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.