// FICHIER : Coordonnee3.h
// CLASSE : Coordonnee3

// 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-2021 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/>.

/************************************************************************
*     DATE:        23/01/97                                            *
*                                                                $     *
*     AUTEUR:      G RIO                                               *
*                                                                $     *
*     PROJET:      Herezh++                                            *
*                                                                $     *
************************************************************************
* BUT: Les classes Coordonnee3 servent a la localisation dans l'espace *
*     3D des objets tels que les noeuds ou les points. Ces classes     *
*     dérivent des Classes génériques Coordonnee.                      *
*                                                                $     *
*     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
************************************************************************/

                                                    

#ifndef COORDONNEE3_H
#define COORDONNEE3_H


//#include "Debug.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "Sortie.h"
#include "Coordonnee.h"

/** @defgroup Les_classes_coordonnee3
*
* BUT: Les classes Coordonnee1 servent a la localisation dans l'espace
*     3D des objets tels que les noeuds ou les points. Ces classes
*     dérivent des Classes génériques Coordonnee.
* \author    Gérard Rio
* \version   1.0
* \date       23/01/97
* \brief       Définition des classes de type Coordonnee3, en coordonnées sans variance (ex:  absolues)
*  ou en coordonnées locales c'est-à-dire en coordonnées covariantes ou contravariantes. Ces classes sont une spécialisation 3D des classes générales Coordonnee
 *
 */



/// @addtogroup Les_classes_coordonnee3
///  @{
///
//==============================================================================
//!    cas des coordonnées simples sans variance
//==============================================================================


class Coordonnee3 : public Coordonnee
{ 

	public :
  /// Surcharge de l'operateur * : multiplication entre un scalaire et des coordonnees
  inline friend Coordonnee3 operator* (double val,const Coordonnee3& c)
    { return Coordonnee3(val*c.coord3[0],val*c.coord3[1],val*c.coord3[2]);};
   // CONSTRUCTEURS :
		
  /*! \brief
  // Constructeur par defaut
		// il y a initialisation des coordonnées à zéro par défaut */
		Coordonnee3 ();		
  /*! \brief
  // 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 */
		Coordonnee3 (bool test );		
		/// Constructeur pour une localisation tridimensionnelle
		Coordonnee3 (double x,double y,double z);
  /*! \brief
  // constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
		//  ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur !!). */
		Coordonnee3 (double* t);						
  /// Constructeur fonction d'un vecteur qui doit avoir une  3
		Coordonnee3 ( const Vecteur& vec);
  /// Constructeur de copie
		Coordonnee3 (const Coordonnee3& c);
  /// Constructeur de copie pour une instance indiférenciée
		Coordonnee3 (const Coordonnee& c);
				
  /// DESTRUCTEUR :
		virtual ~Coordonnee3 () ;
		
		// METHODES :
		
  /// Renvoie le nombre de coordonnees
		int Dimension () const ;
		
  /*! \brief
  // 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 */
  void Libere ();
        
		// Renvoie le nombre de coordonnees
		//int Dimension () const ;
  
  /*! \brief
  // changement de la dimension
  // fonction définie dans la classe mère générique mais qui n'a pas de 
  // sens ici, affiche un message d'erreur */
		void Change_dim(int dim);		
		
  /// Surcharge de l'operateur = : realise l'affectation entre deux points
		Coordonnee3& operator= (const Coordonnee3& c);
		
  /// Surcharge de l'operateur - : renvoie l'oppose d'un point
		Coordonnee3 operator- () const ;
		
  /*! \brief
  // Surcharge de l'operateur - : realise la soustraction des
		// coordonnees de deux points */
		Coordonnee3 operator- (const Coordonnee3& c) const ;
		
  /*! \brief
  // Surcharge de l'operateur + : realise l'addition des
		// coordonnees de deux points */
		Coordonnee3 operator+ (const Coordonnee3& c) const ;
		
  /// Surcharge de l'operateur +=
		void operator+= (const Coordonnee3& c);

  /// Surcharge de l'operateur -=
		void operator-= (const Coordonnee3& c);

  /// Surcharge de l'operateur *=
		void operator*= (double val);
		
  /// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
		Coordonnee3 operator* (double val) const ;
		
  /// Surcharge de l'operateur * : produit scalaire entre coordonnees
		double operator* (const Coordonnee3& c) const ;
		
  /// Surcharge de l'operateur / : division de coordonnees par un scalaire
		Coordonnee3 operator/ (double val) const  ;
		
  /// Surcharge de l'operateur /= : division de coordonnees par un scalaire
		void operator/= (double val) ;

  /*! \brief
  // Surcharge de l'operateur == : test d'egalite
		// Renvoie 1 si les deux positions sont identiques
		// Renvoie 0 sinon */
		int operator== (const Coordonnee3& c) const; 

  /// conversion en Vecteur
  Vecteur Vect() const ;
        
  /// mise a zero des coordonnées
		void Zero() ; 
		
  /// Calcul de la norme euclidienne des composantes du point
		double Norme ()  const ;
		
  /// norme le vecteur coordonnée
		Coordonnee3& Normer ();
		
  /// somme de tous les composantes
		double Somme() const ;
 
  /// sortie du schemaXML: en fonction de enu
  static void SchemaXML_Coordonnee(ofstream& sort,const Enum_IO_XML enu) ;
		
	protected :
	
		double coord3[3];
		
};
/// @}  // end of group

/// @addtogroup Les_classes_coordonnee3
///  @{
///


class Coordonnee3B;  // défini par la suite ( nécessaire pour le produit scalaire)

//==============================================================================
//!    cas des coordonnées contravariantes
//==============================================================================

class Coordonnee3H : public CoordonneeH
{ 

	public :
	 friend class Coordonnee3B;
  /// Surcharge de l'operateur * : multiplication entre un scalaire et des coordonnees
  inline friend Coordonnee3H operator* (double val,const Coordonnee3H& c)
      { return Coordonnee3H(val*c.coord3[0],val*c.coord3[1],val*c.coord3[2]);};
      
      // CONSTRUCTEURS :
		
  /*! \brief
  // Constructeur par defaut
		// il y a initialisation des coordonnées à zéro par défaut */
		Coordonnee3H ();		
  /*! \brief
  // 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 */
		Coordonnee3H (bool test );		
  /// Constructeur pour une localisation tridimensionnelle
		Coordonnee3H (double x,double y,double z);
  /*! \brief
  // constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
		//  ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur !!). */
		Coordonnee3H (double* t);						
  /// Constructeur fonction d'un vecteur qui doit avoir une  3
		Coordonnee3H ( const Vecteur& vec);
  /// Constructeur de copie
		Coordonnee3H (const Coordonnee3H& c);
  /// Constructeur de copie pour une instance indiférenciée
		Coordonnee3H (const CoordonneeH& c);
				
  /// DESTRUCTEUR :
		virtual ~Coordonnee3H () ;
		
		// METHODES :
		
  /// Renvoie le nombre de coordonnees
		int Dimension () const ;
		
  /*! \brief
  // 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 */
  void Libere ();
        
		// Renvoie le nombre de coordonnees
		//int Dimension () const ;
  
  /*! \brief
  // changement de la dimension
  // fonction définie dans la classe mère générique mais qui n'a pas de 
  // sens ici, affiche un message d'erreur */
		void Change_dim(int dim);		
		
  /// Surcharge de l'operateur = : realise l'affectation entre deux points
		Coordonnee3H& operator= (const Coordonnee3H& c);
		
  /// Surcharge de l'operateur - : renvoie l'oppose d'un point
		Coordonnee3H operator- () const ;
		
  /*! \brief
  // Surcharge de l'operateur - : realise la soustraction des
		// coordonnees de deux points */
		Coordonnee3H operator- (const Coordonnee3H& c) const ;
		
  /*! \brief
  // Surcharge de l'operateur + : realise l'addition des
		// coordonnees de deux points */
		Coordonnee3H operator+ (const Coordonnee3H& c) const ;
		
  /// Surcharge de l'operateur +=
		void operator+= (const Coordonnee3H& c);

  /// Surcharge de l'operateur -=
		void operator-= (const Coordonnee3H& c);

  /// Surcharge de l'operateur *=
		void operator*= (double val);
		
  /// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
		Coordonnee3H operator* (double val) const ;
		
  /// Surcharge de l'operateur * : produit scalaire entre coordonnees
		double operator* (const Coordonnee3B& c) const ;
		
  ///  produit scalaire entre coordonnees contravariantes et contravariantes
		double ScalHH(const Coordonnee3H& c) const ;

  /// Surcharge de l'operateur / : division de coordonnees par un scalaire
		Coordonnee3H operator/ (double val) const  ;
		
  /// Surcharge de l'operateur /= : division de coordonnees par un scalaire
		void operator/= (double val) ;

  /*! \brief
  // Surcharge de l'operateur == : test d'egalite
		// Renvoie 1 si les deux positions sont identiques
		// Renvoie 0 sinon */
		int operator== (const Coordonnee3H& c) const; 

  ///  conversion en Vecteur
  Vecteur Vect() const ;
        
  /// mise a zero des coordonnées
		void Zero() ; 
		
  /// Calcul de la norme euclidienne des composantes du point
		double Norme ()  const ;
		
  /// norme le vecteur coordonnée
		Coordonnee3H& Normer ();
		
  /// somme de tous les composantes
		double Somme() const ;
 
  /// sortie du schemaXML: en fonction de enu
  static void SchemaXML_Coordonnee(ofstream& sort,const Enum_IO_XML enu) ;
		
	protected :
	
		double coord3[3];
		
};

/// @}  // end of group

/// @addtogroup Les_classes_coordonnee3
///  @{
///
//==============================================================================
//!    cas des coordonnées covariantes
//==============================================================================

class Coordonnee3B : public CoordonneeB
{ 

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

      // CONSTRUCTEURS :
		
  /*! \brief
  // Constructeur par defaut
		// il y a initialisation des coordonnées à zéro par défaut */
		Coordonnee3B ();		
  /*! \brief
  // 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 */
		Coordonnee3B (bool test );		
  /// Constructeur pour une localisation tridimensionnelle
		Coordonnee3B (double x,double y,double z);
  /*! \brief
  // constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
		//  ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur !!). */
		Coordonnee3B (double* t);						
  /// Constructeur fonction d'un vecteur qui doit avoir une  3
		Coordonnee3B ( const Vecteur& vec);
  /// Constructeur de copie
		Coordonnee3B (const Coordonnee3B& c);
  /// Constructeur de copie pour une instance indiférenciée
		Coordonnee3B (const CoordonneeB& c);
				
  /// DESTRUCTEUR :
		virtual ~Coordonnee3B () ;
		
		// METHODES :
		
  /// Renvoie le nombre de coordonnees
		int Dimension () const ;
		
  /*! \brief
  // 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 */
  void Libere ();
        
		// Renvoie le nombre de coordonnees
		//int Dimension () const ;
  
  /*! \brief
  // changement de la dimension
  // fonction définie dans la classe mère générique mais qui n'a pas de 
  // sens ici, affiche un message d'erreur */
		void Change_dim(int dim);		
		
  /// Surcharge de l'operateur = : realise l'affectation entre deux points
		Coordonnee3B& operator= (const Coordonnee3B& c);
		
  /// Surcharge de l'operateur - : renvoie l'oppose d'un point
		Coordonnee3B operator- () const ;
		
  /*! \brief
  // Surcharge de l'operateur - : realise la soustraction des
		// coordonnees de deux points */
		Coordonnee3B operator- (const Coordonnee3B& c) const ;
		
  /*! \brief
  // Surcharge de l'operateur + : realise l'addition des
		// coordonnees de deux points */
		Coordonnee3B operator+ (const Coordonnee3B& c) const ;
		
  /// Surcharge de l'operateur +=
		void operator+= (const Coordonnee3B& c);

  /// Surcharge de l'operateur -=
		void operator-= (const Coordonnee3B& c);

  /// Surcharge de l'operateur *=
		void operator*= (double val);
		
  /// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
		Coordonnee3B operator* (double val) const ;
		
  /// Surcharge de l'operateur * : produit scalaire entre coordonnees
		double operator* (const Coordonnee3H& c) const ;
		
  ///  produit scalaire entre coordonnees covariantes et covariantes
		double ScalBB(const Coordonnee3B& c) const ;

  /// Surcharge de l'operateur / : division de coordonnees par un scalaire
		Coordonnee3B operator/ (double val) const  ;
		
  /// Surcharge de l'operateur /= : division de coordonnees par un scalaire
		void operator/= (double val) ;

  /*! \brief
  // Surcharge de l'operateur == : test d'egalite
		// Renvoie 1 si les deux positions sont identiques
		// Renvoie 0 sinon */
		int operator== (const Coordonnee3B& c) const; 

  ///  conversion en Vecteur
  Vecteur Vect() const ;
        
  /// mise a zero des coordonnées
		void Zero() ; 
		
  /// Calcul de la norme euclidienne des composantes du point
		double Norme ()  const ;
		
  /// norme le vecteur coordonnée
		Coordonnee3B& Normer ();
		
  /// somme de tous les composantes
		double Somme() const ;
  
  /// sortie du schemaXML: en fonction de enu
  static void SchemaXML_Coordonnee(ofstream& sort,const Enum_IO_XML enu) ;
		
  /// calcul du produit mixte de trois vecteurs coordonnées
  static double Determinant3B( const Coordonnee3B & v1, const Coordonnee3B & v2, const Coordonnee3B & v3);

  /// calcul du produit vectoriel de 2 vecteurs coordonnées
  static Coordonnee3H Vectoriel( const Coordonnee3B & v1, const Coordonnee3B & v2);
		
	protected :
	
		double coord3[3];
		
};
/// @}  // end of group

#ifndef MISE_AU_POINT
  #include "Coordonnee3.cc"
  #include "Coordonnee3H.cc"
  #include "Coordonnee3B.cc"
  #define  COORDONNEE3_H_deja_inclus
#endif

#endif
