Les deux matrices produits précédentes sont différentes
Par produit d'un vecteur vertical (0, a, 0) par la matrice Rx.Ry (rotation par rapport à l'axe Oy, puis par rapport à l'axe Ox), l'abscisse x obtenue est égale à 0 et donc conduit à un vecteur vertical à l'écran. | |
Par produit d'un vecteur vertical (0, a, 0) par la matrice Ry.Rx (rotation par rapport à l'axe Ox, puis par rapport à l'axe Oy), l'abscisse x obtenue est différente de 0 et donc conduit à un vecteur non vertical à l'écran. |
Le source : TD-Mathematiques2.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Avril 2001 */
/* Calculs mathematiques */
/* sur les transformations geometriques */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "ModuleCouleurs.h"
#include "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
#include "ModuleFont.h"
typedef float vecteur[4] ;
typedef float matrice[4][4] ;
#ifndef M_PI
#define M_PI 3.14159265F
#endif
static int question = 0;
float view_rotx = 0.0F;
float view_roty = 0.0F;
static GLfloat zoom = 3.0F;
static float px = 0.0F;
static float py = 0.0F;
static float pz = 0.0F;
static float ax = 0.0F;
static float ay = 0.0F;
static float vrx = 0.0F;
static float vry = 0.0F;
void initIdentite(matrice m) {
for ( int i = 0 ; i < 4 ; i++ )
for ( int j = 0 ; j < 4 ; j++ )
m[i][j] =( i != j ) ? 0.0F : 1.0F;
}
void initTranslation(matrice m,float dx,float dy,float dz) {
initIdentite(m);
m[0][3] = dx;
m[1][3] = dy;
m[2][3] = dz;
}
void initRotationX(matrice m,float a) {
initIdentite(m);
float cs =(float) cos(a*M_PI/180);
float sn =(float) sin(a*M_PI/180);
m[1][1] = m[2][2] = cs;
m[1][2] = -sn;
m[2][1] = sn;
}
void initRotationY(matrice m,float a) {
initIdentite(m);
float cs =(float) cos(a*M_PI/180);
float sn =(float) sin(a*M_PI/180);
m[0][0] = m[2][2] = cs;
m[0][2] = sn;
m[2][0] = -sn;
}
void initRotationZ(matrice m,float a) {
initIdentite(m);
float cs =(float) cos(a*M_PI/180);
float sn =(float) sin(a*M_PI/180);
m[0][0] = m[1][1] = cs;
m[0][1] = -sn;
m[1][0] = sn;
}
void initScale(matrice m,float rx,float ry,float rz) {
initIdentite(m);
m[0][0] = rx;
m[1][1] = ry;
m[2][2] = rz;
}
void composition(matrice a,matrice b,matrice m) {
for ( int i = 0 ; i < 4 ; i++ )
for ( int j = 0 ; j < 4 ; j++ ) {
m[i][j] = 0.0F ;
for ( int k = 0 ; k < 4 ; k++ )
m[i][j] += a[i][k]*b[k][j] ; }
}
void produit(matrice a,vecteur b,vecteur v) {
for ( int i = 0 ; i < 4 ; i++ ) {
v[i] = 0.0F ;
for ( int j = 0 ; j < 4 ; j++ )
v[i] += a[i][j]*b[j] ; }
}
void printf(matrice m) {
for ( int i = 0 ; i < 4 ; i++ ) {
for ( int j = 0 ; j < 4 ; j++ )
printf("%7.3f",m[i][j]);
printf("\n"); }
printf("\n");
}
void solidCube(float px,float py,float pz,matrice m,float rx,float ry,float rz) {
matrice s;
initScale(s,rx,ry,rz);
matrice tr;
initTranslation(tr,px,py,pz);
matrice aux;
composition(m,tr,aux);
matrice trans;
composition(aux,s,trans);
GLfloat vdata[8][3] = {
{ 0.5, 0.5,-0.5},{ 0.5,-0.5,-0.5},
{-0.5,-0.5,-0.5},{-0.5, 0.5,-0.5},
{ 0.5, 0.5, 0.5},{ 0.5,-0.5, 0.5},
{-0.5,-0.5, 0.5},{-0.5, 0.5, 0.5}} ;
int i;
for ( i = 0 ; i < 8 ; i++ ) {
vecteur v = { vdata[i][0],vdata[i][1],vdata[i][2],1.0F };
vecteur nv;
produit(trans,v,nv);
vdata[i][0] = nv[0];
vdata[i][1] = nv[1];
vdata[i][2] = nv[2]; }
static GLint t[6][4] = {
{0,1,2,3},
{7,6,5,4},
{5,6,2,1},
{0,3,7,4},
{6,7,3,2},
{4,5,1,0}} ;
GLfloat ndata[6][3] = {
{ 0.0, 0.0,-1.0},
{ 0.0, 0.0, 1.0},
{ 0.0,-1.0, 0.0},
{ 0.0, 1.0, 0.0},
{-1.0, 0.0, 0.0},
{ 1.0, 0.0, 0.0}} ;
for ( i = 0 ; i < 6 ; i++ ) {
vecteur v = { ndata[i][0],ndata[i][1],ndata[i][2],0.0F };
vecteur nv;
produit(trans,v,nv);
ndata[i][0] = nv[0];
ndata[i][1] = nv[1];
ndata[i][2] = nv[2]; }
for ( i = 0 ; i < 6 ; i++ ) {
glBegin(GL_QUADS) ;
glNormal3fv(&ndata[i][0]);
glVertex3fv(vdata[t[i][0]]);
glVertex3fv(vdata[t[i][1]]);
glVertex3fv(vdata[t[i][2]]);
glVertex3fv(vdata[t[i][3]]);
glEnd() ; }
}
void solidCube(float px,float py,float pz,float rx,float ry,float rz) {
GLfloat vdata[8][3] = {
{ 0.5, 0.5,-0.5},{ 0.5,-0.5,-0.5},
{-0.5,-0.5,-0.5},{-0.5, 0.5,-0.5},
{ 0.5, 0.5, 0.5},{ 0.5,-0.5, 0.5},
{-0.5,-0.5, 0.5},{-0.5, 0.5, 0.5}} ;
int i;
for ( i = 0 ; i < 8 ; i++ ) {
vdata[i][0] *= rx;
vdata[i][0] += px;
vdata[i][1] *= ry;
vdata[i][1] += py;
vdata[i][2] *= rz;
vdata[i][2] += pz; }
static GLint t[6][4] = {
{0,1,2,3},
{7,6,5,4},
{5,6,2,1},
{0,3,7,4},
{6,7,3,2},
{4,5,1,0}} ;
static GLfloat ndata[6][3] = {
{ 0.0, 0.0,-1.0},
{ 0.0, 0.0, 1.0},
{ 0.0,-1.0, 0.0},
{ 0.0, 1.0, 0.0},
{-1.0, 0.0, 0.0},
{ 1.0, 0.0, 0.0}} ;
for ( i = 0 ; i < 6 ; i++ ) {
glBegin(GL_QUADS) ;
glNormal3fv(&ndata[i][0]);
glVertex3fv(vdata[t[i][0]]);
glVertex3fv(vdata[t[i][1]]);
glVertex3fv(vdata[t[i][2]]);
glVertex3fv(vdata[t[i][3]]);
glEnd() ; }
}
void question1() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glPushMatrix();
manipulateurSouris();
manipulateurClavier();
glRotatef(view_rotx,1.0F,0.0F,0.0F);
glRotatef(view_roty,0.0F,1.0F,0.0F);
glScalef(zoom,zoom,zoom);
matrice rx,ry,rxy,ryx;
initRotationX(rx,ax);
initRotationY(ry,ay);
composition(rx,ry,rxy);
composition(ry,rx,ryx);
glPushMatrix();
solidCube(px,py,pz,0.5F,0.4F,0.3F);
glPopMatrix();
glPushMatrix();
solidCube(px,py,pz,rxy,0.5F,0.4F,0.3F);
glPopMatrix();
glPushMatrix();
solidCube(px,py,pz,ryx,0.5F,0.4F,0.3F);
glPopMatrix();
glPopMatrix();
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
float xmin = getXmin();
float ymax = getYmax();
float tpix = getTaillePixel();
setAntialiased(1);
setBold(1);
setEcartementCaracteres(15.0F);
glPushMatrix();
glColor4fv(couleurBlanc());
strokeOutput(xmin,ymax-16*tpix,0.65F,"Cube initial : %f %f %f",px,py,pz);
matrice tr;
initTranslation(tr,px,py,pz);
matrice trans;
composition(rxy,tr,trans);
strokeOutput(xmin,ymax-36*tpix,0.65F,"Rx : %f, Ry : %f",ax,ay);
{ vecteur v = {0.0F,0.0F,0.0F,1.0F};
vecteur vt;
produit(trans,v,vt);
strokeOutput(xmin,ymax-56*tpix,0.65F,"Cube par Ry puis Rx : %f %f %f",vt[0],vt[1],vt[2]); }
composition(ryx,tr,trans);
{ vecteur v = {0.0F,0.0F,0.0F,1.0F};
vecteur vt;
produit(trans,v,vt);
strokeOutput(xmin,ymax-76*tpix,0.65F,"Cube par Rx puis Ry : %f %f %f",vt[0],vt[1],vt[2]); }
glPopMatrix();
setAntialiased(0);
setBold(0);
setEcartementCaracteres(0.0F);
}
void fleche(float dx,float dy,float dz,float cr,float cl) {
glPushMatrix();
glBegin(GL_LINES);
glVertex3f(0.0F,0.0F,0.0F);
glVertex3f(dx,dy,dz);
glEnd();
glPopMatrix();
glPushMatrix();
double d = pow((double) (dx*dx+dy*dy+dz*dz),0.5);
dx /= d;
dy /= d;
dz /= d;
double a = acos(dz) * 360 / 3.14159;
glRotatef(a/2,-dy,dx,0);
glTranslatef(0.0F,0.0F,(float) d);
glutSolidCone(cr,cl,10,10);
glPopMatrix();
}
void question2() {
matrice rx,ry,rxy,ryx;
initRotationX(rx,vrx);
initRotationY(ry,vry);
composition(rx,ry,rxy);
composition(ry,rx,ryx);
glEnable(GL_DEPTH_TEST);
glPushMatrix();
glScalef(zoom,zoom,zoom);
glPushMatrix();
glColor4fv(couleurJaune());
glTranslatef(0.0F,-0.5F,0.0F);
fleche(0.0F,1.0F,0.0F,0.05F,0.2F);
glPopMatrix();
glColor4fv(couleurRouge());
glPushMatrix();
vecteur v1 = {0.0F,1.0F,0.0F,0.0F};
vecteur vt1;
produit(rxy,v1,vt1);
glTranslatef(-1.0F,-0.5F,0.0F);
fleche(vt1[0],vt1[1],vt1[2],0.05F,0.2F);
glPopMatrix();
glColor4fv(couleurBleu());
glPushMatrix();
vecteur v2 = {0.0F,1.0F,0.0F,0.0F};
vecteur vt2;
produit(ryx,v2,vt2);
glTranslatef(1.0F,-0.5F,0.0F);
fleche(vt2[0],vt2[1],vt2[2],0.05F,0.2F);
glPopMatrix();
glPopMatrix();
glDisable(GL_DEPTH_TEST);
float xmin = getXmin();
float ymax = getYmax();
float tpix = getTaillePixel();
setAntialiased(1);
setBold(1);
setEcartementCaracteres(15.0F);
glPushMatrix();
glColor4fv(couleurBlanc());
strokeOutput(xmin,ymax-16*tpix,0.65F,"Rx : %f, Ry : %f",vrx,vry);
glColor4fv(couleurJaune());
strokeOutput(xmin,ymax-36*tpix,0.65F,"Vecteur original : 0.0000 1.0000 0.0000");
glColor4fv(couleurRouge());
strokeOutput(xmin,ymax-56*tpix,0.65F,"Ry puis Rx : %f %f %f",vt1[0],vt1[1],vt1[2]);
glColor4fv(couleurBleu());
strokeOutput(xmin,ymax-76*tpix,0.65F,"Rx puis Ry : %f %f %f",vt2[0],vt2[1],vt2[2]);
glPopMatrix();
setAntialiased(0);
setBold(0);
setEcartementCaracteres(0.0F);
}
void display() {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glPushMatrix();
switch ( question ) {
case 0 : question1();
break;
case 1 : question2();
break; }
glPopMatrix();
glutSwapBuffers();
glFlush();
}
void key(unsigned char key,int x,int y) {
switch ( key ) {
case '1' : if ( question == 1 )
vrx -= 1.0F;
else
ax -= 1.0F;
break;
case '7' : if ( question == 1 )
vrx += 1.0F;
else
ax += 1.0F;
break;
case '2' : if ( question == 1 )
vry -= 1.0F;
else
ay -= 1.0F;
break;
case '8' : if ( question == 1 )
vry += 1.0F;
else
ay += 1.0F;
break;
case 'x' : px -= 0.05F;
break;
case 'X' : px += 0.05F;
break;
case 'y' : py -= 0.05F;
break;
case 'Y' : py += 0.05F;
break;
case 'z' : pz -= 0.05F;
break;
case 'Z' : pz += 0.05F;
break;
case 45 : zoom /= 1.02F;
break;
case 43 : zoom *= 1.02F;
break;
case 0x0D : question = (question+1)%2;
break;
case '\033' : exit(0);
break ; }
glutPostRedisplay();
}
static void special(int k,int x,int y) {
switch (k) {
case GLUT_KEY_UP : if ( question == 1 )
vrx += 1.0F;
else
view_rotx += 2.0;
break;
case GLUT_KEY_DOWN : if ( question == 1 )
vrx -= 1.0F;
else
view_rotx -= 2.0;
break;
case GLUT_KEY_LEFT : if ( question == 1 )
vry += 1.0F;
else
view_roty += 2.0;
break;
case GLUT_KEY_RIGHT : if ( question == 1 )
vry -= 1.0F;
else
view_roty -= 2.0;
break; }
glutPostRedisplay();
}
void myInit(void) {
GLfloat mat_shininess[] = { 50.0 };
GLfloat light0_position[] = { 1.0,1.0,1.0,0.0 };
GLfloat light1_position[] = { -1.0,1.0,1.0,0.0 };
GLfloat light2_position[] = { 1.0,-1.0,1.0,0.0 };
glMaterialfv(GL_FRONT,GL_SPECULAR,couleurBlanc());
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurRouge());
glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurVert());
glLightfv(GL_LIGHT2,GL_DIFFUSE,couleurBleu());
glLightfv(GL_LIGHT0,GL_POSITION,light0_position);
glLightfv(GL_LIGHT1,GL_POSITION,light1_position);
glLightfv(GL_LIGHT2,GL_POSITION,light2_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glDepthFunc(GL_LESS);
glEnable(GL_NORMALIZE);
glEnable(GL_AUTO_NORMAL);
glShadeModel(GL_SMOOTH);
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutCreateWindow("Mathematiques 2");
myInit();
creationMenuBasique();
setParametresOrthoBasique(-6.0,6.0,-6.0,6.0,-500.0,500.0);
setManipulateurDistance(1.0F);
glutReshapeFunc(reshapeOrthoBasique);
glutMotionFunc(motionBasique);
glutMouseFunc(sourisBasique);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}