Commentaires
Quelques soucis se posent à nous. Parmi eux, le premier est que le choix a été fait en TD de définir 4 attributs de type float pour la classe mère
CH3D. Or, notre but est d'implanter le produit matrice-vecteur dont la formule de calcul fait appel à une notation indicielle assimilable à l'utilisation
de tableaux et donc incompatible avec des attributs indépendants. Nous n'allons pas remettre en cause le choix réalisé et donc nous adapter en
redesignant la formule de calcul.
Pour le produit matrice-matrice, rien ne s'oppose à ce que la classe mère TG3D n'ait qu'un seul attribut de type matrice 4x4 de float.
L'utilisation directe de la formule de calcul est donc possible.
Un autre point auquel attention doit être porté est que, contrairement à la hiérarchie de classes CH3D, Pos3D et Dir3D pour laquelle la classe mère
CH3D est ininstanciable car sans constructeur, la hiérarchie TG3D, Tr3D, Rt3D et Sc3D doit être conçue pour que la classe TG3D permettent l'instanciation.
En effet, si aucune situation n'est envisagée qui conduirait à utiliser des objets CH3D, il est parfaitement naturel d'utiliser des objets
TG3D. Exemple : La composition d'une translation et d'une rotation n'étant généralement ni une translation ni une rotation, le résultat
obtenu sera donc une transformation géométrique.
Remarques : La composition de deux translations étant une translation, cette situation pourrait être prévue. La composition de deux rotations étant une rotation, cette situation pourrait être prévue. Il serait aussi possible de développer des méthodes permettant de tester si une TG3D est une translation ou si une TG3D est une rotation.
Les choix de développement suivants ont été réalisés :
Remarque : Le choix de faire des passages de paramètres par adresse ou par référence n'a pas de logique particulière dans les diverses méthodes développées. Le but est de tester différentes possibilités de développement.
Le programme principal vise à tester les différents constructeurs et méthodes développés puis à tester la réalisation de transformations géométriques d'une position ou d'une direction, et la composition de transformations géométriques.
Tous les fichiers sources : Mathematiques2.zip
Fichier source : Mathematiques2.cpp
static void print(char *message1,CH3D *ch,char *message2) {
printf("%s",message1);
ch->print();
printf("%s",message2);
}
static void print(char *message1,TG3D *tg,char *message2) {
printf("%s",message1);
tg->print();
printf("%s",message2);
}
int main(void) {
#if defined(WIN32) || defined(WIN64)
#if defined(_DEBUG)
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//_crtBreakAlloc = 120;
#endif
#endif
Tr3D tr1(1.8F,-3.4F,6.7F);
Tr3D *tr2 = new Tr3D(-4.5F,0.1F,3.2F);
Tr3D tr3;
Tr3D tr4(tr2);
printf("Translations\n\n");
print("tr1 : translation de vecteur (1.8,-3.4,6.7)\n",&tr1,"\n");
print("tr2 : translation de vecteur (-4.5,0.1,3.2)\n",tr2,"\n");
print("tr3 : translation identite\n",&tr3,"\n");
print("tr4 : translation clone de tr2\n",&tr4,"\n");
Dir3D axe1(-1.3F,2.3F,3.7F);
Rt3D rt1(45.0F,axe1);
Dir3D axe2(2.1F,-0.7F,1.8F);
Rt3D *rt2 = new Rt3D(30.0F,axe2);
Rt3D rt3;
Rt3D rt4(rt2);
Dir3D axe5(1.0F,0.0F,0.0F);
Rt3D *rt5 = new Rt3D(30.0,axe5);
printf("Rotations\n\n");
print("rt1 : rotation de 45.0 degres autour de l'axe (-1.3,2.3,3.7) passant par O\n",&rt1,"\n");
print("rt2 : rotation de 30.0 degres autour de l'axe (2.1,-0.7,1.8) passant par O\n",rt2,"\n");
print("rt3 : rotation identite\n",&rt3,"\n");
print("rt4 : rotation clone de rt2\n",&rt4,"\n");
print("rt5 : rotation de 30.0 degres autour de l'axe Ox\n",rt5,"\n");
Sc3D sc1(0.3F,1.3F,0.7F);
Sc3D *sc2 = new Sc3D(0.2F,0.9F,1.7F);
Sc3D sc3;
Sc3D sc4(sc2);
printf("Zooms\n\n");
print("sc1 : zoom de rapports (0.3,1.3,0.7)\n",&sc1,"\n");
print("sc2 : zoom de rapports (0.2,0.9,1.7)\n",sc2,"\n");
print("sc3 : zoom identite\n",&sc3,"\n");
print("sc4 : zoom de clone de sc2\n",&sc4,"\n");
Pos3D p1(2.0F,3.0F,4.0F);
Pos3D *p2 = new Pos3D(-1.1F,-0.2F,-2.3F);
Dir3D d1(2.0F,3.0F,4.0F);
Dir3D *d2 = new Dir3D(-1.1F,-0.2F,-2.3F);
print("tr1 : translation de vecteur (1.8,-3.4,6.7)\n",&tr1,"\n");
print("tr2 : translation de vecteur (-4.5,0.1,3.2)\n",tr2,"\n");
print("rt1 : rotation de 45.0 degres autour de l'axe (-1.3,2.3,3.7) passant par O\n",&rt1,"\n");
print("rt2 : rotation de 30.0 degres autour de l'axe (2.1,-0.7,1.8) passant par O\n",rt2,"\n");
printf("Transformations de positions 3D\n\n");
{ print("p1 : ",&p1,"\n");
Pos3D p = p1.mult(tr1);
print("p cree par translation tr1 de p1 : ",&p,"\n");
p = p.mult(tr2);
print("p modifie par translation tr2 : ",&p,"\n");
printf("\n"); }
{ print("p2 : ",p2,"\n");
Pos3D p = p2->mult(rt1);
print("p cree par rotation rt1 de p2 : ",&p,"\n");
p = p.mult(*rt2);
print("p modifie par rotation rt2 : ",&p,"\n");
printf("\n"); }
printf("Transformations de directions 3D\n\n");
{ print("d1 : ",&d1,"\n");
Dir3D d = d1.mult(tr1);
print("d cree par translation tr1 de d1 : ",&d,"\n");
d = d.mult(*tr2);
print("d modifie par translation tr2 : ",&d,"\n");
printf("\n"); }
{ print("d2 : ",d2,"\n");
Dir3D d = d2->mult(rt1);
print("d cree par rotation rt1 de d1 : ",&d,"\n");
d = d.mult(*rt2);
print("d modifie par rotation rt2 : ",&d,"\n");
printf("\n"); }
printf("Compositions de transformations geometriques\n\n");
TG3D tg1 = tr1.mult(rt1);
print("Composition de tr1 et rt1\n",&tg1,"\n");
TG3D tg2 = rt1.mult(tr1);
print("Composition de rt1 et tr1\n",&tg2,"\n");
printf("\n");
delete(sc2);
delete(rt5);
delete(rt2);
delete(tr2);
delete(p2);
delete(d2);
getchar();
return(0);
}
/* Mathematiques de l'informatique graphique */
/* Coordonnees homogenes en 3D */
/* */
/* Mars 2021 */
#ifndef ____CH3D____
#define ____CH3D____
class TG3D;
class Pos3D;
class Dir3D;
class CH3D {
public :
/* Coordonnees x, y et z */
float x;
float y;
float z;
private :
/* Coordonnee w */
float w;
protected :
/* Construit la position origine */
CH3D(void);
/* Construit la CH3D (xp,yp,zp,wp) */
CH3D(float xp,float yp,float zp,float wp);
/* Construit un clone de la CH3D ch */
CH3D(CH3D *ch);
/* Destructeur */
virtual ~CH3D(void);
protected :
/* Calcul de la transformation de this */
/* par la transformation geometrique tg */
/* et stockage du resultat dans ch */
void mult(const TG3D& tg,CH3D& ch);
public :
/* Methode d'affichage texte */
void print(void);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Coordonnees homogenes en 3D */
/* */
/* Mars 2021 */
#include <stdio.h>
#include "CH3D.h"
#include "Pos3D.h"
#include "Dir3D.h"
#include "TG3D.h"
/* Construit la position origine */
CH3D::CH3D(void) : x(0.0F),y(0.0F),z(0.0F),w(1.0F) {
}
/* Construit la CH3D (xp,yp,zp,wp) */
CH3D::CH3D(float xp, float yp, float zp, float wp) : x(xp),y(yp),z(zp),w(wp) {
}
/* Construit un clone de la CH3D ch */
CH3D::CH3D(CH3D *ch) : x(ch->x),y(ch->y),z(ch->z),w(ch->w) {
}
/* Destructeur */
CH3D::~CH3D(void) {
}
/* Calcul de la transformation de this */
/* par la transformation geometrique tg */
void CH3D::mult(const TG3D& tg,CH3D& ch) {
ch.x = this->x*tg.mat[0][0]+
this->y*tg.mat[0][1]+
this->z*tg.mat[0][2]+
this->w*tg.mat[0][3];
ch.y = this->x*tg.mat[1][0]+
this->y*tg.mat[1][1]+
this->z*tg.mat[1][2]+
this->w*tg.mat[1][3];
ch.z = this->x*tg.mat[2][0]+
this->y*tg.mat[2][1]+
this->z*tg.mat[2][2]+
this->w*tg.mat[2][3];
ch.w = this->x*tg.mat[3][0]+
this->y*tg.mat[3][1]+
this->z*tg.mat[3][2]+
this->w*tg.mat[3][3];
}
/* Methode d'affichage texte */
void CH3D::print(void) {
printf("%10.4f %10.4f %10.4f %10.4f",x,y,z,w);
}
/* Mathematiques de l'informatique graphique */
/* Position en 3D */
/* */
/* Mars 2021 */
#ifndef ____POS3D____
#define ____POS3D____
#include "CH3D.h"
class TG3D;
class Pos3D : public CH3D {
public :
/* Construit l'origine */
Pos3D(void);
/* Construit la position xp,yp,zp) */
Pos3D(float xp,float yp,float zp);
/* Construit un clone de la Pos3D p */
Pos3D(Pos3D *p);
/* Destructeur */
~Pos3D(void);
/* Calcul de la transformation de this */
/* par la transformation geometrique tg */
Pos3D mult(const TG3D& tg);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Position en 3D */
/* */
/* Mars 2021 */
#include "CH3D.h"
#include "Pos3D.h"
/* Construit l'origine */
Pos3D::Pos3D(void):CH3D() {
}
/* Construit la position (xp,yp,zp) */
Pos3D::Pos3D(float xp,float yp,float zp):CH3D(xp,yp,zp,1.0F) {
}
/* Construit un clone de la Pos3D p */
Pos3D::Pos3D(Pos3D *p):CH3D(p) {
}
/* Destructeur */
Pos3D::~Pos3D(void) {
}
/* Calcul de la transformation de this */
/* par la transformation geometrique tg */
Pos3D Pos3D::mult(const TG3D& tg) {
Pos3D d;
CH3D::mult(tg,d);
return d;
}
/* Mathematiques de l'informatique graphique */
/* Direction en 3D */
/* */
/* Mars 2021 */
#ifndef ____DIR3D____
#define ____DIR3D____
class Pos3D;
#include "CH3D.h"
class Dir3D : public CH3D {
public :
/* Construit le vecteur z */
Dir3D(void);
/* Construit la direction (x,y,z) */
Dir3D(float x,float y,float z);
/* Construit un clone de la Dir3D d */
Dir3D(Dir3D *d);
/* Construit la direction p1 p2 */
Dir3D(const Pos3D &p1,const Pos3D &p2);
/* Destructeur */
~Dir3D(void);
/* Methode de calcul de la norme de this */
float norme(void);
/* Calcul de la direction normalisée */
/* de this */
Dir3D normalize(void);
/* Calcul du produit scalaire */
/* de this et de la direction dir */
float operator*(const Dir3D& dir);
/* Calcul du produit vectoriel */
/* de this et de la direction dir */
Dir3D operator^(const Dir3D& dir);
/* Calcul de la transformation de this */
/* par la transformation geometrique tg */
Dir3D mult(const TG3D& tg);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Direction en 3D */
/* */
/* Mars 2021 */
#include <math.h>
#include "CH3D.h"
#include "Dir3D.h"
#include "Pos3D.h"
/* Constructeurs */
/* Construit le vecteur z */
Dir3D::Dir3D(void):CH3D(0.0F,0.0F,1.0F,0.0F) {
}
/* Construit la direction (xp,yp,zp) */
Dir3D::Dir3D(float xp,float yp,float zp):CH3D(xp,yp,zp,0.0F) {
}
/* Construit un clone de la Dir3D d */
Dir3D::Dir3D(Dir3D *d):CH3D(d) {
}
/* Construit la direction p1 p2 */
Dir3D::Dir3D(const Pos3D &p1,const Pos3D &p2) : CH3D(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z,0.0f) {
}
/* Destructeur */
Dir3D::~Dir3D(void) {
}
/* Methode de calcul de la norme de this */
float Dir3D::norme(void) {
return((float) sqrt(x*x+y*y+z*z));
}
/* Calcul de la direction normalisée de this */
Dir3D Dir3D::normalize(void) {
float norm = norme();
Dir3D res;
if (norm != 0.0F) {
res.x = x / norm;
res.y = y / norm;
res.z = z / norm; }
return res;
}
/* Calcul du produit scalaire */
/* de this et de la direction dir */
float Dir3D::operator*(const Dir3D& dir) {
return this->x*dir.x + this->y*dir.y + this->z * dir.z;
}
/* Calcul du produit vectoriel */
/* de this et de la direction dir */
Dir3D Dir3D::operator^(const Dir3D& dir) {
Dir3D res;
res.x = this->y * dir.z - dir.y * this->z;
res.y = this->z * dir.x - dir.z * this->x;
res.z = this->x * dir.y - dir.x * this->y;
return res;
}
/* Calcul de la transformation de this */
/* par la transformation geometrique tg */
Dir3D Dir3D::mult(const TG3D& tg) {
Dir3D d;
CH3D::mult(tg,d);
return d;
}
/* Mathematiques de l'informatique graphique */
/* Transformation geometrique 3D */
/* en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#ifndef ____TG3D____
#define ____TG3D____
class Pos3D;
class Dir3D;
class TG3D {
public :
/* Composantes */
float mat[4][4];
public :
/* Construit la TG3D identite */
TG3D(void);
/* Construit la TG3D clone de tg */
TG3D(TG3D *tg);
/* Destructeur */
virtual ~TG3D(void);
/* Calcul de la composition */
/* de la transformation geometrique this */
/* par la transformation geometrique rhs */
TG3D mult(const TG3D& rhs);
/* Calcul de la transformation */
/* de la Pos3D p */
/* par la transformation geometrique this */
Pos3D mult(Pos3D &p);
/* Calcul de la transformation */
/* de la Dir3D d */
/* par la transformation geometrique this */
Dir3D mult(Dir3D& d);
/* Methode d'affichage texte */
void print(void);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Transformation geometrique 3D */
/* en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "TG3D.h"
#include "CH3D.h"
#include "Pos3D.h"
#include "Dir3D.h"
/* Construit la TG3D identite */
TG3D::TG3D(void) {
for ( int l = 0 ; l < 4 ; ++l ) {
for ( int c = 0 ; c < 4 ; ++c ) {
mat[l][c] = (l == c) ? 1.0F : 0.0F; } }
}
/* Construit la TG3D clone de tg */
TG3D::TG3D(TG3D *tg) {
for ( int l = 0 ; l < 4 ; ++l ) {
for ( int c = 0 ; c < 4 ; ++c ) {
mat[l][c] = tg->mat[l][c]; } }
}
/* Destructeur */
TG3D::~TG3D(void) {
}
/* Calcul de la composition */
/* de la transformation geometrique this */
/* par la transformation geometrique rhs */
TG3D TG3D::mult(const TG3D& rhs) {
TG3D res;
for ( int l = 0 ; l < 4 ; ++l ) {
for ( int c = 0 ; c < 4 ; ++c ) {
res.mat[l][c] = 0.0F;
for ( int k = 0 ; k < 4 ; ++k ) { // [l][k] *[k][c]
res.mat[l][c] += this->mat[l][k] * rhs.mat[k][c]; } } }
return res;
}
/* Calcul de la transformation */
/* de la Pos3D p */
/* par la transformation geometrique this */
Pos3D TG3D::mult(Pos3D& p) {
return p.mult(this);
}
/* Calcul de la transformation */
/* de la Dir3D d */
/* par la transformation geometrique this */
Dir3D TG3D::mult(Dir3D& d) {
return d.mult(this);
}
/* Methode d'affichage texte */
void TG3D::print(void) {
for ( int l = 0 ; l < 4 ; l++ )
printf("%10.4f %10.4f %10.4f %10.4f\n",mat[l][0],mat[l][1],mat[l][2],mat[l][3]);
}
/* Mathematiques de l'informatique graphique */
/* Translation 3D en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#ifndef ____TR3D____
#define ____TR3D____
#include "TG3D.h"
class Dir3D;
class Tr3D : public TG3D {
public :
/* Construit la translation identite */
Tr3D(void);
/* Construit la translation (tx,ty,tz) */
Tr3D(float tx,float ty,float tz);
/* Construit la translation de vecteur d */
Tr3D(const Dir3D &dir);
/* Construit le clone de la translation tr */
Tr3D(Tr3D *tr);
/* Destructeur */
~Tr3D(void);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Translation 3D en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "TG3D.h"
#include "Tr3D.h"
#include "Dir3D.h"
/* Construit la translation identite */
Tr3D::Tr3D(void):TG3D() {
}
/* Construit la translation (tx,ty,tz) */
Tr3D::Tr3D(float tx,float ty,float tz):TG3D() {
mat[0][3] = tx;
mat[1][3] = ty;
mat[2][3] = tz;
}
/* Construit la translation de vecteur d */
Tr3D::Tr3D(const Dir3D &dir):Tr3D(dir.x,dir.y,dir.z) {
}
/* Construit le clone de la translation tr */
Tr3D::Tr3D(Tr3D *tr):TG3D(tr) {
}
/* Destructeur */
Tr3D::~Tr3D(void) {
}
/* Mathematiques de l'informatique graphique */
/* Rotation 3D en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#ifndef ____RT3D____
#define ____RT3D____
#include "TG3D.h"
class Dir3D;
class Rt3D : public TG3D {
public :
/* Construit la rotation identite */
Rt3D(void);
/* Construit la rotation d'angle alpha */
/* radians autour de l'axe de direction dir */
/* passant par l'origine */
Rt3D(float angle,Dir3D& dir);
/* Construit le clone de la rotation rt */
Rt3D(Rt3D *rt);
/* Destructeur */
~Rt3D(void);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Rotation 3D en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "TG3D.h"
#include "Rt3D.h"
#include "Dir3D.h"
/* Construit la rotation identite */
Rt3D::Rt3D(void):TG3D() {
}
/* Construit la rotation d'angle alpha radians */
/* autour de l'axe de direction dir passant */
/* par l'origine */
Rt3D::Rt3D(float angle,Dir3D &dir):TG3D() {
Dir3D dirNorm = dir.normalize();
float sn =(float) sin(angle);
float cs =(float) cos(angle);
mat[0][0] = dirNorm.x*dirNorm.x+cs*(1.0F-dirNorm.x*dirNorm.x);
mat[0][1] = dirNorm.x*dirNorm.y*(1.0F-cs)-sn*dirNorm.z;
mat[0][2] = dirNorm.x*dirNorm.z*(1.0F-cs)+sn*dirNorm.y;
mat[1][0] = dirNorm.x*dirNorm.y*(1.0F-cs)+sn*dirNorm.z;
mat[1][1] = dirNorm.y*dirNorm.y+cs*(1.0F-dirNorm.y*dirNorm.y);
mat[1][2] = dirNorm.y*dirNorm.z*(1.0F-cs)-sn*dirNorm.x;
mat[2][0] = dirNorm.x*dirNorm.z*(1.0F-cs)-sn*dirNorm.y;
mat[2][1] = dirNorm.y*dirNorm.z*(1.0F-cs)+sn*dirNorm.x;
mat[2][2] = dirNorm.z*dirNorm.z+cs*(1.0F-dirNorm.z*dirNorm.z);
}
/* Construit le clone de la rotation rt */
Rt3D::Rt3D(Rt3D *rt):TG3D(rt) {
}
/* Destructeur */
Rt3D::~Rt3D(void) {
}
/* Mathematiques de l'informatique graphique */
/* Zoom 3D en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#ifndef ____SC3D____
#define ____SC3D____
#include "TG3D.h"
class Sc3D : public TG3D {
public :
/* Construit le zoom identite */
Sc3D(void);
/* Construit le zoom de rapports (sx,sy,sz) */
Sc3D(float sx,float sy,float sz);
/* Construit le clone du zoom sc */
Sc3D(Sc3D *sc);
/* Destructeur */
~Sc3D(void);
};
#endif
/* Mathematiques de l'informatique graphique */
/* Zoom 3D en coordonnees homogenes */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Mars 2020 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "TG3D.h"
#include "Sc3D.h"
/* Construit le zoom identite */
Sc3D::Sc3D(void):TG3D() {
}
/* Construit le zoom de rapports (sx,sy,sz) */
Sc3D::Sc3D(float sx,float sy,float sz):TG3D() {
mat[0][0] = sx;
mat[1][1] = sy;
mat[2][2] = sz;
}
/* Construit le clone du zoom sc */
Sc3D::Sc3D(Sc3D *sc):TG3D(sc) {
}
/* Destructeur */
Sc3D::~Sc3D(void) {
}