Home > Mobile >  How to get the signed angle of a quaternion on an arbitrary axis
How to get the signed angle of a quaternion on an arbitrary axis

Time:11-21

I'm trying to make an airplane controller, I am kind of aiming for something between arcade and realistic, so I want the plane to turn with a force proportional to the roll.

I haven't coded in any adjustments and I'm still prototyping the whole thing, but I encountered a problem with getting the signed rotation angle while using quaternions, I had a look at Determining if quarternion rotation is clockwise or counter clockwise here on SO but I am having trouble generalizing the solution to the (almost) arbitrary plane the rotation can be at.

What I made by now:

private void FixedUpdate()
    {
        float desiredYaw = _yaw * _rotationSpeed * Time.fixedDeltaTime;
        float desiredPitch = -_pitch * _rotationSpeed * Time.fixedDeltaTime;

        float rotationStepSize = _throttle * Time.fixedDeltaTime;

        Quaternion toRotate = Quaternion.Euler(desiredPitch, 0, desiredYaw);
        Quaternion straighRotation = Quaternion.LookRotation(_transform.forward, Vector3.up );
        
        _rotation = _transform.rotation * toRotate;
        float turningForce = Quaternion.Angle( _rotation, straighRotation );

        _rigidbody.MoveRotation( _rotation );
        _rigidbody.AddTorque( turningForce * _rotationForce * rotationStepSize * Vector3.up );
        _rigidbody.AddRelativeForce( _speed * rotationStepSize * Vector3.forward );
    }

EDIT: I realized I'm calculating the turning force using the roll rather then the yaw, that was intended just wrong wording, corrected now.

CodePudding user response:

Since all you need is a factor that describes how downward the plane's right is, you can just use the y component of the plane's right for that. No need to bring in quaternions or even trigonometry. Explanation in comments:

private void FixedUpdate()
{
    // ...

    // Calculate how downward local right is in range [-1,1]
    // The more downward, the more tilted right the plane is
    //   positive = tilted right
    //   negative = tilted left
    float turnFactor = -_transform.right.y;

    // Could do things to modify turnFactor to affect easing here.
    // For instance, if turning rate should start slower then rapidly increase:
    //   turnFactor = Mathf.Sign(turnFactor) * turnFactor * turnFactor;

    // Use factor and _rotationForce member to calculate torque, apply along 
    //   global up. 
    // We expect to call this every fixed frame so we can just use the default
    //   ForceMode of ForceMode.Force which multiplies fixed delta time inside.
    _rigidbody.AddTorque(_rotationForce * turnFactor * Vector3.up);

    // ...
}
  • Related