0

我的自定义四元数实现似乎有问题。 下载我在 Java 中的四元数实现

当我启动这个片段时,为了查看四元数角度的演变,在 Main() 方法中:

    Quaternion currentRotation = Quaternion.buildIdentityQuaternion();
    Quaternion constantRotation = Quaternion.buildFromAxisAngle(10, 0,1,0);

    while(true){
        float angle = currentRotation.toAxisAngle()[0];
        System.out.println(angle);
        currentRotation = constantRotation.mulInLeftOf(currentRotation);
    }

我得到了以下结果:

0.0
9.99997
19.999975
29.999979
39.99998
49.999977
59.999977
69.99998
79.99997
89.99997
99.99997
109.99997
119.99997
129.99997
139.99997
149.99997
159.99997
169.99997
179.99997
189.99998
199.99998
209.99998
219.99998
230.0
240.0
250.00002
260.00003
270.00003
280.00003
290.00006
300.0001
310.00012
320.00015
330.00024
340.00037
350.00082
360.0
350.00012
340.0001
330.0001
320.0001
310.00006
300.00006
290.00006

那么为什么角度值首先变为 360 度然后向 0 减小?虽然我已经用 Quaternion#toAxisAngle() 方法中的公式 2*Acos(Quaternion.w) 计算了角度?也许实现还不错,那么如何计算角度以使其返回 0, 10, ...,350, 360, 0, 10, ..., 350, 360, 0, 10 等等?

最后,有没有办法计算真实角度?所以这个角度跨越值:0,10,20,30,...,360,0,10,20...?


然而,我设法在 JOGL 程序中使用它来使简单的 6 色立方体有规律地旋转,只需每次计算四元数乘法并在结果四元数上调用 toMatrix() 方法。什么有效(不要关注 JOGL 的具体实现细节):

  // The OpenGL functionnalities of my program
  MyJOGLEventListener implements GLEventListener {

       Quaternion myCurrentRotation = Quaternion.buildIdentityQuaternion() // w=1, x=0, y=0, z=0
       Quaternion constantRotation = Quaternion.buildFromAxisAngle(0.02f, 0,1,0) // angle = 0.02 degrees, x=0, y=1, z=0

       GLUgl2 glu = new GLUgl2();

       public void display(GLAutoDrawable drawable) {
            GL2 gl = drawable.getGL().getGL2();
            gl.glClear(/* OMITTED : color buffer and depth buffer*/);
            gl.glLoadIdentiy();

            glu.gluLookAt(/* OMITTED */);

            /// the three most relevent lines ///////////////////////////////////
            gl.glMultMatrix(myCurrentRotation.toMatrix(), 0);

            MyCubeDrawer.drawCube(gl);

            myCurrentRotation = constantRotation.mulInLeftOf(myCurrentRotation);
            //////////////////////////////////////////////////////////////////////

      }

     // OMITED : in init(GLAutoDrawable) method, I set up depth buffer
     // OMITED : the reshape(GLAutoDrawable drawable, int x, int y, int width, int height) sets the viewport and projection
 }

问候

4

1 回答 1

4

我怀疑你的四元数实现很好。当您使用四元数传递 360 度时,它会反转旋转轴。因此,首先,您的四元数表示围绕正y轴的正旋转;然而,一旦你穿过 360 度,它就开始代表围绕 y轴的正旋转。

所以你得到的角度仍然是正确的。零旋转通常表示为 [1 0 0 0]。绕y轴旋转 180 度将表示为 [0 0 1 0]。然后旋转 360 度(显然相当于旋转 0)得出 [-1 0 0 0]。再旋转 180 度会给你 [0 0 -1 0] 这是四元数的一般属性。它们是 2 倍冗余。如果将四元数的所有分量取反,就相当于绕着一个翻转的轴反方向旋转得到相同的结果。

为了得到你想要的,你可以检查你的四元数的y分量。如果它小于零,则从 360 度减去您计算的旋转,以便将轴翻转回正数。

于 2011-12-28T03:09:17.187 回答