/*************************************************************************** Copyright (C) 2009 by Pierre,,, pierre@pierre-laptop ***************************************************************************/ #include "vecteur3f.h" #include "matrice3f.h" const Vecteur3f VECT3F_NULL(0,0,0); const Vecteur3f GTerre3f(0.0, 10.0, 0.0); ///fonction qui permet d'initialiser et de renvoyer un Vecteur3f /** @param x : composante x du Vecteur3f @param y : composante y du Vecteur3f @param z : composante z du Vecteur3f */ Vecteur3f initVecteur3f(float x, float y, float z){ Vecteur3f vect(x, y, z); return vect; } using namespace std; /// Fonction qui converti un Point en Vecteur3f /** @param point : Point que l'on veut convertir @return Vecteur3f calculé avec le Point */ Vecteur3f pointToVecteur3f(const Pointf & point){ Vecteur3f vect(point.x, point.y, point.z); return vect; } //////////////////////////////////////////////////////////////////////// // // // Classe Vecteur3f // // // //////////////////////////////////////////////////////////////////////// /// constructeur de Vecteur3f /** @param vecX : composante x du Vecteur3f @param vecY : composante y du Vecteur3f @param vecZ : composante z du Vecteur3f */ Vecteur3f::Vecteur3f(float vecX, float vecY, float vecZ){ this->init(vecX, vecY, vecZ); } ///initialise un Vecteur3f avec une chaîne /** @param str : chaîne d'initialisation */ Vecteur3f::Vecteur3f(const char * str){ this->init(0.0, 0.0, 0.0); this->initString(str); } /// Fonction qui permet d'initialiser un Vecteur3f avec un Point /** @param point : point qui initialisera le Vecteur3f */ Vecteur3f::Vecteur3f(const Pointf& point){ this->init(point.x, point.y, point.z); } /// constructeur de copie de Vecteur3f /** @param vec : Vecteur3f */ Vecteur3f::Vecteur3f(const Vecteur3f & vec){ this->init(vec.x, vec.y, vec.z); } ///destructeur de Vecteur3f Vecteur3f::~Vecteur3f(){} /// fonction qui :sauvegarde les coordonnées du Vecteur3f (x,y,z) dans le fichier fp /** @param fp : fichier de savegarde du vecteur */ void Vecteur3f::save(FILE* fp){ fprintf(fp, "(%f,", this->x); fprintf(fp, "%f,", this->y); fprintf(fp, "%f)", this->z); } /// fonction qui :sauvegarde les coordonnées du Vecteur3f (x,y) dans le fichier fp /** @param fp : fichier de savegarde du vecteur */ void Vecteur3f::save2d(FILE* fp){ fprintf(fp, "(%f,", this->x); fprintf(fp, "%f)", this->y); } /// Cette fonction initialise le Vecteur3f avec les valeurs de coordonnées de Vecteur3f enregistrées sous forme de fichiers /** @param fp : fichier où doit se trouver des coordonnées de Vecteur3f */ void Vecteur3f::load(FILE* fp){ float nb; fscanf(fp, "(%f,", &nb); this->x = nb; fscanf(fp, " %f,", &nb); this->y = nb; fscanf(fp, " %f)", &nb); this->z = nb; } ///initialisation avec une chaine de caractères /** @param str : chaîne de caractères pour l'initialisation du Vecteur3f * @return true si l'initialisation s'est faite, false sinon */ bool Vecteur3f::initString(const char * str){ if(str == NULL) return false; if(sscanf(str,"(%f,%f,%f)",&x,&y,&z) == 0){ if(sscanf(str,"(%f,%f)",&x,&y) == 0){ if(sscanf(str,"(%f)",&x) == 0){ return false; }else return true; }else return true; }else return true; } /// redéfinition de l'opérateur = /** @param vect : Vecteur3f @return Vecteur3f (*this) */ Vecteur3f & Vecteur3f::operator = ( const Vecteur3f & vect){ this->init(vect.x, vect.y, vect.z); return *this; } /// redéfinition de l'opérateur += /** @param vect : Vecteur3f @return Vecteur3f (*this) */ Vecteur3f & Vecteur3f::operator += ( const Vecteur3f & vect){ this->x += vect.x; this->y += vect.y; this->z += vect.z; return *this; } /// redéfinition de l'opérateur -= /** @param vect : Vecteur3f @return Vecteur3f (*this) */ Vecteur3f & Vecteur3f::operator -= ( const Vecteur3f & vect){ this->x -= vect.x; this->y -= vect.y; this->z -= vect.z; return *this; } /// redéfinition de l'opérateur *= /** @param coef : float @return Vecteur3f (*this)*coef */ Vecteur3f & Vecteur3f::operator *= (float coef){ //redéfinition de l'opérateur *= this->x *= coef; this->y *= coef; this->z *= coef; return *this; } /// redéfinition de l'opérateur /= /** @param coef : float @return Vecteur3f (*this)/coef */ Vecteur3f & Vecteur3f::operator /= (float coef){ //redéfinition de l'opérateur /= this->x /= coef; this->y /= coef; this->z /= coef; return *this; } /// redéfinition de l'opérateur - pour un Vecteur3f /** @return Vecteur3f opposé de *this */ Vecteur3f Vecteur3f::operator - (){ Vecteur3f v(-x,-y,-z); return v; } ///renvoie la norme euclidienne du Vecteur3f /** @return taille du Vecteur3f */ float Vecteur3f::taille() const{ //calcul de la taille du vecteur float taille = sqrt(x*x + y*y + z*z); return taille; } ///donne la norme du vecteur en coordonnées de Leci-Civita (u, v, 0.0) /** @return norme du vecteur en coordonnées de Leci-Civita (u, v, 0.0) (= u² + v²) */ float Vecteur3f::tailleLeviCivita() const{ return x*x + y*y; } /// fonction qui calcul et renvoie la norme au carré de *this /** @return norme au carré du Vecteur3f *this très utile pour faire de l'économie de calcul en faisant des simulations qui font intervenir des forces */ float Vecteur3f::normeSQR() const{ return x*x + y*y + z*z; } /// Retourne un Vecteur3f ayant pour composantes les valeurs absolues des composantes de this /** @return Vecteur3f positif */ Vecteur3f Vecteur3f::abs() const{ Vecteur3f vect(fabs(this->x), fabs(this->y), fabs(this->z)); return vect; } ///renvoie un Vecteur3f qui a un x positif /** @return Vecteur3f x positif */ Vecteur3f Vecteur3f::absX() const{ Vecteur3f vect(fabs(this->x), this->y, this->z); return vect; } ///renvoie un Vecteur3f qui a un y positif /** @return Vecteur3f y positif */ Vecteur3f Vecteur3f::absY() const{ Vecteur3f vect(this->x, fabs(this->y), this->z); return vect; } ///renvoie un Vecteur3f qui a un z positif /** @return Vecteur3f z positif */ Vecteur3f Vecteur3f::absZ() const{ Vecteur3f vect(this->x, this->y, fabs(this->z)); return vect; } ///Renvoie un vecteur (x, 0, 0) /** @return un Vecteur3f de la composante x du Vecteur3f */ Vecteur3f Vecteur3f::getVectX() const{ Vecteur3f vect(this->x, 0, 0); return vect; } ///Renvoie un vecteur (0, y, 0) /** @return un Vecteur3f de la composante y du Vecteur3f */ Vecteur3f Vecteur3f::getVectY() const{ Vecteur3f vect(0, this->y, 0); return vect; } ///Renvoie un vecteur (0, 0, z) /** @return un Vecteur3f de la composante z du Vecteur3f */ Vecteur3f Vecteur3f::getVectZ() const{ Vecteur3f vect(0, 0, this->z); return vect; } ///Renvoie un Vecteur3f (x, y, 0) /** @return un Vecteur3f (x, y, 0) */ Vecteur3f Vecteur3f::getVectXY() const{return Vecteur3f(x, y, 0.0);} ///Renvoie un Vecteur3f (0, y, z) /** @return un Vecteur3f (0, y, z) */ Vecteur3f Vecteur3f::getVectYZ() const{return Vecteur3f(0.0, y, z);} ///Renvoie un Vecteur3f (x, 0, z) /** @return un Vecteur3f (x, 0, z) */ Vecteur3f Vecteur3f::getVectXZ() const{return Vecteur3f(x, 0.0, z);} ///Renvoie le vecteur unitaire de *this /** @return le Vecteur3f unitaire correspondant au Vecteur3f courrant */ Vecteur3f Vecteur3f::getUnit() const{ if(x == 0.0 && y == 0.0 && z == 0.0) return VECT3F_NULL; float taille = this->taille(); Vecteur3f unit(this->x/taille, this->y/taille, this->z/taille); return unit; } /// fonction de calcul d'angle qui doit être plus rapide que le calcul avec des nombres complexes /** @param normale : Vecteur3f qui est la référence du calcul suivant @return angle entre le Vecteur3f normal et *this en radian */ float Vecteur3f::getAngle(const Vecteur3f& normale) const{ if(x == 0.0 && y == 0.0 && z == 0.0) return 0.0; return acos(((*this)*normale)/this->taille()); } /// Fonction qui converti un Vecteur3f en Point /** @return Point correspondant u Vecteur3f */ Pointf Vecteur3f::toPoint() const{ Pointf point; point.x = this->x; point.y = this->y; point.z = this->z; return point; } ///fonction qui transforme un vecteur en coordonnées de Leci-Civita (u, v, 0) en un Vecteur3f normal (x, y, 0) en 2D en tout cas pour l'instant /** @return Vecteur3f en coordonnées normales (x, y, 0) car Leci-Civita est en 2D */ Vecteur3f Vecteur3f::leviCivitaToVecteur3f() const{ Vecteur3f vect(x*x - y*y, 2.0*x*y, 0.0); return vect; } /// fonction qui initialise les composantes du Vecteur3f /** @param vecX : composante x @param vecY : composante y @param vecZ : composante z */ void Vecteur3f::setXYZ(float vecX, float vecY, float vecZ){ this->x = vecX; this->y = vecY; this->z = vecZ; } /// fonction qui initialise les composantes du Vecteur3f avec un Point /** @param pt : Point servant à initialiser le Vecteur3f */ void Vecteur3f::setXYZ(const Pointf& pt){ this->init(pt.x, pt.y, pt.z); } /// initialise la composantes x du Vecteur3f /** @param x : conposante x du Vecteur3f */ void Vecteur3f::setx(const float x){this->x = x;} /// initialise la composantes y du Vecteur3f /** @param y : conposante y du Vecteur3f */ void Vecteur3f::sety(const float y){this->y = y;} /// initialise la composantes z du Vecteur3f /** @param z : conposante z du Vecteur3f */ void Vecteur3f::setz(const float z){this->z = z;} ///ajoute une valeur à la composante en x du Vecteur3f /** @param dx : variation de x */ void Vecteur3f::addx(float dx){this->x += dx;} ///ajoute une valeur à la composante en y du Vecteur3f /** @param dy : variation de y */ void Vecteur3f::addy(float dy){this->y += dy;} ///ajoute une valeur à la composante en z du Vecteur3f /** @param dz : variation de z */ void Vecteur3f::addz(float dz){this->z += dz;} ///fonction qui initialise le vecteur avec des angles en coordonnées spériques /** @param angleTeta : angle des coordonnées polaires (si phi = M_PI/2) @param anglePhi : angle des coordonnées sphériques */ void Vecteur3f::setRotation(float angleTeta, float anglePhi){ float longeur = this->taille(); this->x = sin(anglePhi)*cos(angleTeta)*longeur; this->y = sin(anglePhi)*sin(angleTeta)*longeur; this->z = cos(anglePhi)*longeur; } ///fonction qui initialise le vecteur avec des angles en coordonnées spériques /** @param rho : norme du Vecteur3f * @param angleTeta : angle des coordonnées polaires (si phi = M_PI/2) @param anglePhi : angle des coordonnées sphériques */ void Vecteur3f::setSpheric(float rho, float angleTeta, float anglePhi){ this->x = sin(anglePhi)*cos(angleTeta)*rho; this->y = sin(anglePhi)*sin(angleTeta)*rho; this->z = cos(anglePhi)*rho; } /// fonction qui calcul la rotation du vecteur avec les variations de ses angles en coordonnées spériques /** @param axe : axe de rotation autour duquel on doit faire tourner le Vecteur3f @param angle : angle de rotation autour de l'axe de rotation */ void Vecteur3f::rotation(const Vecteur3f& axe, float angle){ Vecteur3f tourner = cos(angle)*(*this) + (1 - cos(angle))*((*this)*axe)*axe + sin(angle)*(axe^(*this)); (*this) = tourner; } ///fonction qui calcul la rotation du vecteur avec les variations de ses angles en coordonnées spériques /** @param matriceRotation : matricede rotation * @param centreRotation : position du centre de rotation du Vecteur3f */ void Vecteur3f::rotation(const Matrice3f& matriceRotation, const Vecteur3f& centreRotation){ Vecteur3f rot(*this); rot = matriceRotation*(rot - centreRotation) + centreRotation; (*this) = rot; } ///fonction qui retourne l'angle dans le plan du Vecteur3f /** @return angle du Vecteur3f */ float Vecteur3f::getAngleTeta() const{ float longeur = this->taille(); float anglePhi = acosf(this->z/longeur); float cosTeta = this->x / (longeur*sinf(anglePhi)); float sinTeta = this->y / (longeur*sinf(anglePhi)); float complex zTeta = longeur*(cosTeta + I*sinTeta); //I est le i des nombres complexes float angleTeta = cargf(zTeta); return angleTeta; } ///fonction qui calcul le réflexion du Vecteur3f *this par rapport à un vecteur normal /** le vecteur étant réfléchit dans la direction du Vecteur3f normal @param normal : Vecteur3f qui est la référence du calcul suivant */ void Vecteur3f::reflexion(const Vecteur3f& normal){ //vecteur normal à une surface plane Vecteur3f xF = (normal*(-(*this)))/(normal.taille()*normal.taille())*normal; *this = xF*2 + (*this); } ///Définition de l'addition de deux Vecteur3f /** @param vect1 : Vecteur3f @param vect2 : Vecteur3f @return Vecteur3f addition de vect1 + vect2 */ Vecteur3f operator + (const Vecteur3f & vect1, const Vecteur3f & vect2){ Vecteur3f vect3(vect1.x + vect2.x, vect1.y + vect2.y, vect1.z + vect2.z); return vect3; } /// Définition de la soustraction de deux Vecteur3f, const à droite /** @param vect1 : Vecteur3f @param vect2 : Vecteur3f @return Vecteur3f soustraction de vect1 - vect2 */ Vecteur3f operator - (const Vecteur3f & vect1, const Vecteur3f & vect2){ Vecteur3f vect3(vect1.x - vect2.x, vect1.y - vect2.y, vect1.z - vect2.z); return vect3; } /// Définition du produit scalaire entre deux Vecteur3f /** @param vect1 : Vecteur3f @param vect2 : Vecteur3f @return float : résultat du produit scalaire */ float operator * (const Vecteur3f & vect1, const Vecteur3f & vect2){ return vect1.x*vect2.x + vect1.y*vect2.y + vect1.z*vect2.z; } ///mutiplication par un scalaire à droite /** Définition de la multiplication par un scalaire à droite @param vect : Vecteur3f @param scal : scalaire @return Vecteur3f produit de vect1*scal */ Vecteur3f operator * (const Vecteur3f & vect, float scal){ Vecteur3f vect2(vect.x*scal, vect.y*scal, vect.z*scal); return vect2; } ///mutiplication par un scalaire à gauche /** Définition de la multiplication par un scalaire à gauche @param scal : scalaire @param vect : Vecteur3f @return Vecteur3f produit de scal*vect1 */ Vecteur3f operator * (float scal, const Vecteur3f & vect){ Vecteur3f vect2(vect.x*scal, vect.y*scal, vect.z*scal); return vect2; } /// division par un scalaire /** @param vect : Vecteur3f @param scal : float @return Vecteur3f division de vect1/scal */ Vecteur3f operator / (const Vecteur3f & vect, float scal){ Vecteur3f vect2(vect.x/scal, vect.y/scal, vect.z/scal); return vect2; } /// Définition du produit vectoriel /** @param vect1 : Vecteur3f @param vect2 : Vecteur3f @return Vecteur3f produit vectoriel vect1^vect2 */ Vecteur3f operator ^ (const Vecteur3f & vect1, const Vecteur3f & vect2){ Vecteur3f vect(vect1.y*vect2.z - vect1.z*vect2.y, -vect1.x*vect2.z + vect1.z*vect2.x, vect1.x*vect2.y - vect1.y*vect2.x); return vect; } /// Définition de l'égalité entre deux Vecteur3f /** @param vect1 : Vecteur3f @param vect2 : Vecteur3f @return booleen true si toutes les composantes des deux Vecteur3f sont égalles, false sinon */ bool operator == (const Vecteur3f & vect1, const Vecteur3f & vect2){ return (vect1.x == vect2.x && vect1.y == vect2.y && vect1.z == vect2.z); } /// Définition de l'inégalité entre deux Vecteur3f /** @param vect1 : Vecteur3f @param vect2 : Vecteur3f @return booleen true si toutes les composantes des deux Vecteur3f sont inégalles, false sinon */ bool operator != (const Vecteur3f & vect1, const Vecteur3f & vect2){ return !(vect1.x == vect2.x && vect1.y == vect2.y && vect1.z == vect2.z); } /// permet l'affichage d'un vecteur dans la console /** @param out : sortie standart de la console (cout) @param vecteur : Vecteur3f à afficher dans la console */ std::ostream & operator << (std::ostream & out, const Vecteur3f & vecteur){ out << "(" << vecteur.x << ", " << vecteur.y << ", " << vecteur.z << ")"; return out; } ///permet l'initialisation d'un Vecteur3f dans la console où avec un fichier de config /** @param in : entrée standart de la console (cin) @param v : Vecteur3f à initialiser */ std::istream & operator >> (std::istream & in, Vecteur3f & v){ in >> v.x >> v.y >> v.z; return in; } ///initialise un Vecteur3f à partir d'une chaine de type (x,y,z) /** @param source : chaine d'initlisation * @return true si la fonction à réussie, false sinon */ bool Vecteur3f::loadFromConfig(const char* source) { return (sscanf(source,"(%f,%f,%f)",&x,&y,&z) != 0); } /// fonction qui initialise un Vecteur3f /** @param vecX : composante x du Vecteur3f @param vecY : composante y du Vecteur3f @param vecZ : composante z du Vecteur3f */ void Vecteur3f::init(float vecX, float vecY, float vecZ){ this->x = vecX; this->y = vecY; this->z = vecZ; } ///fonction qui indique comment initilialiser un Vecteur3f avec un fichier de config /** @param source : chaine d'initlisation @param v : Vecteur3f à initialiser */ void pConfig_load_obj(const char * source, Vecteur3f & v) { v.loadFromConfig(source); } ///fonction qui permet d'initialiser une PListeVecteur3f /** @param fileName : nom du fichier à lire * @param listeVecteur3f : PListeVecteur3f à initialiser * @return true si la fonction à réussie, false sinon */ bool loadPListeVecteur3f(const char * fileName, PListeVecteur3f & listeVecteur3f){ if(fileName == NULL) return false; FILE* fp = fopen(fileName, "r"); bool find(false); if(fp != NULL){ char buffer[1024]; Vecteur3f vect; while(!feof(fp)){ if (fgets(buffer,sizeof(buffer) - 1, fp)){ if(vect.initString(buffer)){ listeVecteur3f.push_back(vect); find = true; } } } fclose(fp); } return find; } ///fonction qui permet de sauvergarder une PListeVecteur3f /** @param fileName : nom du fichier à lire * @param listeVecteur3f : PListeVecteur3f à sauvergarder */ void savePlisteVecteur3f(const char * fileName, const PListeVecteur3f & listeVecteur3f){ if(fileName == NULL) return; FILE* fp = fopen(fileName, "w"); if(fp != NULL){ for(PListeVecteur3f::const_iterator it = listeVecteur3f.begin(); it != listeVecteur3f.end(); it++){ fprintf(fp, "(%f,%f,%f)\n", it->getx(), it->gety(), it->getz()); } fclose(fp); } } ///fonction qui permet de sauvergarder une PListeVecteur3f sur x /** @param fileName : nom du fichier à lire * @param listeVecteur3f : PListeVecteur3f à sauvergarder */ void savePlisteVecteur3fX(const char * fileName, const PListeVecteur3f & listeVecteur3f){ if(fileName == NULL) return; FILE* fp = fopen(fileName, "w"); if(fp != NULL){ for(PListeVecteur3f::const_iterator it = listeVecteur3f.begin(); it != listeVecteur3f.end(); it++){ fprintf(fp, "%f\n", it->getx()); } fclose(fp); } } ///fonction qui permet de sauvergarder une PListeVecteur3f sur y /** @param fileName : nom du fichier à lire * @param listeVecteur3f : PListeVecteur3f à sauvergarder */ void savePlisteVecteur3fY(const char * fileName, const PListeVecteur3f & listeVecteur3f){ if(fileName == NULL) return; FILE* fp = fopen(fileName, "w"); if(fp != NULL){ for(PListeVecteur3f::const_iterator it = listeVecteur3f.begin(); it != listeVecteur3f.end(); it++){ fprintf(fp, "%f\n", it->gety()); } fclose(fp); } } ///fonction qui permet de sauvergarder une PListeVecteur3f sur z /** @param fileName : nom du fichier à lire * @param listeVecteur3f : PListeVecteur3f à sauvergarder */ void savePlisteVecteur3fZ(const char * fileName, const PListeVecteur3f & listeVecteur3f){ if(fileName == NULL) return; FILE* fp = fopen(fileName, "w"); if(fp != NULL){ for(PListeVecteur3f::const_iterator it = listeVecteur3f.begin(); it != listeVecteur3f.end(); it++){ fprintf(fp, "%f\n", it->getz()); } fclose(fp); } }