How to calculate time it takes for angular velocity to reach 0 w/ angular drag being applied?

Hi there,

So I apply a force to my Image GameObject like:

img.GetComponent<Rigidbody2D>().angularVelocity = Random.Range(-720, -1080);

After this I’d like to calculate the time it takes - in seconds - for the angular drag to stop its rotation.
Angular drag is 0.5, mass is 1.0, the object’s position is freezed on both the x and y axis.

I tried with:

img.GetComponent<Rigidbody2D> ().angularVelocity * img.GetComponent<Rigidbody2D> ().angularDrag * Time.fixedDeltaTime;

It does give an almost accurate result but I suppose it is more complicated than just dividing or multiplying 2 or 3 variables together.
I’ve also searched Unity’s references for physics and (angular) drag but it only describes the definition of it and its damping, coefficient. No formula or method given how it is being calculated.


The usage would be a “Spin the Wheel” kind of feature for my game, where by a button the player gives a random rotation on the Z for the above image gameobject and within an IEnumerator, I use yield return new WaitForSeconds(time it takes to reach 0) and after that, based on its angle an award will be presented to the player.

Any suggestions are welcome, thanks for your time!

Christian

Well, the angular drag is just a percentage slowdown. To get the multipier that the angular velocity is multiplied with every fixed frame you just need to multiply the angularDrag with the fixedDeltaTime which gives you the slowdown percentage. Subtract this from “1” and you get the multiplier that is applied each fixed frame.

Once you have this you have to define an angular velocity that you consider “resting”. The sleeping behaviour is not that easy to calculate as it relies on the kinetic energy of the rigidbody and for the angular velocity it depends on the inertia tensor. So it’s easier to just say an angular velocity of “0.05” is our goal. Note that you can’t go for an velocity of 0 as in theory you would never reach it. If your starting angular velocity is “10” we just calculate the total factor that brings us from 0.05 to 10 (or the other way round). In this case 10 / 0.05 == 200

Now we can use the logarithm to calculate the required steps it would take to reach that goal:

log(200) / log(1-angularDrag*fixedDeltaTime)

This will give us a negative number. However the absolute value should be the exact number of fixed frames until you reach an angular velocity of 0.05 when starting from 10

As a method it would be something like this:

public static float AngularDragTime(float aVelocity, float aTargetVelocity, float aAngularDrag)
{
    float d = aVelocity / aTargetVelocity;
    float a = 1f - aAngularDrag * Time.fixedDeltaTime;
    return -Time.fixedDeltaTime * (Mathf.Floor(Mathf.Log(d) / Mathf.Log(a))-2);
}

This should return the time in seconds until a rigidbody with an angular velocity of “aVelocity” reaches aTargetVelocity when using the "aAngularDrag " and no other forces are applied. The floor and the additional “2” frames seem to work consistently. If i count down the calculated time each fixed frame then the time will reach 0 at the same frame as the velocity drops below our target velocity.

Have you considered using:

while(!img.GetComponent<Rigidbody2D>().isSleepgng())
{
    yield return new WaitForSeconds(0.2f);
}