// FICHIER : Coordonnee3H.cp
// CLASSE : Coordonnee3H

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

//#include "Debug.h"

# include <iostream>
using namespace std;  //introduces namespace std
#include <stdlib.h>
#include "Sortie.h"
#include "ConstMath.h"
#include "MathUtil.h"

#include "Coordonnee3.h"


#ifndef  COORDONNEE3_H_deja_inclus
 

// Constructeur par defaut
// il y a initialisation des coordonnées à zéro 
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::Coordonnee3H () :
 CoordonneeH(3,coord3)
{   coord3[0] = 0.;coord3[1] = 0.;coord3[2] = 0.; 
};

// Constructeur suivant un booleen
// quelque soit la valeur du booleen il n'y a pas initialisation des coordonnées 
// ceci  pour aller plus vite par rapport au constructeur par défaut
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::Coordonnee3H (bool  ):
 CoordonneeH(3,coord3)
{  };

#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::Coordonnee3H (double x,double y,double z):
 CoordonneeH(3,coord3)
// Constructeur pour un point a trois dimensions
{	coord3[0]=x;
	coord3[1]=y;
	coord3[2]=z;	
};

// constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
// et d'une dimension ( l'existance de la place mémoire est a la charge
//  de l'utilisateur.
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::Coordonnee3H (double* t):
 CoordonneeH(3,coord3)
  { coord3[0]=t[0];
	coord3[1]=t[1];
	coord3[2]=t[2];
   };  						

// Constructeur de copie
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::Coordonnee3H (const Coordonnee3H& c):
 CoordonneeH(3,coord3)
{  coord3[0]=c.coord3[0];coord3[1]=c.coord3[1];coord3[2]=c.coord3[2];
};

// Constructeur de copie pour une instance indiférenciée
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::Coordonnee3H (const CoordonneeH& c):
 CoordonneeH(3,coord3)
{	
    #ifdef MISE_AU_POINT
	 if (c.Dimension () != 3)
		{ cout << "\nErreur la dimension de c est différente de 3 !! !\n";
		  cout << "Coordonnee3H::Coordonnee3H (const Coordonnee& c) \n";
		  Sortie(1);
		 } 
    #endif
    coord3[0]=c(1);coord3[1]=c(2);
    coord3[2]=c(3);
};

// DESTRUCTEUR :
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H::~Coordonnee3H () 
{ dim = 0; // pour l'appel de ~Coordonnee()
  #ifdef MISE_AU_POINT
    coord=NULL;
  #endif
 };
// Desallocation de la place memoire allouee
// fonction définie dans la classe mère générique mais qui n'a pas de 
// sens ici
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::Libere ()
 {       
		 #ifdef MISE_AU_POINT
		   cout << "\nErreur cette fonction n'a pas cours !! !\n";
		   cout << "Coordonnee3H::Libere () \n";
		   Sortie(1);
         #endif
  };		


// Renvoie le nombre de coordonnees
#ifndef MISE_AU_POINT
  inline 
#endif
int Coordonnee3H::Dimension ()  const
 { return 3; };
 
// changement de la dimension
// fonction définie dans la classe mère générique mais qui n'a pas de 
// sens ici
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::Change_dim(int )
  { 
		 #ifdef MISE_AU_POINT
		   cout << "\nErreur cette fonction n'a pas cours !! !\n";
		   cout << "Coordonnee3H::Change_dim(int dimen) \n";
		   Sortie(1);
         #endif
  };
  
// Surcharge de l'operateur = : realise l'affectation entre deux points 
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H& Coordonnee3H::operator= (const Coordonnee3H& c)
  {	 coord3[0]=c.coord3[0];coord3[1]=c.coord3[1];coord3[2]=c.coord3[2];
     return (*this);			
   };
  		
		
// Surcharge de l'operateur - : renvoie l'oppose d'un point
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H Coordonnee3H::operator- () const 
		{	return Coordonnee3H(-coord3[0],-coord3[1],-coord3[2]);			
		};
		
// Surcharge de l'operateur - : realise la soustraction des
// coordonnees de deux points
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H Coordonnee3H::operator- (const Coordonnee3H& c) const 
		{ return Coordonnee3H(coord3[0]-c.coord3[0],coord3[1]-c.coord3[1],
			                   coord3[2]-c.coord3[2]);			
		};
		
// Surcharge de l'operateur + : realise l'addition des 
// coordonnees de deux points
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H Coordonnee3H::operator+ (const Coordonnee3H& c) const 
		{	return Coordonnee3H(coord3[0]+c.coord3[0],coord3[1]+c.coord3[1],
			                   coord3[2]+c.coord3[2]);		
		};
		
// Surcharge de l'operateur += 
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::operator+= (const Coordonnee3H& c)
		{  coord3[0]+=c.coord3[0];
		   coord3[1]+=c.coord3[1];
		   coord3[2]+=c.coord3[2];
		};

// Surcharge de l'operateur -= 
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::operator-= (const Coordonnee3H& c)
		{ coord3[0]-=c.coord3[0];
		  coord3[1]-=c.coord3[1];
		  coord3[2]-=c.coord3[2];
		};		

// Surcharge de l'operateur *= 
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::operator*= (double val)
		{	coord3[0]*=val;coord3[1]*=val;coord3[2]*=val;
		};	
		
// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H Coordonnee3H::operator* (double val) const 
		{ return Coordonnee3H(val*coord3[0],val*coord3[1],val*coord3[2]);
		};
		
// Surcharge de l'operateur * : produit scalaire entre coordonnees 
#ifndef MISE_AU_POINT
  inline 
#endif
double Coordonnee3H::operator* (const Coordonnee3B& c) const 
 { return ( coord3[0] * c.coord3[0] + coord3[1] * c.coord3[1] +
            coord3[2] * c.coord3[2] );
  };
		
//  produit scalaire entre coordonnees contravariantes et contravariantes
#ifndef MISE_AU_POINT
  inline 
#endif
double Coordonnee3H::ScalHH(const Coordonnee3H& c) const 
 { return ( coord3[0] * c.coord3[0] + coord3[1] * c.coord3[1] +
            coord3[2] * c.coord3[2] );
  };

// Surcharge de l'operateur / : division de coordonnees par un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H Coordonnee3H::operator/ (double val) const 
 {
   #ifdef MISE_AU_POINT
    if(Dabs(val) <= ConstMath::trespetit)
    { cout << "\n erreur, division par zero ";
      cout << "\nCoordonnee3H::operator/ (double val) " << endl;
      Sortie (1);
     }
   #endif
   return Coordonnee3H(coord3[0] / val,coord3[1] / val,coord3[2] / val);  
  };
		
// Surcharge de l'operateur /= : division de coordonnees par un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::operator/= (double val)
 {
  #ifdef MISE_AU_POINT
   if(Dabs(val) <= ConstMath::trespetit)
    { cout << "\n erreur, division par zero ";
      cout << "\nCoordonnee3H::operator/= (double val) " << endl;
      Sortie (1);
     }
  #endif
   coord3[0]/=val;coord3[1]/=val;coord3[2]/=val;
  };

// Surcharge de l'operateur == : test d'egalite 
// Renvoie 1 si les deux positions sont identiques
// Renvoie 0 sinon
#ifndef MISE_AU_POINT
  inline 
#endif
int Coordonnee3H::operator== (const Coordonnee3H& c) const 
		{  if ((c.coord3[0]!=coord3[0]) || (c.coord3[1]!=coord3[1])
		        || (c.coord3[2]!=coord3[2]))
				 return 0;
		   else 
		    	 return 1;
		};


// mise a zero des coordonnées
#ifndef MISE_AU_POINT
  inline 
#endif
void Coordonnee3H::Zero() 
		 { coord3[0] = 0.;coord3[1] = 0.;coord3[2] = 0.;
		  };  
		   
// Calcul de la norme euclidienne des composantes du point
#ifndef MISE_AU_POINT
  inline 
#endif
double Coordonnee3H::Norme ()  const 
 { return sqrt( coord3[0] * coord3[0] + coord3[1] * coord3[1] +
            coord3[2] * coord3[2] );
  };
// norme le vecteur coordonnée
#ifndef MISE_AU_POINT
  inline 
#endif
Coordonnee3H& Coordonnee3H::Normer ()
 { double norme = this->Norme();
   #ifdef MISE_AU_POINT
   if(Dabs(norme) <= ConstMath::trespetit)
    { cout << "\n erreur, division par zero ";
      cout << "\nCoordonnee3H::Normer () " << endl;
      Sortie (1);
     }
  #endif
  *this /=  norme;
  return *this ;
 };
		
// somme de tous les composantes 
#ifndef MISE_AU_POINT
  inline 
#endif
double Coordonnee3H::Somme() const 
  { 
    return ( coord3[0]  + coord3[1]  + coord3[2] );
   };

/* // Surcharge de l'operateur * : multiplication entre un scalaire et des coordonnees
#ifndef MISE_AU_POINT
  inline 
#endif
 Coordonnee3H operator* (double val,const Coordonnee3H& c)
 { return Coordonnee3H(val*c.coord3[0],val*c.coord3[1],val*c.coord3[2]);}; */

#ifndef MISE_AU_POINT
  inline 
#endif
    // sortie du schemaXML: en fonction de enu 
void Coordonnee3H::SchemaXML_Coordonnee(ostream& sort,const Enum_IO_XML enu)
  {
	switch (enu)
	{ case XML_TYPE_GLOBAUX :
  	   {sort << "\n <!--  *************************** CoordonneeH dim 3 ***************************  -->"
  	         << "\n<xs:complexType name=\"COORDONNEE_3H\" >"
  	         << "\n    <xs:annotation>"
  	         << "\n      <xs:documentation> coordonnee de dimension  3: elements: "
  	         << "\n          3 reels "
  	         << "\n      </xs:documentation>"
  	         << "\n    </xs:annotation>"
  	         << "\n    <xs:sequence>"
  	         << "\n        <xs:element name=\"coordonnees\" >"
  	         << "\n            <xs:simpleType>"
  	         << "\n          	 <xs:restriction base=\"liste_de_reels\">"
  	         << "\n                <xs:minLength value=\"3\" />"
  	         << "\n                <xs:maxLength value=\"3\" />"
  	         << "\n              </xs:restriction>"  
  	         << "\n            </xs:simpleType>"
  	         << "\n        </xs:element>"
  	         << "\n    </xs:sequence>"
  	         << "\n</xs:complexType>";
		 break;
		}
		case XML_IO_POINT_INFO :
		{
		 break;
		}
		case XML_IO_POINT_BI :
		{
		 break;
		}
		case XML_IO_ELEMENT_FINI :
		{
		 break;
		}
  default: cout << "\n *** attention cas non pris en compte pour le moment "
                << " XML_TYPE_GLOBAUX= "<<XML_TYPE_GLOBAUX
                << " Coordonnee3H::SchemaXML_Coordonnee(ostream& sort,const Enum_IO_XML enu) "
                << endl;
	};		
  };


 
#endif