/*-------------------------------------------------------------*/
/* CVector3.h :   Fichier contenant la définition de la classe */
/*                CVector3 et également la surcharge des	   */
/*                opérateurs sur les vecteurs.                 */
/*-------------------------------------------------------------*/

#ifndef CVECTOR3_H
#define CVECTOR3_H

class CVector3
{
public:
	float x, y, z;

	// Constructeur par paramètres et par défaut
	inline CVector3(float a = 0, float b = 0, float c = 0) { x = a; y = b; z = c; }
	// Calcule et retourne la norme du vecteur
	inline float Norm() { return(sqrt(x*x + y*y + z*z)); }
	// Normalise le vecteur
	inline void Normalize() 
	{ float Temp = sqrt(x*x + y*y + z*z); x /= Temp; y /= Temp; z /= Temp; }
};

// Addition de deux vecteurs
inline CVector3 operator + (const CVector3 &v1, const CVector3 &v2)
{
	return CVector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}

// Soustraction de deux vecteurs
inline CVector3 operator - (const CVector3 &v1, const CVector3 &v2)
{
	return CVector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}

// Produit scalaire de deux vecteurs
inline float operator * (const CVector3 &v1, const CVector3 &v2)
{
	return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}

// Produit vectoriel de deux vecteurs
inline CVector3 operator ^ (const CVector3 &v1, const CVector3 &v2)
{
	return CVector3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
}

// Produit d'un vecteur par un scalaire
inline CVector3 operator * (const CVector3 &v, float k)
{
	return CVector3(k*v.x, k*v.y, k*v.z);
}

// Produit d'un scalaire par un vecteur
inline CVector3 operator * (float k, const CVector3 &v)
{
	return CVector3(k*v.x, k*v.y, k*v.z);
}

// Division d'un vecteur par un scalaire
inline CVector3 operator / (const CVector3 &v, float k)
{
	return CVector3(v.x/k, v.y/k, v.z/k);
}

// Projection d'un vecteur sur un autre vecteur
inline CVector3 operator >> (const CVector3 &v1, const CVector3 &v2)
{
	float Temp = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z) / (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z);
	return CVector3(Temp*v2.x, Temp*v2.y, Temp*v2.z);
}


// Opposé d'un vecteur
inline CVector3 operator - (const CVector3 &v)
{
	return CVector3(-v.x, -v.y, -v.z);
}


// Opérateurs combinés à l'égalité
inline CVector3& operator += (CVector3 &v1, const CVector3 &v2)
{
	v1.x += v2.x;
	v1.y += v2.y;
	v1.z += v2.z;
	return v1;
}

inline CVector3& operator -= (CVector3 &v1, const CVector3 &v2)
{
	v1.x -= v2.x;
	v1.y -= v2.y;
	v1.z -= v2.z;
	return v1;
}

inline CVector3& operator ^= (CVector3 &v1, const CVector3 &v2)
{
	v1 = CVector3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
	return v1;
}

inline CVector3& operator *= (CVector3 &v, float k)
{
	v.x *= k;
	v.y *= k;
	v.z *= k;
	return v;
}

inline CVector3& operator /= (CVector3 &v, float k)
{
	v.x /= k;
	v.y /= k;
	v.z /= k;
	return v;
}

inline CVector3& operator >>= (CVector3 &v1, const CVector3 &v2)
{
	float Temp = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z) / (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z);
	v1.x = v2.x * Temp;
	v1.y = v2.y * Temp;
	v1.z = v2.z * Temp;
	return v1;
}


#endif
