Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3779 connectés 

 


Dernière réponse
Sujet : matrices de rotation
darkoli 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.

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
darkoli 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.
BENB

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.

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

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

darkoli 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.
bemixam 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 ?
darkoli

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)

darkoli remplace le truc louche par  
 
asm {
  ...
  }
 
devient
 
cosinus=cos(angle);
sinus=sin(angle);
BENB C'est pas plus simple d'utiliser un vecteur rotation ?
bemixam asm {
fld     [angle]  
fsincos  
fstp    [cosinus]  
fstp    [sinus]  
}  
 
=> c est koa ce truc louche ??
je comprend pas .... :(
 
avec CC ou GCC ca marche ??
darkoli 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)
bemixam merci :D
ca s est de la reponse !!
 
je vais tester tout ca maintenant ...
darkoli 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);
darkoli 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]

bemixam tu me propose koa alors Verdoux ... ??
mystereetbouledegomme 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
verdoux Euh là c'est vraiment n'importe quoi :D
mystereetbouledegomme 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;
}
bemixam 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.
no1 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 !
bemixam 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

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)