#0 

20-01-2010 13:54:07

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

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


#1 

20-01-2010 17:28:33

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

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


#2 

20-01-2010 21:25:52

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

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


#3 

20-01-2010 22:06:58

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

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)


Et hop... wink

Hors ligne


#4 

21-01-2010 02:00:46

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

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


#5 

21-01-2010 09:40:50

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

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


#6 

21-01-2010 12:51:59

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

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

Code:

/**
@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.


Et hop... wink

Hors ligne


#7 

21-01-2010 16:26:16

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

Waow ! ça déchire.
bon je ne vous cacherez pas que mes connaissances sont proches de zero en math wink 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 tongue) 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


#8 

21-01-2010 16:40:11

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

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. wink


Et hop... wink

Hors ligne


#9 

21-01-2010 17:26:07

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

ok, non ça va pour une fois j'avais compris wink
il me reste plus qu'à étudier atan2 et l'affaire est dans le sac smile

thanks a lot !

Hors ligne


#10 

21-01-2010 18:28:17

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

Ok désolé. smile

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.....


Et hop... wink

Hors ligne


#11 

21-01-2010 22:05:44

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

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 wink

Hors ligne


#12 

22-01-2010 14:39:04

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

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


#13 

22-01-2010 15:39:44

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

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 wink

http://fr.wikipedia.org/wiki/Fonction_t … 3%A9trique
http://fr.wikipedia.org/wiki/Rotation_vectorielle

Hors ligne


#14 

22-01-2010 16:44:24

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

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


#15 

22-01-2010 19:49:13

nico
Webmaster
Date d'inscription: 07-08-2009
Messages: 563
Corrections: 9

cool firnafin, je vais épingler un topic avec les liens utiles smile

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
13 invités en ligne
Aucun membre connecté
RSS Feed