/*************************************************************************** Copyright (C) 2009 by Pierre,,, pierre@pierre-laptop ***************************************************************************/ #include "vecteur.h" ///fonction qui permet d'initialiser et de renvoyer un Vecteur /** @param x : composante x du Vecteur @param y : composante y du Vecteur @param z : composante z du Vecteur */ Vecteur initVecteur(double x, double y, double z){ Vecteur vect(x, y, z); return vect; } using namespace std; //////////////////////////////////////////////////////////////////////// // // // Classe Vecteur // // // //////////////////////////////////////////////////////////////////////// /// constructeur de Vecteur /** @param vecX : composante x du Vecteur @param vecY : composante y du Vecteur @param vecZ : composante z du Vecteur */ Vecteur::Vecteur(double vecX, double vecY, double vecZ){ initialisationVecteur(vecX, vecY, vecZ); } ///initialise un Vecteur avec une chaîne /** @param str : chaîne d'initialisation */ Vecteur::Vecteur(const char * str){ initialisationVecteur(0.0, 0.0, 0.0); loadFromConfig(str); } /// constructeur de copie de Vecteur /** @param vec : Vecteur */ Vecteur::Vecteur(const Vecteur & vec){ initialisationVecteur(vec.p_x, vec.p_y, vec.p_z); } ///destructeur de Vecteur Vecteur::~Vecteur(){} /// fonction qui :sauvegarde les coordonnées du Vecteur (x,y,z) dans le fichier fp /** @param fp : fichier de savegarde du vecteur */ void Vecteur::save(FILE* fp){ fprintf(fp, "(%lf,", p_x); fprintf(fp, "%lf,", p_y); fprintf(fp, "%lf)", p_z); } /// fonction qui :sauvegarde les coordonnées du Vecteur (x,y) dans le fichier fp /** @param fp : fichier de savegarde du vecteur */ void Vecteur::save2d(FILE* fp){ fprintf(fp, "(%lf,", p_x); fprintf(fp, "%lf)", p_y); } /// Cette fonction initialise le Vecteur avec les valeurs de coordonnées de Vecteur enregistrées sous forme de fichiers /** @param fp : fichier où doit se trouver des coordonnées de Vecteur */ void Vecteur::load(FILE* fp){ double nb; if(fscanf(fp, "(%lf,", &nb) == 0) return; p_x = nb; if(fscanf(fp, " %lf,", &nb) == 0) return; p_y = nb; if(fscanf(fp, " %lf)", &nb) == 0) return; p_z = nb; } ///initialisation avec une chaine de caractères /** @param str : chaîne de caractères pour l'initialisation du Vecteur * @return true si l'initialisation s'est faite, false sinon */ bool Vecteur::initString(const char * str){ if(str == NULL) return false; if(sscanf(str,"(%lf,%lf,%lf)",&p_x,&p_y,&p_z) == 0){ if(sscanf(str,"(%lf,%lf)",&p_x,&p_y) == 0){ if(sscanf(str,"(%lf)",&p_x) == 0){ return false; }else return true; }else return true; }else return true; } /// redéfinition de l'opérateur = /** @param vect : Vecteur @return Vecteur (*this) */ Vecteur & Vecteur::operator = ( const Vecteur & vect){ initialisationVecteur(vect.p_x, vect.p_y, vect.p_z); return *this; } /// redéfinition de l'opérateur += /** @param vect : Vecteur @return Vecteur (*this) */ Vecteur & Vecteur::operator += ( const Vecteur & vect){ p_x += vect.p_x; p_y += vect.p_y; p_z += vect.p_z; return *this; } /// redéfinition de l'opérateur -= /** @param vect : Vecteur @return Vecteur (*this) */ Vecteur & Vecteur::operator -= ( const Vecteur & vect){ p_x -= vect.p_x; p_y -= vect.p_y; p_z -= vect.p_z; return *this; } /// redéfinition de l'opérateur *= /** @param coef : double @return Vecteur (*this)*coef */ Vecteur & Vecteur::operator *= (double coef){ //redéfinition de l'opérateur *= p_x *= coef; p_y *= coef; p_z *= coef; return *this; } /// redéfinition de l'opérateur /= /** @param coef : double @return Vecteur (*this)/coef */ Vecteur & Vecteur::operator /= (double coef){ //redéfinition de l'opérateur /= p_x /= coef; p_y /= coef; p_z /= coef; return *this; } /// redéfinition de l'opérateur - pour un Vecteur /** @return Vecteur opposé de *this */ Vecteur Vecteur::operator - (){ Vecteur v(-p_x,-p_y,-p_z); return v; } ///renvoie la norme euclidienne du Vecteur /** @return taille du Vecteur */ double Vecteur::taille() const{ //calcul de la taille du vecteur double taille = sqrt(p_x*p_x + p_y*p_y + p_z*p_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²) */ double Vecteur::tailleLeviCivita() const{ return p_x*p_x + p_y*p_y; } /// fonction qui calcul et renvoie la norme au carré de *this /** @return norme au carré du Vecteur *this très utile pour faire de l'économie de calcul en faisant des simulations qui font intervenir des forces */ double Vecteur::normeSQR() const{ return p_x*p_x + p_y*p_y + p_z*p_z; } /// Retourne un Vecteur ayant pour composantes les valeurs absolues des composantes de this /** @return Vecteur positif */ Vecteur Vecteur::abs() const{ Vecteur vect(fabs(p_x), fabs(p_y), fabs(p_z)); return vect; } ///renvoie un Vecteur qui a un x positif /** @return Vecteur x positif */ Vecteur Vecteur::absX() const{ Vecteur vect(fabs(p_x), p_y, p_z); return vect; } ///renvoie un Vecteur qui a un y positif /** @return Vecteur y positif */ Vecteur Vecteur::absY() const{ Vecteur vect(p_x, fabs(p_y), p_z); return vect; } ///renvoie un Vecteur qui a un z positif /** @return Vecteur z positif */ Vecteur Vecteur::absZ() const{ Vecteur vect(p_x, p_y, fabs(p_z)); return vect; } ///Renvoie un vecteur (x, 0, 0) /** @return un Vecteur de la composante x du Vecteur */ Vecteur Vecteur::getVectX() const{ Vecteur vect(p_x, 0, 0); return vect; } ///Renvoie un vecteur (0, y, 0) /** @return un Vecteur de la composante y du Vecteur */ Vecteur Vecteur::getVectY() const{ Vecteur vect(0, p_y, 0); return vect; } ///Renvoie un vecteur (0, 0, z) /** @return un Vecteur de la composante z du Vecteur */ Vecteur Vecteur::getVectZ() const{ Vecteur vect(0, 0, p_z); return vect; } ///Renvoie un Vecteur (x, y, 0) /** @return un Vecteur (x, y, 0) */ Vecteur Vecteur::getVectXY() const{return Vecteur(p_x, p_y, 0.0);} ///Renvoie un Vecteur (0, y, z) /** @return un Vecteur (0, y, z) */ Vecteur Vecteur::getVectYZ() const{return Vecteur(0.0, p_y, p_z);} ///Renvoie un Vecteur (x, 0, z) /** @return un Vecteur (x, 0, z) */ Vecteur Vecteur::getVectXZ() const{return Vecteur(p_x, 0.0, p_z);} ///Renvoie le vecteur unitaire de *this /** @return le Vecteur unitaire correspondant au Vecteur courrant */ Vecteur Vecteur::getUnit() const{ if(p_x == 0.0 && p_y == 0.0 && p_z == 0.0) return VECT3D_NULL; double tailleVec = this->taille(); Vecteur unit(p_x/tailleVec, p_y/tailleVec, p_z/tailleVec); return unit; } /// fonction de calcul d'angle qui doit être plus rapide que le calcul avec des nombres complexes /** @param normale : Vecteur qui est la référence du calcul suivant @return angle entre le Vecteur normal et *this en radian */ double Vecteur::getAngle(const Vecteur& normale) const{ if(p_x == 0.0 && p_y == 0.0 && p_z == 0.0) return 0.0; return acos(((*this)*normale)/this->taille()); } ///fonction qui transforme un vecteur en coordonnées de Leci-Civita (u, v, 0) en un Vecteur normal (x, y, 0) en 2D en tout cas pour l'instant /** @return Vecteur en coordonnées normales (x, y, 0) car Leci-Civita est en 2D */ Vecteur Vecteur::leviCivitaToVecteur() const{ Vecteur vect(p_x*p_x - p_y*p_y, 2.0*p_x*p_y, 0.0); return vect; } /// fonction qui initialise les composantes du Vecteur /** @param vecX : composante x @param vecY : composante y @param vecZ : composante z */ void Vecteur::setXYZ(double vecX, double vecY, double vecZ){ p_x = vecX; p_y = vecY; p_z = vecZ; } /// initialise la composantes x du Vecteur /** @param x : conposante x du Vecteur */ void Vecteur::setx(const double x){p_x = x;} /// initialise la composantes y du Vecteur /** @param y : conposante y du Vecteur */ void Vecteur::sety(const double y){p_y = y;} /// initialise la composantes z du Vecteur /** @param z : conposante z du Vecteur */ void Vecteur::setz(const double z){p_z = z;} ///ajoute une valeur à la composante en x du Vecteur /** @param dx : variation de x */ void Vecteur::addx(double dx){p_x += dx;} ///ajoute une valeur à la composante en y du Vecteur /** @param dy : variation de y */ void Vecteur::addy(double dy){p_y += dy;} ///ajoute une valeur à la composante en z du Vecteur /** @param dz : variation de z */ void Vecteur::addz(double dz){p_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 Vecteur::setRotation(double angleTeta, double anglePhi){ double longeur = this->taille(); p_x = sin(anglePhi)*cos(angleTeta)*longeur; p_y = sin(anglePhi)*sin(angleTeta)*longeur; p_z = cos(anglePhi)*longeur; } ///fonction qui initialise le vecteur avec des angles en coordonnées spériques /** @param rho : norme du Vecteur * @param angleTeta : angle des coordonnées polaires (si phi = M_PI/2) @param anglePhi : angle des coordonnées sphériques */ void Vecteur::setSpheric(double rho, double angleTeta, double anglePhi){ p_x = sin(anglePhi)*cos(angleTeta)*rho; p_y = sin(anglePhi)*sin(angleTeta)*rho; p_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 Vecteur @param angle : angle de rotation autour de l'axe de rotation */ void Vecteur::rotation(const Vecteur& axe, double angle){ Vecteur tourner = cos(angle)*(*this) + (1 - cos(angle))*((*this)*axe)*axe + sin(angle)*(axe^(*this)); (*this) = tourner; } ///fonction qui retourne l'angle dans le plan du Vecteur /** @return angle du Vecteur */ double Vecteur::getAngleTeta() const{ double longeur = this->taille(); double anglePhi = acosf(p_z/longeur); double cosTeta = p_x / (longeur*sinf(anglePhi)); double sinTeta = p_y / (longeur*sinf(anglePhi)); double complex zTeta = longeur*(cosTeta + I*sinTeta); //I est le i des nombres complexes double angleTeta = cargf(zTeta); return angleTeta; } ///fonction qui calcul le réflexion du Vecteur *this par rapport à un vecteur normal /** le vecteur étant réfléchit dans la direction du Vecteur normal @param normal : Vecteur qui est la référence du calcul suivant */ void Vecteur::reflexion(const Vecteur& normal){ //vecteur normal à une surface plane Vecteur xF = (normal*(-(*this)))/(normal.taille()*normal.taille())*normal; *this = xF*2 + (*this); } ///Définition de l'addition de deux Vecteur /** @param vect1 : Vecteur @param vect2 : Vecteur @return Vecteur addition de vect1 + vect2 */ Vecteur operator + (const Vecteur & vect1, const Vecteur & vect2){ Vecteur vect3(vect1.p_x + vect2.p_x, vect1.p_y + vect2.p_y, vect1.p_z + vect2.p_z); return vect3; } /// Définition de la soustraction de deux Vecteur, const à droite /** @param vect1 : Vecteur @param vect2 : Vecteur @return Vecteur soustraction de vect1 - vect2 */ Vecteur operator - (const Vecteur & vect1, const Vecteur & vect2){ Vecteur vect3(vect1.p_x - vect2.p_x, vect1.p_y - vect2.p_y, vect1.p_z - vect2.p_z); return vect3; } /// Définition du produit scalaire entre deux Vecteur /** @param vect1 : Vecteur @param vect2 : Vecteur @return double : résultat du produit scalaire */ double operator * (const Vecteur & vect1, const Vecteur & vect2){ return vect1.p_x*vect2.p_x + vect1.p_y*vect2.p_y + vect1.p_z*vect2.p_z; } ///mutiplication par un scalaire à droite /** Définition de la multiplication par un scalaire à droite @param vect : Vecteur @param scal : scalaire @return Vecteur produit de vect1*scal */ Vecteur operator * (const Vecteur & vect, double scal){ Vecteur vect2(vect.p_x*scal, vect.p_y*scal, vect.p_z*scal); return vect2; } ///mutiplication par un scalaire à gauche /** Définition de la multiplication par un scalaire à gauche @param scal : scalaire @param vect : Vecteur @return Vecteur produit de scal*vect1 */ Vecteur operator * (double scal, const Vecteur & vect){ Vecteur vect2(vect.p_x*scal, vect.p_y*scal, vect.p_z*scal); return vect2; } /// division par un scalaire /** @param vect : Vecteur @param scal : double @return Vecteur division de vect1/scal */ Vecteur operator / (const Vecteur & vect, double scal){ Vecteur vect2(vect.p_x/scal, vect.p_y/scal, vect.p_z/scal); return vect2; } /// Définition du produit vectoriel /** @param vect1 : Vecteur @param vect2 : Vecteur @return Vecteur produit vectoriel vect1^vect2 */ Vecteur operator ^ (const Vecteur & vect1, const Vecteur & vect2){ Vecteur vect(vect1.p_y*vect2.p_z - vect1.p_z*vect2.p_y, -vect1.p_x*vect2.p_z + vect1.p_z*vect2.p_x, vect1.p_x*vect2.p_y - vect1.p_y*vect2.p_x); return vect; } /// Définition de l'égalité entre deux Vecteur /** @param vect1 : Vecteur @param vect2 : Vecteur @return booleen true si toutes les composantes des deux Vecteur sont égalles, false sinon */ bool operator == (const Vecteur & vect1, const Vecteur & vect2){ return (vect1.p_x == vect2.p_x && vect1.p_y == vect2.p_y && vect1.p_z == vect2.p_z); } /// Définition de l'inégalité entre deux Vecteur /** @param vect1 : Vecteur @param vect2 : Vecteur @return booleen true si toutes les composantes des deux Vecteur sont inégalles, false sinon */ bool operator != (const Vecteur & vect1, const Vecteur & vect2){ return !(vect1.p_x == vect2.p_x && vect1.p_y == vect2.p_y && vect1.p_z == vect2.p_z); } /// permet l'affichage d'un vecteur dans la console /** @param out : sortie standart de la console (cout) @param vecteur : Vecteur à afficher dans la console */ std::ostream & operator << (std::ostream & out, const Vecteur & vecteur){ out << "(" << vecteur.p_x << ", " << vecteur.p_y << ", " << vecteur.p_z << ")"; return out; } ///permet l'initialisation d'un Vecteur dans la console où avec un fichier de config /** @param in : entrée standart de la console (cin) @param v : Vecteur à initialiser */ std::istream & operator >> (std::istream & in, Vecteur & v){ in >> v.p_x >> v.p_y >> v.p_z; return in; } ///initialise un Vecteur à partir d'une chaine de type (x,y,z) /** @param source : chaine d'initlisation * @return true si la fonction à réussie, false sinon */ bool Vecteur::loadFromConfig(const char* source) { return (sscanf(source,"(%lf,%lf,%lf)",&p_x,&p_y,&p_z) != 0); } /// fonction qui initialise un Vecteur /** @param vecX : composante x du Vecteur @param vecY : composante y du Vecteur @param vecZ : composante z du Vecteur */ void Vecteur::initialisationVecteur(double vecX, double vecY, double vecZ){ p_x = vecX; p_y = vecY; p_z = vecZ; }