Je lis le livre en ligne "Learning Modern 3D Graphics Programming" de Jason L. McKesson
À partir de maintenant, je suis au problème du verrouillage du cardan et comment le résoudre en utilisant des quaternions.
Cependant ici, sur la page Quaternions .
Une partie du problème est que nous essayons de stocker une orientation sous la forme d'une série de 3 rotations axiales cumulées. Les orientations sont des orientations, pas des rotations. Et les orientations ne sont certainement pas une série de rotations. Nous devons donc traiter l'orientation du navire comme une orientation, comme une quantité spécifique.
Je suppose que c'est le premier endroit où je commence à être confus, parce que je ne vois pas la différence spectaculaire entre les orientations et les rotations. Je ne comprends pas non plus pourquoi une orientation ne peut pas être représentée par une série de rotations ...
Aussi:
La première pensée à cette fin serait de conserver l'orientation comme matrice. Lorsque vient le temps de modifier l'orientation, nous appliquons simplement une transformation à cette matrice, stockant le résultat en tant que nouvelle orientation actuelle.
Cela signifie que chaque lacet, tangage et roulis appliqué à l'orientation actuelle sera relatif à cette orientation actuelle. C'est précisément ce dont nous avons besoin. Si l'utilisateur applique un lacet positif, vous voulez que ce lacet les fasse pivoter par rapport à l'endroit où ils pointent actuellement, et non par rapport à un système de coordonnées fixe.
Le concept, je le comprends, mais je ne comprends pas comment si l'accumulation de transformations matricielles est une solution à ce problème, comment le code donné dans la page précédente n'est pas seulement cela.
Voici le code:
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();
}
À ma connaissance, ce qu'il fait (modifier une matrice sur une pile) n'est-il pas considéré comme accumulant des matrices, car l'auteur a combiné toutes les transformations de rotation individuelles en une seule matrice qui est stockée au sommet de la pile.
Ma compréhension d'une matrice est qu'ils sont utilisés pour prendre un point qui est relatif à une origine (disons ... le modèle), et le faire par rapport à une autre origine (la caméra). Je suis sûr que c'est une définition sûre, mais j'ai l'impression qu'il manque quelque chose qui m'empêche de comprendre ce problème de verrouillage du cardan.
Une chose qui n'a pas de sens pour moi est la suivante: si une matrice détermine la différence relative entre deux "espaces", comment se fait-il qu'une rotation autour de l'axe Y pour, disons, rouler, ne place pas le point dans "l'espace de roulis" "qui peut ensuite être transformé une fois de plus par rapport à ce roulis ... En d'autres termes, aucune autre transformation à ce stade ne devrait être en relation avec ce nouvel" espace de roulis "et donc la rotation ne doit pas être relative à la précédente" espace modèle "qui provoque le verrouillage du cardan.
C'est pourquoi le verrouillage du cardan se produit à droite? C'est parce que nous faisons tourner l'objet autour des axes X, Y et Z définis plutôt que de faire tourner l'objet autour de ses propres axes relatifs . Ou ai-je tort?
Puisqu'apparemment, ce code auquel j'ai lié n'est pas une accumulation de transformations matricielles, pouvez-vous donner un exemple de solution utilisant cette méthode.
Donc en résumé:
- Quelle est la différence entre une rotation et une orientation?
- Pourquoi le code n'est-il pas lié dans un exemple d'accumulation de transformations matricielles?
- Quel est le véritable objectif spécifique d'une matrice, si je me trompais?
- Comment une solution au problème de verrouillage du cardan pourrait-elle être mise en œuvre en utilisant l'accumulation de transformations matricielles?
- De plus, en prime: pourquoi les transformations après la rotation sont-elles toujours relatives à "l'espace objet"?
- Autre bonus: ai-je tort de supposer qu'après une transformation, d'autres transformations se produiront par rapport au courant?
De plus, si ce n'était pas implicite, j'utilise OpenGL, GLSL, C ++ et GLM, donc des exemples et des explications en termes de ceux-ci sont grandement appréciés, sinon nécessaires.
Plus il y a de détails, mieux c'est!
Merci d'avance.
la source
Les accumulations matricielles peuvent en fait résoudre le verrouillage du cardan. En accumulant des rotations, vous ajoutez des cardans, permettant toute rotation arbitraire. Le diagramme fourni par ktodisco montre un verrou de cardan dans le diagramme de gauche. La matrice de cette orientation peut être définie comme:
En raison de la rotation du cardan y, les cardans X et Z sont maintenant verrouillés, nous avons donc perdu un degré de mouvement. À ce stade, nous n'avons pas de lacet (y local, z global) en utilisant ces trois cardans. Mais en ajoutant un autre cardan, je peux tourner localement autour du y:
Pour chaque nouveau roulis, tangage et lacet, ajoutez simplement un autre cardan, en les cumulant dans une matrice. Ainsi, chaque fois qu'une autre rotation locale est nécessaire, une rotation est créée et multipliée dans la matrice d'accumulation. Comme le chapitre le mentionne, il y a toujours des problèmes, mais le verrouillage du cardan n'en fait pas partie.
la source