2010-07-28 37 views
7

Im tratando de hacer una simple rotación de un cubo sobre los ejes X e Y:cuaterniones rotación matriz de OpenGL

Quiero girar siempre el cubo sobre el eje x por una cantidad x y girar el cubo sobre el eje Y por una cantidad y independiente de la rotación del eje x

primera i ingenuamente hizo:

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

entonces

pero que los primeros Gira ov er x luego gira sobre y quiero rotar sobre la y independientemente del acceso x.

me puse a buscar en los cuaterniones, así que intenté:

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); 

que sólo lo hace casi exactamente lo que se logró haciendo 2 glRotates consecutivos ... así que creo im perder el paso o 2.

¿Los cuaterniones son el camino a seguir o debería usar algo diferente? Y si los cuaterniones son el camino a seguir, ¿qué pasos puedo agregar para hacer que el cubo gire independientemente de cada eje? Creo que alguien tiene el mismo problema: Rotating OpenGL scene in 2 axes

+0

bien déjame decirlo de esta manera ... lo que quiero hacer es girar un cubo con el ratón. Quiero a la izquierda para controlar la rotación del eje y de las pantallas y luego controlar y bajar las pantallas x rotación del eje. Quiero que giren independientemente del otro eje, pero solo roten en las pantallas del eje global. Si hago 2 glRotations no obtengo este comportamiento porque la rotación de un eje mutila al otro. – yeahdixon

+0

Por ejemplo, girar un cubo: operaciones sin rotaciones revela un solo lado luego hago glRotatef (90,1,0,0); \t glRotatef (45,0,1,0); \t ⁃ \t me da un cubo inclinado (diamante), cuando quería un cubo que tenía su esquina frente a la cámara que en realidad sería el resultado del intercambio de las operaciones: \t glRotatef (45,0,1,0); \t glRotatef (90,1,0,0); Simplemente cambiaría los comandos de rotaciones, pero eso tiene los mismos problemas cuando se cambian los valores de ángulo. – yeahdixon

Respuesta

3

Lo hice funcionar correctamente utilizando cuaterniones: estoy seguro de que hay otras formas, pero después de algún reseatch, esto funcionó perfectamente para mí. Publiqué una versión similar en otro foro.http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=280859&#Post280859

primero crear la representación de cuaternión de los ángulos de cambio x/y entonces cada trama de multiplicar el cambiando los ángulos de los cuaterniones a un cuaternión acumulación, a continuación, convertir finalmente que cuaternión a la matriz forma para multiplicar la matriz actual. Aquí está el código principal del bucle:

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); 

luego dibujar el cubo

+0

este sitio realmente ayudó: http://www.gamedev.net/reference/articles/article1095.asp pero no tenía sentido al principio hasta que investigué y probé más – yeahdixon

0

Sería de gran ayuda si usted podría dar una explicación más detallada de lo que usted está tratando de hacer y cómo los resultados que está obteniendo difieren de los resultados que desea. Pero en general usar ángulos de Euler para la rotación tiene algunos problemas, ya que combinar rotaciones puede dar como resultado un comportamiento poco intuitivo (y en el peor de los casos perder un grado de libertad).

Quaternion slerp podría ser el camino a seguir si puede encuentre un solo eje y un solo ángulo que represente la rotación que desea. Pero hacer rotaciones sucesivas alrededor del eje X e Y usando cuaterniones no lo ayudará a evitar los problemas inherentes a la composición de las rotaciones de Euler.

Sin embargo, la publicación a la que enlazas parece implicar otro problema. El póster parece haber estado traduciendo su objeto y luego haciendo sus rotaciones, cuando debería haber estado rotando primero y luego traduciendo.

+0

Describí el problema anterior con más detalle, pero creo que el término oficial es gimbal lock – yeahdixon

0

No está claro lo que quiere lograr. Tal vez deba pensar en algunos puntos y hacia dónde quiere que giren, por ej. el vértice (1,1,1) debería corresponder a (0,1,0). Luego, a partir de esa información, puede calcular la rotación requerida.

Los cuaterniones se utilizan generalmente para interpolar entre dos "posiciones" giratorias. Así que el primer paso es identificar sus "posiciones" de inicio y fin, que aún no tiene. Una vez que tienes eso, usas cuaterniones para interpolar. No parece que tengas ningún aspecto variable en el tiempo aquí.

+0

Describí el problema anterior con más detalle, pero creo que el término oficial es gimbal lock – yeahdixon

0

Su problema no es el bloqueo cardánico. Y efectivamente, no hay ninguna razón por la cual su versión de cuaternión funcionaría mejor que su versión de matriz (glRotate) porque los cuaterniones que está utilizando son matemáticamente idénticos a sus matrices de rotación.

Si lo que desea es un control de mouse, es probable que desee comprobar arcballs.

+0

gracias, sí estoy totalmente de acuerdo, cuaterniones y matrices de rotación se puede intercambiar para que pueda hacerse sin cuaterniones. La respuesta a este problema fue más en la premultiplicación de la matriz, usando rotaciones incrementales. – yeahdixon

Cuestiones relacionadas