【问题标题】:How to get the signed angle of a quaternion on an arbitrary axis如何在任意轴上获得四元数的有符号角度
【发布时间】:2021-11-20 02:01:04
【问题描述】:

我正在尝试制作一个飞机控制器,我的目标是介于街机和现实之间,所以我希望飞机以与滚动成正比的力转动。

我没有对任何调整进行编码,我仍在对整个事物进行原型设计,但我在使用四元数时遇到了获取有符号旋转角度的问题,我查看了 Determining if quarternion rotation is clockwise or counter clockwise 在这里,但我无法将解决方案推广到(几乎)任意平面上的旋转。

我现在所做的:

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 );
    }

编辑:我意识到我正在使用滚动而不是偏航来计算转动力,这本来是错误的措辞,现在更正了。

【问题讨论】:

  • “四元数在任意轴上的有符号角”实际上没有意义,除非您有一个特定的向量,其旋转前后的位置是感兴趣的。如果您对此感兴趣,具体示例将有助于描述您的意思。无论如何,我会从 _rigidbody.AddTorque(_rotationForce * Mathf.Sin( Mathf.Deg2Rad * Vector3.SignedAngle(Vector3.up, _transform.up, _transform.forward) * Vector3.up); 开始,然后从那里进行调整,就像你想修改 Mathf.Sin 的结果以具有不同的缓动一样。
  • 有点不清楚_throttle 与飞机应该滚动的速度有什么关系,所以我在计算中放弃了它。此外,将AddTorqueForce 的默认强制模式一起使用已经将time.fixedDeltaTime 考虑在内,因此您不需要包含它。参见here 关于Force 模式(这是关于AddForce 但也适用于AddTorque
  • 无论如何,如果该公式为您提供了理想的结果,请告诉我,我可以在下面写更多关于它的答案。或者我可以提供其他建议,具体取决于它如何不符合您的需求。
  • 非常感谢!这正是我所需要的!顺便说一句,油门只是我对气体的命名真的很糟糕(idk如何在飞机上调用它......)
  • 在上面睡觉后我意识到还有一种更简单的方法,请参阅下面的答案,如果有帮助不要忘记accept it :)

标签: c# unity3d quaternions


【解决方案1】:

由于您只需要一个描述平面右侧向下的因素,因此您只需使用平面右侧的 y 分量即可。无需引入四元数甚至三角函数。 cmets中的解释:

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);

    // ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2013-04-17
    • 1970-01-01
    • 2015-05-27
    相关资源
    最近更新 更多