|
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. |
Aperçu |
---|
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 | ok si tu le dis.
Tu as fait beaucoup d'études en math ? (c'est pas du tout mon cas) |
BENB |
|
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 |
|
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 |