OpenGL матрица вращения кватернионов - PullRequest
7 голосов
/ 28 июля 2010

Я пытаюсь сделать простое вращение куба вокруг осей x и y:

Я хочу всегда вращать куб по оси x на величину x и вращать куб по оси Y наколичество y, не зависящее от вращения оси x

сначала я наивно сделал:

glRotatef(x,1,0,0);
glRotatef(y,0,1,0);

затем

, но это сначала вращается по x, а затем вращается по yi.y независимо от доступа x.

Я начал изучать кватернионы, поэтому я попытался:

Quaternion Rotation1;
Rotation1.createFromAxisAngle(0,1, 0, globalRotateY);
Rotation1.normalize();

Quaternion Rotation2;
Rotation2.createFromAxisAngle(1,0, 0, globalRotateX);
Rotation2.normalize();

GLfloat Matrix[16];

Quaternion q=Rotation2 * Rotation1;

q.createMatrix(Matrix);
glMultMatrixf(Matrix);

, который почти полностью выполняет то, что было достигнуто, выполняя 2 последовательных glRotates ... так что я думаюя пропускаю шаг или 2.

это кватернионы, путь или я должен использовать что-то другое?И если кватернионы - это путь, какие шаги я могу добавить, чтобы куб вращался независимо от каждой оси.я думаю, что у кого-то еще есть та же проблема: Вращение OpenGL сцены в 2 осях

Ответы [ 4 ]

3 голосов
/ 29 июля 2010

Я получил это, чтобы работать правильно, используя кватернионы: Я уверен, что есть другие способы, но после некоторого повторного поиска, это отлично сработало для меня.Я выложил похожую версию на другом форуме.http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=280859&#Post280859

сначала создайте кватернионное представление углов изменения x / y, затем каждый кадр умножьте кватернионы изменяющихся углов на накопительный кватернион, а затем, наконец, преобразуйте этот кватернион в матричную форму, чтобы умножить текущую матрицу.Вот основной код цикла:

Quaternion3D Rotation1=Quaternion3DMakeWithAxisAndAngle(Vector3DMake(-1.0f,0,0), DEGREES_TO_RADIANS(globalRotateX));
Quaternion3DNormalize(&Rotation1);

Quaternion3D Rotation2=Quaternion3DMakeWithAxisAndAngle(Vector3DMake(0.0f,-1.0f,0), DEGREES_TO_RADIANS(globalRotateY));
Quaternion3DNormalize(&Rotation2);


Matrix3D Mat;
Matrix3DSetIdentity(Mat);
Quaternion3DMultiply(&QAccum, &Rotation1);

Quaternion3DMultiply(&QAccum, &Rotation2);

Matrix3DSetUsingQuaternion3D(Mat, QAccum);
globalRotateX=0;
globalRotateY=0;

glMultMatrixf(Mat);

, затем нарисуйте куб

0 голосов
/ 28 июля 2010

Не ясно, чего вы хотите достичь. Возможно, вам следует подумать о некоторых точках и о том, куда вы хотите их повернуть - например, вершина (1,1,1) должна отображаться в (0,1,0). Затем, исходя из этой информации, вы можете рассчитать необходимое вращение.

Кватернионы обычно используются для интерполяции между двумя вращательными «позициями». Итак, первый шаг - определение вашей начальной и конечной «позиции», которой у вас еще нет. Получив это, вы используете кватернионы для интерполяции. Не похоже, что у вас есть какой-то изменяющийся во времени аспект.

0 голосов
/ 28 июля 2010

Ваша проблема не в блокировке карданного подвеса. И фактически, нет никаких причин, по которым ваша кватернионная версия будет работать лучше, чем ваша матричная (glRotate) версия, потому что кватернионы, которые вы используете, математически идентичны вашим матрицам вращения.

Если вам нужен элемент управления мышью, вы, вероятно, захотите проверить arcballs .

0 голосов
/ 28 июля 2010

Было бы очень полезно, если бы вы могли дать более подробное объяснение того, что вы пытаетесь сделать, и как результаты, которые вы получаете, отличаются от результатов, которые вы хотите.Но в целом использование углов Эйлера для поворота имеет некоторые проблемы, так как объединение поворотов может привести к неинтуитивному поведению (и в худшем случае к потере степени свободы).

Quaternion slerp может быть подходящим вариантом, еслиВы можете найти одну ось и один угол, которые представляют желаемое вращение.Но выполнение последовательных вращений вокруг осей X и Y с использованием кватернионов не поможет вам избежать проблем, присущих составлению вращений Эйлера.

Пост, на который вы ссылаетесь, кажется, связан с другой проблемой.Постер, кажется, переводил свой объект, а затем делал свои вращения, когда он должен был сначала вращаться, а затем переводить.

...