【问题标题】:What is the correct way to rotate a quaternion from its current rotation a certain angle?将四元数从当前旋转角度旋转一定角度的正确方法是什么?
【发布时间】:2021-11-29 21:47:31
【问题描述】:

我正在尝试使用来自 JOML 的四元数来使用四元数旋转:https://github.com/JOML-CI/JOML/blob/main/src/org/joml/Quaternionf.java

我可以让物体旋转,但它们卡住了,无法完成完整的旋转。对象每帧都会更新。

编辑: 删除了所有与欧拉相关的代码,我只是试图让对象基于某个角度在单个轴上旋转。

编辑 2: 我正在尝试使用共轭并将四元数相乘,就像我在一些视频中看到的那样。但我并不完全在那里,因为模型出于某种原因将自己从屏幕上旋转了下来。

编辑 3: 标准化四元数修复了消失的行为。问题似乎是没有简单的方法来旋转一定的量,而没有一个计时器来处理这在我的情况下不起作用,因为我试图旋转一个没有设置开始和结束的任意量的对象。

旋转函数

public void rotate(float angle, float x, float y, float z) {
    Quaternionf rot = new Quaternionf();
    rot.rotateAxis((float) Math.toRadians(angle), x, y, z);

    Quaternionf conjugate = rot.conjugate();

    rotation = rot.mul(rotation).mul(conjugate);
}

调用旋转函数

entity.transform.rotate( 1,0,1, 0);

【问题讨论】:

    标签: java rotation lwjgl quaternions joml


    【解决方案1】:

    无论您将欧拉角转换为矩阵还是四元数或任何表示形式都没有关系:只要您使用欧拉角表示方向,Gimbal Lock 不可避免

    因此,为了避免万向节锁定的发生,您必须放弃使用欧拉角并使用一种表示方向(如 3x3 矩阵或四元数)并应用 delta 改变它们,而不是试图将完整的方向表示为三个欧拉角。因此,每当您 - 比方说 - 将对象围绕某个轴旋转几度时,您就会将该增量变化或方向应用于矩阵/四元数。

    【讨论】:

    • 所以如果我想在 x 上旋转 5 度,我在 x 上将四元数旋转 5 度?我使用的库中有一个 rotateXYZ 四元数函数,它似乎只有在我让当前的 x + x 旋转并将其输入函数时才有效,但它只能在锁定之前执行 180 度。
    • 删除了大部分,仍然无法使用,但我觉得我越来越近了。据我所知,旋转函数似乎只是设置旋转,而不是将其附加到当前对象旋转。
    【解决方案2】:

    我相信我已经弄明白了。

    1. 您需要创建一个四元数并将其旋转到您的增量值,不要直接操作四元数值(例如,改用 rotationX 函数)。

    2. 要将四元数相加,请将它们相乘。

    3. 最后你需要使用方程:

      delta 四元数 * 旋转的四元数 * delta 四元数的逆

    代码:

        public void rotate(float x, float y, float z) {
            //Use modulus to fix values to below 360 then convert values to radians
            float newX = (float) Math.toRadians(x % 360);
            float newY = (float) Math.toRadians(y % 360);
            float newZ = (float) Math.toRadians(z % 360);
    
            //Create a quaternion with the delta rotation values
            Quaternionf rotationDelta = new Quaternionf();
            rotationDelta.rotationXYZ(newX, newY, newZ);
    
            //Calculate the inverse of the delta quaternion
            Quaternionf conjugate = rotationDelta.conjugate();
    
            //Multiply this transform by the rotation delta quaternion and its inverse
            rotation.mul(rotationDelta).mul(conjugate);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-05
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多