Java 使用四元数旋转模型

Java 使用四元数旋转模型,java,opengl,graphics,3d,lwjgl,Java,Opengl,Graphics,3d,Lwjgl,我已经找到了许多解决这个问题的办法,但似乎没有一个奏效 我正在使用JBullet库检索一个对象方向,它以四元数的形式给出。如何从这个四元数中检索Euler值,以便调用 glRotate(rotationX, 1, 0, 0); glRotate(rotationY, 0, 1, 0); glRotate(rotationZ, 0, 0, 1); 或者有更有效的方法 编辑: 我试过quat->vec public static Vector3f quatToVec(Quat4f q) {

我已经找到了许多解决这个问题的办法,但似乎没有一个奏效

我正在使用JBullet库检索一个对象方向,它以四元数的形式给出。如何从这个四元数中检索Euler值,以便调用

glRotate(rotationX, 1, 0, 0);
glRotate(rotationY, 0, 1, 0);
glRotate(rotationZ, 0, 0, 1);
或者有更有效的方法

编辑:

我试过quat->vec

public static Vector3f quatToVec(Quat4f q) {
        float x = q.x;
        float y = q.y;
        float z = q.z;
        float w = q.w;
        float roll  = (float) (Math.atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z) / Math.PI * 360);
        float pitch = (float) (Math.atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z) / Math.PI * 360);
        float yaw   =  (float) (Math.asin(2*x*y + 2*z*w) / Math.PI * 720);
        return new Vector3f(yaw, pitch, roll);
    }
我试过quat->旋转矩阵

public static FloatBuffer quatToMatrix(Quat4f q) {
        float qx = q.x;
        float qy = q.y;
        float qz = q.z;
        float qw = q.w;
        FloatBuffer fb = BufferUtils.createFloatBuffer(16);
        fb.put(new float[]{1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
                2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
                2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f});
        fb.flip();
        return fb;
    }

然而,这一切似乎都不起作用。你发布的第二个解决方案更可取,因为欧拉角在+/-90度的螺距下会出现奇异现象(在其他领域称为万向节锁)

你现在最大的障碍是你的矩阵是行主要的,无论什么原因。由于这是一个通用的
FloatBuffer
,而不是一个实际的矩阵类,因此在执行
fb.put(…)
时,您可能必须自己转置矩阵

这应该可以做到:

fb.put(new float[] {1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy + 2.0f*qz*qw,        2.0f*qx*qz - 2.0f*qy*qw,        0.0f,
                    2.0f*qx*qy - 2.0f*qz*qw,        1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz + 2.0f*qx*qw,        0.0f,
                    2.0f*qx*qz + 2.0f*qy*qw,        2.0f*qy*qz - 2.0f*qx*qw,        1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
                    0.0f,                           0.0f,                           0.0f,                           1.0f});

您发布的第二个解决方案更可取,因为欧拉角在+/-90度俯仰时会出现奇异(在其他领域称为万向节锁)

你现在最大的障碍是你的矩阵是行主要的,无论什么原因。由于这是一个通用的
FloatBuffer
,而不是一个实际的矩阵类,因此在执行
fb.put(…)
时,您可能必须自己转置矩阵

这应该可以做到:

fb.put(new float[] {1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy + 2.0f*qz*qw,        2.0f*qx*qz - 2.0f*qy*qw,        0.0f,
                    2.0f*qx*qy - 2.0f*qz*qw,        1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz + 2.0f*qx*qw,        0.0f,
                    2.0f*qx*qz + 2.0f*qy*qw,        2.0f*qy*qz - 2.0f*qx*qw,        1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
                    0.0f,                           0.0f,                           0.0f,                           1.0f});

您可以使用

glRotation(Math.acos(q.w)*360/Math.PI, q.x, q.y, q.z);

但是,矩阵提取更可取,因为它避免了glRotation调用中的ACO和cos

glRotation(Math.acos(q.w)*360/Math.PI, q.x, q.y, q.z);

但是,矩阵提取更可取,因为它避免了glRotation调用中的ACO和cos

我以前遇到过这个问题,下面是我的(直接复制粘贴)代码:

这假设quart[]保持骨骼的平移和旋转

您需要对此进行一些更改以匹配您的应用程序


允许一系列调用将骨骼链接在一起。

我以前遇到过这个问题,下面是我的(直接复制粘贴)代码:

这假设quart[]保持骨骼的平移和旋转

您需要对此进行一些更改以匹配您的应用程序


允许一系列调用将骨骼链接在一起。

您尝试了什么?什么不起作用。。。因为我们不是来做你的工作/研究的@Vallentin好的:)你试了什么?什么不起作用。。。因为我们不是来做你的工作/研究的@Vallentin ok done:)非常感谢,你用这个答案结束了2003年数小时的痛苦搜索论坛:)非常感谢,你用这个答案结束了2003年数小时的痛苦搜索论坛:)