Applying Angular Acceleration in a Basic Physics Model

| | August 8, 2015

I’m attempting to use a basic physics system to create an arcade flight model. So far I have managed to get the aircraft moving forward, apply gravity, etc. However, after trying to implement torque I noticed some interesting behaviour in the flight model. When turning after a while the controls appear to reverse, sometimes, the controls for the different movements (pitch, roll, yaw) also seem to change. I was hoping that someone may be able to advise me as to what I should check next. I have included my source code in case anyone spots any glaring mistakes! I have listed some of the variables below to show their data types:

Quaternion rotation = Quaternion.Identity;
Quaternion newRotation = Quaternion.Identity;
Vector3 rotationChange = Vector3.Zero;
Vector3 rotVec = Vector3.Zero;

Below is the update logic for the rotational forces:

dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
if (dt > 1.0f / 60.0f)
{
    dt = 1.0f / 60.0f;
}

Vector3 newRotationChange = rotationChange + dt * angularAcceleration;
Vector3 newRotVec = rotVec + dt * newRotationChange;

rotationChange = newRotationChange;
rotVec = newRotVec;

Vector3 rotAxis = rotVec;
rotAxis.Normalize();

if (rotVec.Length() < 0.001f)
{
    rotVec = Vector3.Zero;
    newRotation = Quaternion.CreateFromAxisAngle(forwardVector, 0.0f);
}
else
{
    float angle = rotVec.Length();
    newRotation = Quaternion.CreateFromAxisAngle(rotAxis, angle);
}

if (rotationChange.Length() < 0.001f)
{
    rotationChange = Vector3.Zero;
}

rotation = newRotation;
angularAcceleration = Vector3.Zero;

My method for creating the torque:

/// <summary>
/// Creates a rotational force for an object
/// </summary>
/// <param name="pointOfAction">Point the force is being applied on the object
/// </param>
/// <param name="forceAmount">Magnitude of the force being applied</param>
/// <param name="forceDir">Direction of the force being applied</param>
public void CreateTorque(Vector3 pointOfAction, float forceAmount, Vector3
        forceDir)
{
    // Vector from position to pointOfAction
    Vector3 r = pointOfAction - position;

    // Create the force
    Vector3 force = forceDir * forceAmount;

    // Create the torque force
    torque = Vector3.Cross(r, force);

    angularAcceleration += torque;
}

Sorry for the massive code block and thanks in advance for any help you can give.

2 Responses to “Applying Angular Acceleration in a Basic Physics Model”

  1. Ok so I finally managed to work out what I was doing wrong.
    The issue was how I was applying the rotation vector to the quaternion. Basically rather than use Quaternion.CreateFromAxisAngle() I now create a rotation change Quaternion using my angular velocity as the X,Y,Z components and 0 for the scalar. So just for clarity here is my new update code for rotational physics. ( This replaces every line of code after calculating dt)

    Vector3 newAngularVelocity = angularVelocity + dt * angularAcceleration;
    Quaternion rotChange = 
        new Quaternion(angularVelocity.X, angularVelocity.Y, angularVelocity.z, 0);
    rotChange = Quaternion.Multiply(rotChange, dampeningFactor) * rotation;
    rotation += rotChange * dt;
    rotation.Normalize();
    
    angularVelocity = newAngularVelocity;
    angularAcceleration = Vector3.Zero;
    

    Hopefully this proves helpful to someone else!

  2. Whenever you use .CreateFromAxisAngle() it is necessary to supply a unit length vector for the axis param. If you don’t, it will over or under rotate the result since the axis magnitude is a factor in the rotation calculation.

    Try normalizing it like this:

    else
    {
        float angle = rotVec.Length();
        rotVec /= angle;//this normalizes rotVec
        newRotation = Quaternion.CreateFromAxisAngle(rotVec, angle);// use 'rotVec' as the axis, not rotAxis
    }
    

Leave a Reply