/* Mathematiques de l'informatique graphique    */
/* Direction en 3D                              */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Mars 2019                                    */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "CH3D.h"
#include "Dir3D.h"
#include "Pos3D.h"

/* Constructeurs                                */
Dir3D::Dir3D(void):CH3D(0.0,0.0,0.0,0.0) {
}

Dir3D::Dir3D(double x,double y,double z):CH3D(x,y,z,0.0) {
}

Dir3D::Dir3D(Dir3D *p):CH3D(p) {
}

Dir3D::Dir3D(Pos3D *pi,Pos3D *pf):CH3D() {
  x = pf->x-pi->x;
  y = pf->y-pi->y;
  z = pf->z-pi->z;
  w = 0.0;
}

/* Destructeur                                  */
Dir3D::~Dir3D(void) {
}

/* Methode de calcul de la norme de this        */
double Dir3D::norme(void) {
  return(sqrt(x*x+y*y+z*z));
}

/* Methode de normalisation de this             */
void Dir3D::normalisation(void) {
  double d = norme();
  if ( d != 0.0 ) {
    x /= d;
    y /= d;
    z /= d; }
}

/* Methode de calcul du produit scalaire        */
/* de this et de la direction d                 */
double Dir3D::produitScalaire(Dir3D *d) {
  return(produitScalaire(this,d));
}

/* Methode statique de calcul                   */
/* du produit scalaire des deux directions      */
/* d1 et d2                                     */
double Dir3D::produitScalaire(Dir3D *d1,Dir3D *d2) {
  return(d1->x*d2->x+d1->y*d2->y+d1->z*d2->z);
}

/* Methode de calcul du produit vectoriel       */
/* de this par la direction d                   */
/* avec stockage du resultat dans this          */
void Dir3D::produitVectoriel(Dir3D *d) {
  produitVectoriel(this,d,this);
}

/* Methode de calcul du produit vectoriel       */
/* de this par la direction d                   */
/* avec stockage du resultat dans res           */
void Dir3D::produitVectoriel2(Dir3D *d,Dir3D *res) {
  produitVectoriel(this,d,res);
}

/* Methode statique de calcul                   */
/* du produit vectoriel de deux directions      */
/* d1 et d2                                     */
/* Retour d'un objet Dir3D                      */
/* cree dans la methode                         */
Dir3D *Dir3D::produitVectoriel(Dir3D *d1,Dir3D *d2) {
  Dir3D *d = new Dir3D();
  produitVectoriel(d1,d2,d);
  return d;
}

/* Methode statique de calcul                   */
/* du produit vectoriel de deux directions      */
/* d1 et d2 avec Stockage du resultat           */
/* dans res                                     */
void Dir3D::produitVectoriel(Dir3D *d1,Dir3D *d2,Dir3D *res) {
  double x = d1->y*d2->z - d1->z*d2->y;
  double y = d1->z*d2->x - d1->x*d2->z;
  double z = d1->x*d2->y - d1->y*d2->x;
  res->x = x;
  res->y = y;
  res->z = z;
  res->w = 0.0;
}
