#include "point.hpp"

//constructeur
point::point()
{
    _x = _y = _z = 0;
}

point::point(float X, float Y, float Z)
{
    _x = X;
    _y = Y;
    _z = Z;
}

//getteur
void point::setX(float X)
{
    _x = X;
}

void point::setY(float Y)
{
    _y = Y;
}

void point::setZ(float Z)
{
    _z = Z;
}

//getteur

float point::getX()const
{
    return _x;
}

float point::getY()const
{
    return _y;
}

float point::getZ()const
{
    return _z;
}

//======================================Operations sur les points===============================================
//adition de deux points
const point point::_add(const point& p) const
{
    return point (_x+p._x, _y+p._y, _z+p._z);
}

//soustraction de deux points
const point point::_sous(const point& p) const
{
    return point (_x-p._x, _y-p._y, _z-p._z);
}

//=================================Operation avec scalaires================================
//multiplication par un scalaire
const point point::_somS(float scalaire) const
{
    return point (_x*scalaire, _y*scalaire, _z*scalaire);
}

//division par un scalaire
const point point::_divS (float scalaire) const
{
    return point (_x/scalaire, _y/scalaire, _z/scalaire);
}

//-----------------------------Rotation------------------------------------------------
//petite modif par martin par soucil d'uniformité, fonction retour,
//pluto que methode mutator,
//ainsi eliminer l'appel de deux fois les fonctions trigonometrique
//qui sont lourde
//rotation sur les X
const point point::rotX(float angle)const
{
//    _y = (_y*cos(angle) - _z*sin(angle));
//    _z = (_y*sin(angle) - _z*cos(angle)); <==+
    double s = sin(angle),  //le caller deux fois c'est aussi long qu'une SQRT
           c = cos(angle);
    return point( _x, _y*c - _z*s , _y*s + _z*c);
}

 //rotation sur les Y
const point point::rotY(float angle)const
{
//    _z = (_z*cos(angle) - _x*sin(angle));
//    _x = (_z*sin(angle) - _x*cos(angle)); <== +
    double s = sin(angle),  //le caller deux fois c'est aussi long qu'une SQRT
           c = cos(angle);
    return point(_z*s + _x*c, _y, _z*c - _x*s);
}

//rotation sur les Z
const point point::rotZ(float angle)const
{
//    _x = (_x*cos(angle) - _y*sin(angle));
//    _y = (_x*sin(angle) - _y*cos(angle)); <== +
    double s = sin(angle),  //le caller deux fois c'est aussi long qu'une SQRT
           c = cos(angle);
    return point(_x*c - _y*s, _x*s + _y*c, _z);
}

 //==================================Cross Product===============================================================
const point point::cross(const point& p) const
 {
     return point((_y * p._z)-(p._y * _z),
                  (_z * p._x)-(p._z * _x),
                  (_x * p._y)-(p._x * _y));
 }

//===================================magnitude SQ========================
//par Martin
//ce n'est rien d'autre que hypothenuse sans la racine carré
float point::magSQ()const
{
    return _x*_x + _y*_y + _z*_z;
}

//methode the deudeeification du point      MARTIN
const point point::deuxdee(float magnification, float zfactor)const
{
    return point(_x*magnification/_z*zfactor, _y*magnification/_z*zfactor ,1);
}

//-----------------------------------Les Methodes qui servent presque a rien-------------------------------------
//affichage des points
//void point::print(ostream& out)const
//{
//    out<<"X: "<<_x<<" Y: "<<_y<<" Z: "<<_z;
//}
//======================================Surcharges des operateurs externes=======================================
const point point::operator+(const point& p) const
{
    point temp = _add(p);
    return temp;
}

const point point::operator-(const point& p) const
{
    point temp = _sous(p);
    return temp;
}

const point point::operator*(float scaliare) const
{
    point temp = _somS(scaliare);
    return temp;
}

const point point::operator/(float scaliare) const
{
    point temp = _divS(scaliare);
    return temp;
}

//======================================Surcharges des operateurs externes=======================================
//ostream& operator << (ostream& out, const point& p)
//{
//    p.print(out);
//    return out;
//}
//
//istream& operator >> (istream& in, point& p)
//{
//    char c;
//    in >> c >> p._x
//       >> c >> p._y
//       >> c >> p._z
//       >> c;
//    return in;
//}
