Estoy leyendo el libro en línea "Aprendizaje de la programación moderna de gráficos 3D" de Jason L. McKesson
A partir de ahora, estoy preparado para el problema del bloqueo del cardán y cómo resolverlo usando cuaterniones.
Sin embargo, aquí mismo, en la página Quaternions .
Parte del problema es que estamos tratando de almacenar una orientación como una serie de 3 rotaciones axiales acumuladas. Las orientaciones son orientaciones, no rotaciones. Y las orientaciones ciertamente no son una serie de rotaciones. Por lo tanto, debemos tratar la orientación del barco como una orientación, como una cantidad específica.
Supongo que este es el primer punto en el que empiezo a confundirme, la razón es porque no veo la diferencia dramática entre orientaciones y rotaciones. Tampoco entiendo por qué una orientación no puede ser representada por una serie de rotaciones ...
También:
El primer pensamiento hacia este fin sería mantener la orientación como una matriz. Cuando llega el momento de modificar la orientación, simplemente aplicamos una transformación a esta matriz, almacenando el resultado como la nueva orientación actual.
Esto significa que cada guiñada, inclinación y balance aplicado a la orientación actual será relativa a esa orientación actual. Que es precisamente lo que necesitamos. Si el usuario aplica un guiñada positivo, desea que ese guiñada los rote en relación con el lugar donde apuntan actualmente, no en relación con algún sistema de coordenadas fijo.
Entiendo el concepto, sin embargo, no entiendo cómo si la acumulación de transformaciones matriciales es una solución a este problema, cómo el código dado en la página anterior no es solo eso.
Aquí está el código:
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutil::MatrixStack currMatrix;
currMatrix.Translate(glm::vec3(0.0f, 0.0f, -200.0f));
currMatrix.RotateX(g_angles.fAngleX);
DrawGimbal(currMatrix, GIMBAL_X_AXIS, glm::vec4(0.4f, 0.4f, 1.0f, 1.0f));
currMatrix.RotateY(g_angles.fAngleY);
DrawGimbal(currMatrix, GIMBAL_Y_AXIS, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
currMatrix.RotateZ(g_angles.fAngleZ);
DrawGimbal(currMatrix, GIMBAL_Z_AXIS, glm::vec4(1.0f, 0.3f, 0.3f, 1.0f));
glUseProgram(theProgram);
currMatrix.Scale(3.0, 3.0, 3.0);
currMatrix.RotateX(-90);
//Set the base color for this object.
glUniform4f(baseColorUnif, 1.0, 1.0, 1.0, 1.0);
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(currMatrix.Top()));
g_pObject->Render("tint");
glUseProgram(0);
glutSwapBuffers();
}
Según tengo entendido, no es lo que está haciendo (modificar una matriz en una pila) considerar la acumulación de matrices, ya que el autor combinó todas las transformaciones de rotación individuales en una matriz que se almacena en la parte superior de la pila.
Mi comprensión de una matriz es que se utilizan para tomar un punto que es relativo a un origen (digamos ... el modelo), y hacerlo relativo a otro origen (la cámara). Estoy bastante seguro de que esta es una definición segura, sin embargo, siento que falta algo que me impide comprender este problema de bloqueo de cardán.
Una cosa que no tiene sentido para mí es: si una matriz determina la diferencia relativa entre dos "espacios", ¿cómo es que una rotación alrededor del eje Y para, digamos, rodar, no pone el punto en "rodar espacio"? "que luego se puede transformar una vez más en relación con este rollo ... En otras palabras, no debería haber más transformaciones a este punto en relación con este nuevo" espacio de rollo "y, por lo tanto, no tener la rotación en relación con el anterior" espacio modelo "que está causando el bloqueo del cardán.
Es por eso que se produce el bloqueo del cardán ¿verdad? Es porque estamos girando el objeto alrededor de los ejes X, Y y Z en lugar de girar el objeto alrededor de sus propios ejes relativos . ¿O estoy equivocado?
Dado que aparentemente este código que he vinculado no es una acumulación de transformaciones matriciales, ¿puede dar un ejemplo de una solución con este método?
Entonces en resumen:
- ¿Cuál es la diferencia entre una rotación y una orientación?
- ¿Por qué el código vinculado no es un ejemplo de acumulación de transformaciones matriciales?
- ¿Cuál es el propósito real y específico de una matriz, si me equivoqué?
- ¿Cómo podría implementarse una solución al problema del bloqueo del cardán utilizando la acumulación de transformaciones matriciales?
- Además, como beneficio adicional: ¿por qué las transformaciones después de la rotación siguen siendo relativas al "espacio modelo"?
- Otra ventaja: ¿me equivoco al suponer que después de una transformación, se producirán más transformaciones en relación con la corriente?
Además, si no estaba implícito, estoy usando OpenGL, GLSL, C ++ y GLM, por lo que los ejemplos y explicaciones en términos de estos son muy apreciados, si no es necesario.
¡Cuanto más detalle, mejor!
Gracias por adelantado.
fuente
De hecho, las acumulaciones de matrices pueden resolver el bloqueo de cardán. Al acumular rotaciones, agrega gimbals, lo que permite cualquier rotación arbitraria. El diagrama que proporcionó ktodisco muestra un bloqueo de cardán en el diagrama de la izquierda. La matriz para esta orientación se puede definir como:
Debido a la rotación del cardán y, los cardán X y Z ahora están bloqueados, por lo que hemos perdido un grado de movimiento. En este punto no tenemos guiñada (local y, global z) usando estos tres cardán. Pero al agregar otro cardán, puedo rotar localmente alrededor de la y:
Por cada nuevo rollo, cabeceo y guiñada, simplemente agregue otro cardán, ACUMULANDO en una matriz. Entonces, cada vez que se necesita otra rotación local, se crea una rotación y se multiplica a la matriz de acumulación. Como se menciona en el capítulo, todavía hay problemas, pero el bloqueo de cardán no es uno de ellos.
fuente