#1 

20-01-2010 12:54:07

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


#2 

20-01-2010 16:28:33

Hawk
Membres
Date d'inscription:
Messages: 91
IP: 91.103.40.50
Courriel  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


#3 

20-01-2010 20:25:52

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


#4 

20-01-2010 21:06:58

Gehogor
Membres
Avatar de Gehogor
Date d'inscription:
Messages: 130
IP: 86.72.254.176
Courriel

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.


Et hop... wink

Hors ligne


#5 

21-01-2010 01:00:46

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


#6 

21-01-2010 08:40:50

Hawk
Membres
Date d'inscription:
Messages: 91
IP: 91.103.40.50
Courriel  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


#7 

21-01-2010 11:51:59

Gehogor
Membres
Avatar de Gehogor
Date d'inscription:
Messages: 130
IP: 132.167.34.106
Courriel

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.


Et hop... wink

Hors ligne


#8 

21-01-2010 15:26:16

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


#9 

21-01-2010 15:40:11

Gehogor
Membres
Avatar de Gehogor
Date d'inscription:
Messages: 130
IP: 132.167.34.106
Courriel

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


#10 

21-01-2010 16:26:07

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


#11 

21-01-2010 17:28:17

Gehogor
Membres
Avatar de Gehogor
Date d'inscription:
Messages: 130
IP: 86.72.254.176
Courriel

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


#12 

21-01-2010 21:05:44

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


#13 

22-01-2010 13:39:04

firnafin
Membres
Avatar de firnafin
Date d'inscription:
Messages: 150
IP: 93.9.158.129
Courriel

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


#14 

22-01-2010 14:39:44

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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_trigonom%C3%A9trique
http://fr.wikipedia.org/wiki/Rotation_vectorielle


Hors ligne


#15 

22-01-2010 15:44:24

firnafin
Membres
Avatar de firnafin
Date d'inscription:
Messages: 150
IP: 93.9.158.129
Courriel

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


#16 

22-01-2010 18:49:13

nico
Administrateurs
Avatar de nico
Date d'inscription:
Messages: 563
IP: 82.232.128.163
Courriel

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


Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
159 invités en ligne
membre en ligne: -
RSS Feed