Кватернион "регулярное вращение" дает странные значения при переходе к углу оси - PullRequest
0 голосов
/ 22 ноября 2011

похоже, что есть проблема с моей пользовательской реализацией Quaternion. Скачать реализацию My quaternion в 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? Хотя я вычислил угол по формуле 2 * Acos (Quaternion.w) в методе Quaternion # toAxisAngle ()? Может быть, реализация не плохая, так как я могу вычислить угол так, чтобы он возвращал 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
 }

Привет

1 Ответ

4 голосов
/ 28 декабря 2011

Я подозреваю, что ваша кватернионная реализация в порядке.Когда вы проходите 360 градусов с кватернионом, он инвертирует ось вращения.Итак, сначала ваш кватернион представляет собой положительные вращения вокруг положительной оси y ;однако, когда вы пересекаете 360 градусов, он начинает представлять положительное вращение вокруг оси отрицательное y .

Таким образом, углы, которые вы получаете, все еще верны.Вращение нуля обычно представляется как [1 0 0 0].Поворот на 180 градусов вокруг оси y будет представлен как [0 0 1 0].И тогда поворот на 360 градусов (очевидно, эквивалентный повороту 0) оказывается равным [-1 0 0 0].Поворот на 180 градусов даст вам [0 0 -1 0] Это общее свойство кватернионов.Они в 2 раза избыточнее.Если вы отрицаете все компоненты кватерниона, это эквивалентно вращению в противоположном направлении вокруг перевернутой оси, чтобы получить тот же результат.

Чтобы получить то, что вы хотели, вы можете просто проверить y компонент вашего кватерниона.Если оно меньше нуля, то вычтите вычисленное вращение из 360, чтобы перевернуть ось обратно в положительное значение.

...