salut, j'utilise la fonction getOpenGLMatrix() pour récupérer une matrice de 16 cases , qui contient les mises à jour physique des objets.
j'ai trouvé que les cases 12, 13 et 14 correspondent à la position, mais je n'arrive pas à trouvé comment sont agencé les autres cases,
quelqu'un aurait une idée ? merci.
Hors ligne
Si j'ai bien compris, il s'agit d'une matrice de transformation OpenGL. Ce sont des matrices 4*4 qui représentent la translation, la rotation et le scale d'une transformation. De manière schématique :
[ a b c x
d e f y
g h i z
0 0 0 1]
Tes coefficients 12,13 et 14 sont sur la matrices ci-dessus les coefficient x,y,z soit la translation (autrement dit, ta position)
La matrice 3*3 en haut à gauche (coefficients a à i) représente la rotation et le scale. Plus précisément, a, e et i sont le facteur d'agrandissement selon X, Y et Z. Après, je ne sais plus la formule exacte, mais de ça, tu peux extraire les angles de rotation selon X,Y et Z également.
La dernière ligne de la matrice, je ne sais plus à quoi elle sert. En général, elle a les valeurs que je lui ai donnée. L'idée, c'est que si tu fait le produit d'un vecteur [X Y Z W] avec cette matrice (représentant un objet à une position X, Y, Z), tu obtiens en sortie un vecteur [X',Y',Z', W'] qui est ton objet que tu as transformé (tourné changer de taille et déplacer).
Hors ligne
merci pour les explications, par contre je suis un peu perdu sur la matrice 3*3 .
A quoi correspond bcd et fgh ? j'ai surtout besoin de récupérer la rotation.
Hors ligne
Coucou.
Juste au cas où:
Une matrice de passage ou homogène est une matrice 4*4 comme indiqué ci-dessous (tu peux la voir aussi comme un repère 3D ou une matrice de positionnement d'un objet dans son monde 3D):
11 12 13 | 14
21 22 23 | 24
31 32 33 | 34
---------------
41 42 43 | 44
Les termes 14, 24 et 34 sont respectivement x, y, z, soit ton vecteur translation ou matrice de translation.
Les termes 11, 12, 13 et 21, 22, 23 et 31, 32, 33 sont les 9 termes de la matrice de rotation, ou matrice 3*3. Elle donne sans ambiguïté la position angulaire de ton repère par rapport à un autre repère (le repère monde par exemple).
Le terme 44 est toujours égale à 1 et 41, 42, 44 sont égaux à 0. Cette dernière ligne est là pour rendre la matrice carrée et donc permettre des calculs d'inversions matricielles.
Du coup, lorsque tu multiplies un vecteur (x1, y1 , z1 ,1) par cette matrice, tu obtiens un autre vecteur exprimer dans ce nouveau repère.
Ps: OpenGL utilise les termes 41, 42, 43 pour y stocker le vecteur "échelle" en x, y et z respectivement.
Pss: Pour des raisons historiques, le z et le y sont inversé dans les moteurs 3D par rapport à la réalité mathématique. Soit, si tu insères des calculs extérieur à Irrlicht, tu dois permuter les lignes 3-4 et les colonnes 3-4. Si tu ne fais que de l'Irrlicht, alors il n'y a pas ce genre de problème. Et oui, les premiers jeux vidéos étaient en 2D codés en x-y, après est venue la profondeur qui devint z, d'où la permutation.
Voili voilou. Bonne soirée.
Dernière modification par Gehogor (20-01-2010 22:07:47)
Hors ligne
merci pour les précisions, cependant cela reste toujours aussi floue concernant les rotations.
comment pourrai-je faire pour calculer les rotations en degrés ?
Hors ligne
Dans l'idée, il faut voir ta matrice 4*4 non pas comme une seule matrice, mais comme une multiplication de matrices, ce qui correspond à une suite de transformation.
M = Rx*Rx*Rz*S*T
Avec Rx la matrice qui définit une rotation autour de l'axe X, Ry la rotation autour de Y, Rz la rotation autour de Z, S le changement de taille, T la translation. Attention, l'ordre des transformations (et donc du produit de matrice) est important, si tu change l'ordre, tu n'obtiens pas forcément le même résultat.
Pour la forme des matrices, je te laisse voir ça sur l'image ci dessous :
Ensuite, pour récupérer les angles de rotations, il me semble qu'Irrlicht a une fonction qui permet de le faire. Regarde un peu la classe CMatrix4 dans l'API. Cependant, dans mon souvenir, quand j'avais essayé de l'utiliser, la fonction pour récupérer les angles n'était pas très au point. Mais c'était avec la 1.4 je crois, depuis c'est peut être corrigé.
Sinon, si tu veux le faire toi même, il faut que je regarde dans un vieux code, il me semble que je l'avais fait, mais c'est des maths pures.
Hors ligne
En effet, je vais essayer d'être plus claire en ce qui concerne la matrice de rotation qui est le résultat des produits des matrice de rotation en X,Y et Z comme l'a expliqué très justement Hawk. Je vais te donner une fonction que j'ai faite pour passer d'une matrice de rotation à un vecteur cartésien (c'est à dire composé de x, y, z, Rx, Ry et Rz):
/** @brief Convert the matrix to point. @param l_Convention Represent the convention of the point. @return The resulting point . */ GPoint GMatrix::toPoint(GPoint::Convention l_Convention) const { GPoint Point; switch(l_Convention) { case GPoint::BRYANT: Point.Rx = atan2( at(3,2) , at(3,3)); Point.Ry = atan2(-at(3,1) , sqrt(at(1,1)*at(1,1) + at(2,1)*at(2,1))); Point.Rz = atan2( at(2,1) , at(1,1)); if((Point.Ry <= PI/2.0+0.0001)&&(Point.Ry >= PI/2.0-0.0001)) {Point.Rx=0.0;Point.Rz = -atan2( at(1,2) , at(2,2));} if((Point.Ry >= -PI/2.0-0.0001)&&(Point.Ry <= -PI/2.0+0.0001)) {Point.Rx=0.0;Point.Rz = atan2(-at(1,2) , at(2,2));} Point.X = at(1,4); Point.Y = at(2,4); Point.Z = at(3,4); break; case GPoint::EULER_XYZ: Point.Rx = atan2(-at(2,3) , at(3,3)); Point.Ry = atan2( at(1,3) , sqrt(at(3,3)*at(3,3) + (-at(2,3))*(-at(2,3)))); Point.Rz = atan2(-at(1,2) , at(1,1)); if((Point.Ry <= PI/2.0+0.0001)&&(Point.Ry >= PI/2.0-0.0001)) {Point.Rx=0.0;Point.Rz = atan2( at(3,2) , at(2,2));} if((Point.Ry >= -PI/2.0-0.0001)&&(Point.Ry <= -PI/2.0+0.0001)) {Point.Rx=0.0;Point.Rz = atan2( -at(3,2) , at(2,2));} Point.X = at(1,4); Point.Y = at(2,4); Point.Z = at(3,4); break; case GPoint::EULER_ZYX: Point.Rx = atan2( at(3,2) , at(3,3)); Point.Ry = atan2(-at(3,1) , sqrt(at(1,1)*at(1,1) + at(2,1)*at(2,1))); Point.Rz = atan2( at(2,1) , at(1,1)); if((Point.Ry <= PI/2.0+0.0001)&&(Point.Ry >= PI/2.0-0.0001)) {Point.Rx=0.0;Point.Rz = -atan2( at(1,2) , at(2,2));} if((Point.Ry >= -PI/2.0-0.0001)&&(Point.Ry <= -PI/2.0+0.0001)) {Point.Rx=0.0;Point.Rz = atan2( -at(1,2) , at(2,2));} Point.X = at(1,4); Point.Y = at(2,4); Point.Z = at(3,4); break; case GPoint::THIRD_COLUMN: Point.Rx = at(3,2); Point.Ry = at(1,3); Point.Rz = at(2,1); Point.X = at(1,4); Point.Y = at(2,4); Point.Z = at(3,4); break; case GPoint::RPY: Point.Rx = atan2( at(2,1) , at(1,1)); Point.Ry = atan2(-at(3,1) , sqrt(at(1,1)*at(1,1) + at(2,1)*at(2,1))); Point.Rz = atan2( at(3,2) , at(3,3)); if((Point.Ry <= PI/2.0+0.0001)&&(Point.Ry >= PI/2.0-0.0001)) {Point.Rx=0.0;Point.Rz = atan2( at(1,2) , at(2,2));} if((Point.Ry >= -PI/2.0-0.0001)&&(Point.Ry <= -PI/2.0+0.0001)) {Point.Rx=0.0;Point.Rz = atan2(-at(1,2) , at(2,2));} Point.X = at(1,4); Point.Y = at(2,4); Point.Z = at(3,4); break; } Point.setConvention(l_Convention); return Point; }
Tous les at(i,j) sont équivalant à une matrice (double** at) si tu veux. Tu n'as qu'a reprendre les formules. Les "if" sont là pour gérer les singularités. Toutes ses conversions suivent les normes Euleriennes. RPY signifie Roll Pitch Yaw.
Et voilà, j'espère que ça t'aidera.
Hors ligne
Waow ! ça déchire.
bon je ne vous cacherez pas que mes connaissances sont proches de zero en math cela dit il n'est jamais trop tard pour apprendre.
j'ai pu me documenter sur sqrt(bon ok on l'apprend au cm2, mais pas en version anglaise ) et atan2(),
mais je ne comprend pas ce at() ? est-ce le lieu ?
Enfin en tout cas merci, ça fait du bien d'apprendre les bases.
Hors ligne
Le "at()" représente juste une méthode qui accède à ma matrice, soit at(1,2) veut dire le terme 12 de ma matrice, at(1,4) -> 14, at(2,2) -> 22:
11 12 13 | 14
21 22 23 | 24
31 32 33 | 34
---------------
41 42 43 | 44
Quand tu parles du lieu, je pense que tu veux dire la position x, y et z de l'objet, soit ce sont les termes 14, 24 et 34 qui sont respectivement x, y et z.
Bon courage dans ta quête des MATRICES.
Hors ligne
ok, non ça va pour une fois j'avais compris
il me reste plus qu'à étudier atan2 et l'affaire est dans le sac
thanks a lot !
Hors ligne
Ok désolé.
Sinon, atan2 représente la fonction inverse de la tangente mais en respectant les quatre quadrants. En gros:
http://fr.wikipedia.org/wiki/Atan2
De toute façon, si tu es en c++ ou c, math.h la contient.....
Hors ligne
ouai j'ai commencé à lire cette article, et au bout de quelques lignes, j'ai découvert un autre article sur les matrices de rotations http://fr.wikipedia.org/wiki/Matrices_de_rotation
Donc du coup c'est impecable, avec toutes ces ressources je devrais arriver à comprendre le pourquoi du comment
Hors ligne
Il me semble que les matrices 4x4 opengl et irrlicht ont pas la meme structure ( la translation est en derniere ligne pour irrlicht ).un fois le passage opengl->irrlicht fais tu peut utiliser les methodes d'irrlicht :
- mat.getTranslation ()
- mat.getRotation ()
- mat.getScale()
pr obtenir les vecteurs 3d position,rotation,scale.
Hors ligne
merci pour l'info, pour l'instant j'ai laissé codeblocks de coté pour rattraper mes lacunes en maths, on se moque pas mais je met les liens utiles pour les débutants de mon genre
http://fr.wikipedia.org/wiki/Fonction_t … 3%A9trique
http://fr.wikipedia.org/wiki/Rotation_vectorielle
Hors ligne
un petit tuyau :
ce qu'il faut connaitre pour faire de la prog3d:
-produit scalaire (usuel) , norme euclidienne
-produit vectoriel
-matrice ( au moins savoir s'en servir meme si comprendre le peu de théorie qu'il y a derriere c'est mieu )
-symetrie , projection , rotation, translation
-eventuellement la relation entre transformation et matrice.
-base vectorielle
Voici un bon site pour apprendre les maths/physique : www.sciences.ch
Hors ligne
cool firnafin, je vais épingler un topic avec les liens utiles
Hors ligne
Options | Liens officiels | Caractéristiques | Statistiques | Communauté |
---|---|---|---|---|
Corrections |
|
xhtml 1.0 css 2.1 Propulsé par FluxBB Traduit par FluxBB.fr |
882 membres 1429 sujets 11119 messages |
Dernier membre inscrit: LiseBuisson96 174 invités en ligne Aucun membre connecté RSS Feed |