matrices de rotation

matrices de rotation - Programmation

Marsh Posté le 16-04-2001 à 11:42:06    

je cherche a faire une (ou plusieurs) fonction
utilisant des matrices de rotation ...
je les avait faites moi meme mais apperement c est pas bon
 
alors si qqun pouvais me les fournir de maniere utilisable en C (ou alors la methode)
une petite fonction qui prend trois coordonnees en parametre
et qui les renvoie une fois modifiee
 
rappel :  
Rx =
 1,0,0
 0,cos(@x), -sin(@x)
 0, sin(@x), cos(@x)
 
Rz =  
 cos(@y), 0, sin(@y)
 0, 1, 0
 -sin(@y), 0, cos(@y)
 
Rz =
 cos(@z), -sin(@z), 0
 sin(@z), cos(@z), 0
 0, 0, 1

Reply

Marsh Posté le 16-04-2001 à 11:42:06   

Reply

Marsh Posté le 16-04-2001 à 14:01:51    

deja si tu l'as tape comme ca c'est mal parti:
Rz =  :gun:  
cos(@y), 0, sin(@y)  
0, 1, 0  
-sin(@y), 0, cos(@y)  
 
sinon pas de reponse pour l'instant !


---------------
VENTE DE MATOS INFO .. Version 2
Reply

Marsh Posté le 16-04-2001 à 14:17:51    

bien sur c est Ry et pas Rz ...vous l aurez compris :D
mais ce n est pas ca le probleme parcequ il est correctement
note dans le prog.

Reply

Marsh Posté le 16-04-2001 à 16:04:32    

Hello,
 
Moi je dirai qu'un truc du genre ca devrait marche mais sans certitude :
void transfo(int x,int y,int z)
{
int trx,try,trz;
 
trx=x+y*cos(x)-y*sin(x)+z*sin(x)+cos(x)*z;
try=x*cos(y)+z*sin(y)+y-z*sin(y)+cos(y)*z;
trz=x*cos(z)-x*sin(z)+y*cos(z)+y*sin(z)+z
x=trx;
y=try;
z=trz;
}

Reply

Marsh Posté le 16-04-2001 à 16:58:52    

Euh là c'est vraiment n'importe quoi :D

Reply

Marsh Posté le 16-04-2001 à 17:23:34    

Oui la multiplication des matrices n'a jamais ete mon fort :  
Peut etre que ceci est plus coherent si c'est pas ca alors j'irai dormir promis :
Pour X :  
(a b c) * Rx  
je dirai donc que ca vaut x = a
                          y = b*cos(x) - c*sin x  
                          z = b*sin(x)+c*cos(x)
Je croise les doigts pour que ce soit ca

Reply

Marsh Posté le 16-04-2001 à 20:37:54    

tu me propose koa alors Verdoux ... ??

Reply

Marsh Posté le 16-04-2001 à 20:44:34    

cadeau ...
 
//---------------------------------------------------------------------------
#include <stdlib.h>
#include <math.h>
#include <time.h>
 
//---------------------------------------------------------------------------
// toutes les fonctions assembleur sont inutiliser en attente de la mise
// à jour de l'utilisation des variables
 
void Inversion_de_matrice(double* matrice,double* resultat);
void Multiplication_de_matrices_tt(double* matrice,double* matrice_,double* resultat);
void Multiplication_de_matrices_tp(double* matrice,double* matrice_,double* resultat,int nb_point);
double* Matrice_Id(void);
double* Matrice_Trs(double Tx,double Ty,double Tz);
double* Matrice_Rx(double angle);
double* Matrice_Ry(double angle);
double* Matrice_Rz(double angle);
double* Matrice_Rn(double nx,double ny,double nz,double angle);
 
// variables temporaires pour l'inversion
double td=0;               // determinant
double t[6]={0,0,0,0,0,0};
double tmp[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
// calcul de sinus et cosinus
double  angle=0;
double  sinus=0;
double  cosinus=0;
 
// mesure de temps en secondes
/*  time_t td=time(NULL);
  time_t tf=time(NULL);
  int ecart=tf-td;
  IntToStr(ecart);*/
 
//---------------------------------------------------------------------------
// inversion de matrices : matrice de taille 4x4 exclusivement
void Inversion_de_matrice(double* matrice,double* resultat) {
 
 // calcul des cofacteurs de la ligne 1
  t[0]=matrice[10]*matrice[15] - matrice[14]*matrice[11];
  t[1]=matrice[9]*matrice[15] - matrice[13]*matrice[11];
  t[2]=matrice[9]*matrice[14] - matrice[13]*matrice[10];
  t[3]=matrice[8]*matrice[15] - matrice[12]*matrice[11];
  t[4]=matrice[8]*matrice[14] - matrice[12]*matrice[10];
  t[5]=matrice[8]*matrice[13] - matrice[12]*matrice[9];
 
  tmp[0]=matrice[5]*t[0] - matrice[6]*t[1] + matrice[7]*t[2];
  tmp[1]=matrice[4]*t[0] - matrice[6]*t[3] + matrice[7]*t[4];
  tmp[2]=matrice[4]*t[1] - matrice[5]*t[3] + matrice[7]*t[5];
  tmp[3]=matrice[4]*t[2] - matrice[5]*t[4] + matrice[6]*t[5];
 
 // calcul du determinant
  td=matrice[0]*tmp[0] - matrice[1]*tmp[1] + matrice[2]*tmp[2] - matrice[3]*tmp[3];
//  Form1->Edit1->Text=FloatToStr(td);
 // test du determiant : si non nul on continue
  if (td==0) {
    resultat[ 0]=1;
    resultat[ 1]=0;
    resultat[ 2]=0;
    resultat[ 3]=0;
    resultat[ 4]=0;
    resultat[ 5]=1;
    resultat[ 6]=0;
    resultat[ 7]=0;
    resultat[ 8]=0;
    resultat[ 9]=0;
    resultat[10]=1;
    resultat[11]=0;
    resultat[12]=0;
    resultat[13]=0;
    resultat[14]=0;
    resultat[15]=1;
    return;
    }
 
 // calcul des cofacteurs de la ligne 2
  tmp[4]=matrice[1]*t[0] - matrice[2]*t[1] + matrice[3]*t[2];
  tmp[5]=matrice[0]*t[0] - matrice[2]*t[3] + matrice[3]*t[4];
  tmp[6]=matrice[0]*t[1] - matrice[1]*t[3] + matrice[3]*t[5];
  tmp[7]=matrice[0]*t[2] - matrice[1]*t[4] + matrice[2]*t[5];
 
 // calcul des cofacteurs de la ligne 3
  t[0]=matrice[2]*matrice[7] - matrice[6]*matrice[3];
  t[1]=matrice[1]*matrice[7] - matrice[5]*matrice[3];
  t[2]=matrice[1]*matrice[6] - matrice[5]*matrice[2];
  t[3]=matrice[0]*matrice[7] - matrice[4]*matrice[3];
  t[4]=matrice[0]*matrice[6] - matrice[4]*matrice[2];
  t[5]=matrice[0]*matrice[5] - matrice[4]*matrice[1];
 
  tmp[8] =matrice[13]*t[0] - matrice[14]*t[1] + matrice[15]*t[2];
  tmp[9] =matrice[12]*t[0] - matrice[14]*t[3] + matrice[15]*t[4];
  tmp[10]=matrice[12]*t[1] - matrice[13]*t[3] + matrice[15]*t[5];
  tmp[11]=matrice[12]*t[2] - matrice[13]*t[4] + matrice[14]*t[5];
 
 // calcul des cofacteurs de la ligne 4
  tmp[12]=matrice[9]*t[0] - matrice[10]*t[1] + matrice[11]*t[2];
  tmp[13]=matrice[8]*t[0] - matrice[10]*t[3] + matrice[11]*t[4];
  tmp[14]=matrice[8]*t[1] - matrice[9]*t[3] + matrice[11]*t[5];
  tmp[15]=matrice[8]*t[2] - matrice[9]*t[4] + matrice[10]*t[5];
 
 // inversion
  td=1/td;
  resultat[0]=  tmp[0]*td;
  resultat[1]= -tmp[4]*td;
  resultat[2]=  tmp[8]*td;
  resultat[3]= -tmp[12]*td;
  resultat[4]= -tmp[1]*td;
  resultat[5]=  tmp[5]*td;
  resultat[6]= -tmp[9]*td;
  resultat[7]=  tmp[13]*td;
  resultat[8]=  tmp[2]*td;
  resultat[9]= -tmp[6]*td;
  resultat[10]= tmp[10]*td;
  resultat[11]=-tmp[14]*td;
  resultat[12]=-tmp[3]*td;
  resultat[13]= tmp[7]*td;
  resultat[14]=-tmp[11]*td;
  resultat[15]= tmp[15]*td;
 // fin
}
//---------------------------------------------------------------------------
// multiplication de matrices : matrices de taille 4x4 exclusivement
// matrice projective * matrice projective : 4x4 * 4x4
void Multiplication_de_matrices_tt(double* matrice,double* matrice_,double* resultat) {
 // variables temporaires
 
 // multiplication
  resultat[ 0]=matrice[ 0]*matrice_[ 0] + matrice[ 1]*matrice_[ 4] + matrice[ 2]*matrice_[ 8] + matrice[ 3]*matrice_[12];
  resultat[ 4]=matrice[ 4]*matrice_[ 0] + matrice[ 5]*matrice_[ 4] + matrice[ 6]*matrice_[ 8] + matrice[ 7]*matrice_[12];
  resultat[ 8]=matrice[ 8]*matrice_[ 0] + matrice[ 9]*matrice_[ 4] + matrice[10]*matrice_[ 8] + matrice[11]*matrice_[12];
  resultat[12]=matrice[12]*matrice_[ 0] + matrice[13]*matrice_[ 4] + matrice[14]*matrice_[ 8] + matrice[15]*matrice_[12];
  resultat[ 1]=matrice[ 0]*matrice_[ 1] + matrice[ 1]*matrice_[ 5] + matrice[ 2]*matrice_[ 9] + matrice[ 3]*matrice_[13];
  resultat[ 5]=matrice[ 4]*matrice_[ 1] + matrice[ 5]*matrice_[ 5] + matrice[ 6]*matrice_[ 9] + matrice[ 7]*matrice_[13];
  resultat[ 9]=matrice[ 8]*matrice_[ 1] + matrice[ 9]*matrice_[ 5] + matrice[10]*matrice_[ 9] + matrice[11]*matrice_[13];
  resultat[13]=matrice[12]*matrice_[ 1] + matrice[13]*matrice_[ 5] + matrice[14]*matrice_[ 9] + matrice[15]*matrice_[13];
  resultat[ 2]=matrice[ 0]*matrice_[ 2] + matrice[ 1]*matrice_[ 6] + matrice[ 2]*matrice_[10] + matrice[ 3]*matrice_[14];
  resultat[ 6]=matrice[ 4]*matrice_[ 2] + matrice[ 5]*matrice_[ 6] + matrice[ 6]*matrice_[10] + matrice[ 7]*matrice_[14];
  resultat[10]=matrice[ 8]*matrice_[ 2] + matrice[ 9]*matrice_[ 6] + matrice[10]*matrice_[10] + matrice[11]*matrice_[14];
  resultat[14]=matrice[12]*matrice_[ 2] + matrice[13]*matrice_[ 6] + matrice[14]*matrice_[10] + matrice[15]*matrice_[14];
  resultat[ 3]=matrice[ 0]*matrice_[ 3] + matrice[ 1]*matrice_[ 7] + matrice[ 2]*matrice_[11] + matrice[ 3]*matrice_[15];
  resultat[ 7]=matrice[ 4]*matrice_[ 3] + matrice[ 5]*matrice_[ 7] + matrice[ 6]*matrice_[11] + matrice[ 7]*matrice_[15];
  resultat[11]=matrice[ 8]*matrice_[ 3] + matrice[ 9]*matrice_[ 7] + matrice[10]*matrice_[11] + matrice[11]*matrice_[15];
  resultat[15]=matrice[12]*matrice_[ 3] + matrice[13]*matrice_[ 7] + matrice[14]*matrice_[11] + matrice[15]*matrice_[15];
}
//---------------------------------------------------------------------------
// multiplication de matrices : matrices de taille 4x4 exclusivement
// matrice projective * matrice de point :
// matrice  : 4x4
// matrice_ : 4xn
// resultat : 4xn
void Multiplication_de_matrices_tp(double* matrice,double* matrice_,double* resultat,int nb_point) {
 // variables temporaires
  int tmp0=0;
  int tmp1=1;
  int tmp2=2;
  int tmp3=3;
 
 // multiplication
  for (int i=0;i<nb_point;i++) {
    resultat[tmp0]=matrice[ 0]*matrice_[tmp0] + matrice[ 1]*matrice_[tmp1] + matrice[ 2]*matrice_[tmp2] + matrice[ 3]*matrice_[tmp3];
    resultat[tmp1]=matrice[ 4]*matrice_[tmp0] + matrice[ 5]*matrice_[tmp1] + matrice[ 6]*matrice_[tmp2] + matrice[ 7]*matrice_[tmp3];
    resultat[tmp2]=matrice[ 8]*matrice_[tmp0] + matrice[ 9]*matrice_[tmp1] + matrice[10]*matrice_[tmp2] + matrice[11]*matrice_[tmp3];
    resultat[tmp3]=matrice[12]*matrice_[tmp0] + matrice[13]*matrice_[tmp1] + matrice[14]*matrice_[tmp2] + matrice[15]*matrice_[tmp3];
    tmp0=tmp0+4;
    tmp1=tmp1+4;
    tmp2=tmp2+4;
    tmp3=tmp3+4;
    }
}
//---------------------------------------------------------------------------
// retourne la matrice projective identité
double* Matrice_Id(void) {
  double* resultat=(double*)malloc(sizeof(double)*16);
   
  resultat[ 0]=1;
  resultat[ 1]=0;
  resultat[ 2]=0;
  resultat[ 3]=0;
  resultat[ 4]=0;
  resultat[ 5]=1;
  resultat[ 6]=0;
  resultat[ 7]=0;
  resultat[ 8]=0;
  resultat[ 9]=0;
  resultat[10]=1;
  resultat[11]=0;
  resultat[12]=0;
  resultat[13]=0;
  resultat[14]=0;
  resultat[15]=1;
 
 // fin
  return(resultat);
}
//---------------------------------------------------------------------------
// retourne la matrice projective translation
double* Matrice_Trs(double Tx,double Ty,double Tz) {
  double* resultat=(double*)malloc(sizeof(double)*16);
 
  resultat[ 0]=1;
  resultat[ 1]=0;
  resultat[ 2]=0;
  resultat[ 3]=Tx;
  resultat[ 4]=0;
  resultat[ 5]=1;
  resultat[ 6]=0;
  resultat[ 7]=Ty;
  resultat[ 8]=0;
  resultat[ 9]=0;
  resultat[10]=1;
  resultat[11]=Tz;
  resultat[12]=0;
  resultat[13]=0;
  resultat[14]=0;
  resultat[15]=1;
 
 // fin
  return(resultat);
}
//---------------------------------------------------------------------------
// retourne la matrice projective de la rotation sur x
double* Matrice_Rx(double angle) {
  double* resultat=(double*)malloc(sizeof(double)*16);
 
  asm {
    fld     [angle]
    fsincos
    fstp    [cosinus]
    fstp    [sinus]
    }
 
  resultat[ 0]=1;
  resultat[ 1]=0;
  resultat[ 2]=0;
  resultat[ 3]=0;
  resultat[ 4]=0;
  resultat[ 5]=cosinus;
  resultat[ 6]=-sinus;
  resultat[ 7]=0;
  resultat[ 8]=0;
  resultat[ 9]=sinus;
  resultat[10]=cosinus;
  resultat[11]=0;
  resultat[12]=0;
  resultat[13]=0;
  resultat[14]=0;
  resultat[15]=1;
 
 // fin
  return(resultat);
}
//---------------------------------------------------------------------------
// retourne la matrice projective de la rotation sur y
double* Matrice_Ry(double angle) {
  double* resultat=(double*)malloc(sizeof(double)*16);
 
  asm {
    fld     [angle]
    fsincos
    fstp    [cosinus]
    fstp    [sinus]
    }
 
  resultat[ 0]=cosinus;
  resultat[ 1]=0;
  resultat[ 2]=sinus;
  resultat[ 3]=0;
  resultat[ 4]=0;
  resultat[ 5]=1;
  resultat[ 6]=0;
  resultat[ 7]=0;
  resultat[ 8]=-sinus;
  resultat[ 9]=0;
  resultat[10]=cosinus;
  resultat[11]=0;
  resultat[12]=0;
  resultat[13]=0;
  resultat[14]=0;
  resultat[15]=1;
 
 // fin
  return(resultat);
}
//---------------------------------------------------------------------------
// retourne la matrice projective de la rotation sur z
double* Matrice_Rz(double angle) {
  double* resultat=(double*)malloc(sizeof(double)*16);
 
  asm {
    fld     [angle]
    fsincos
    fstp    [cosinus]
    fstp    [sinus]
    }
 
  resultat[ 0]=cosinus;
  resultat[ 1]=-sinus;
  resultat[ 2]=0;
  resultat[ 3]=0;
  resultat[ 4]=sinus;
  resultat[ 5]=cosinus;
  resultat[ 6]=0;
  resultat[ 7]=0;
  resultat[ 8]=0;
  resultat[ 9]=0;
  resultat[10]=1;
  resultat[11]=0;
  resultat[12]=0;
  resultat[13]=0;
  resultat[14]=0;
  resultat[15]=1;
 
 // fin
  return(resultat);
}
//---------------------------------------------------------------------------

 

[edit]--Message édité par darkoli--[/edit]

Reply

Marsh Posté le 16-04-2001 à 20:55:17    

voila, il ya toutes les fonctions de bases pour obtenir les matrices de rotations sur x,y et z. Ensuite il suffit de les multiplier avec la fonction Multiplication_de_matrices_tt(double* matrice,double* matrice_,double* resultat).
 
exemple :  
  faire une rotation sur x, puis sur y puis sur z.
  double* mx,my,mz;  
  double  tmp[16];
  double  resultat[16];
 
  mx=Matrice_Rx(angle en radian);
  my=Matrice_Ry(angle en radian);
  mz=Matrice_Rz(angle en radian);
 
  Multiplication_de_matrices_tt(mx,my,tmp);
  Multiplication_de_matrices_tt(tmp,mz,resultat);
 
 // la matrice resultat contient mx*my*mz  
 // attention l'ordre est important.
 
 // à la fin
  free(mx);
  free(my);
  free(mz);

Reply

Marsh Posté le 17-04-2001 à 01:59:33    

merci :D
ca s est de la reponse !!
 
je vais tester tout ca maintenant ...

Reply

Marsh Posté le 17-04-2001 à 01:59:33   

Reply

Marsh Posté le 17-04-2001 à 11:14:43    

pour le calcul du cosinus et du sinus j'utilise une partion de code en assembleur mais suivant le compilateur ca passe pas toujours bien (testé avec Borland c++ Builder)

Reply

Marsh Posté le 17-04-2001 à 11:25:04    

asm {
fld     [angle]  
fsincos  
fstp    [cosinus]  
fstp    [sinus]  
}  
 
=> c est koa ce truc louche ??
je comprend pas .... :(
 
avec CC ou GCC ca marche ??

Reply

Marsh Posté le 17-04-2001 à 11:31:45    

C'est pas plus simple d'utiliser un vecteur rotation ?

Reply

Marsh Posté le 17-04-2001 à 12:01:46    

remplace le truc louche par  
 
asm {
  ...
  }
 
devient
 
cosinus=cos(angle);
sinus=sin(angle);

Reply

Marsh Posté le 17-04-2001 à 12:02:34    

BENB a écrit a écrit :

C'est pas plus simple d'utiliser un vecteur rotation ?




 
qu'est ce que tu appeles un vecteur de rotation ? (un quaternion)

Reply

Marsh Posté le 17-04-2001 à 12:05:07    

ok ...je vois ...mais j ai un petit probleme ...mon prog est fais avec des matrices 3*3
 
tout le monde a l air de dire que c est plus simple avec des 4*4
je vois pas trop pourquoi ...
moi en tout cas moi ca m ennuie un peu ...
vas falloir que je convertisse ?

Reply

Marsh Posté le 17-04-2001 à 14:10:04    

les matrices 4x4 ne font pas que les rotations :
 
  R  R  R  Tx
  R  R  R  Ty
  R  R  R  Tz
  Px Py Py H
 
attention : notation francaise !!! (la notation us est différente).
 
oui c'est vrai, en fait ta matrice 3x3 c'est les R.  
 
La colonne de droite (Tx,Ty, et Tz) c'est pour faire une translation.
 
La ligne en bas (Px,Py et Pz) c'est en générale pour les projections.
 
La case en bas à droite c'est pour les changement d'échelles.
 
En réalité les points que tu utilises non pas 3 mais 4 coordonnées : x,y,z et w avec w=1.
 
tant que tu ne fais que des rotations et des translations, tu n'as pas à te souccier de w.
 
Donc en notation francaise un point est un vecteur colonne de 4 coordonnées.
 
pour appliquer une transformation à un point, on fait :
 
        R R R T      X  
  M*P = R R R T   *  Y
        R R R T      Z
        P P P H      W
 
l'ordre est tres important.

Reply

Marsh Posté le 17-04-2001 à 14:30:25    

darkoli a écrit a écrit :

 
 
qu'est ce que tu appeles un vecteur de rotation ? (un quaternion)




 
c'est une Definition  
le vecteur rotation a pour direction l'axe de rotation, et pour norme la vitesse de rotation.
ca s'utilise avec un produit vectoriel...

Reply

Marsh Posté le 17-04-2001 à 14:46:54    

ok si tu le dis.
Tu as fait beaucoup d'études en math ? (c'est pas du tout mon cas)

Reply

Marsh Posté le 17-04-2001 à 14:58:19    

darkoli a écrit a écrit :

ok si tu le dis.
Tu as fait beaucoup d'études en math ? (c'est pas du tout mon cas)




Un peu...  mais ca c'est plus de la mecanique du solide
mais avec ce vecteur tu ne stockes que trois valeurs au lieu de 9 pour tes rotation.
Pour un solide en mouvement tu aurras un vecteur vitesse et un vecteur rotation qui s'appliquent au centre de gravite.

Reply

Marsh Posté le 17-04-2001 à 15:07:42    

donc c'est comme si on utilisait les quaternions (4 valeurs) avec une valeur de moins.  
 
Mais dans le cas ou on veut faire plus que des rotations : des translation et une projection perspective je crois que dans ce ca la matrice projective est mieux adaptée pour appliquer en une seule multiplication (de matrices) toutes ces operations.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed