#include "Point_3D_impl.h"

#include "Vector_3D.h"
//#include "Affine_combination.h"
//#include "Linear_combination_handler.h"

#include <math.h>

namespace MM
{
Point_3D_impl::
Point_3D_impl (Point_3D const & v)
:
    x_(v.x()), y_(v.y()), z_(v.z())
{
}

/*Point_3D_impl::
Point_3D_impl (Point_3D_impl const & v)
:
    x_(v.x()), y_(v.y()), z_(v.z())
{
}//*/

Point_3D_impl::
Point_3D_impl (double x, double y, double z)
:
    x_(x), y_(y), z_(z)
{
}

void Point_3D_impl::
difference (Point_3D const & p, Vector_3D * result) const
{
    result->set_x (x_ - p.x());
    result->set_y (y_ - p.y());
    result->set_z (z_ - p.z());
}

void Point_3D_impl::
operator += (Vector_3D const & v)
{
    x_ += v.x();
    y_ += v.y();
    z_ += v.z();
}

void Point_3D_impl::
operator -= (Vector_3D const & v)
{
    x_ -= v.x();
    y_ -= v.y();
    z_ -= v.z();
}

void Point_3D_impl::
add_scaled (double scale, Vector_3D const& v)
{
    x_ += v.x() * scale;
    y_ += v.y() * scale;
    z_ += v.z() * scale;
}

double Point_3D_impl::
distance (Point_3D const & p) const
{
    double x =  x_ - p.x();
    double y =  y_ - p.y();
    double z =  z_ - p.z();

    return sqrt (x*x + y*y + z*z);
}

double Point_3D_impl::
distance_2 (Point_3D const & p) const
{
    double x =  x_ - p.x();
    double y =  y_ - p.y();
    double z =  z_ - p.z();

    return x*x + y*y + z*z;
}

double Point_3D_impl::
distance (Point_3D_impl const & p) const
{
    return sqrt(distance_2(p));
}

void Point_3D_impl::
affine (Point_3D const & p, double t)
{
    x_ = (1 - t) * x_ + t * p.x();
    y_ = (1 - t) * y_ + t * p.y();
    z_ = (1 - t) * z_ + t * p.z();
}
/*
void Point_3D_impl::
get (double * values) const
{
    *values++ = x_;
    *values++ = y_;
    *values++ = z_;
}

void Point_3D_impl::
set (double const* new_values)
{
    x_ = *new_values++;
    y_ = *new_values++;
    z_ = *new_values++;
}

void Point_3D_impl::
add (double const* values)
{
    x_ += *values++;
    y_ += *values++;
    z_ += *values++;
}

void Point_3D_impl::
add_scaled (double scale, double const* values)
{
    x_ += *values++ * scale;
    y_ += *values++ * scale;
    z_ += *values++ * scale;
}

void Point_3D_impl::
multiply (double value)
{
    x_ *= value;
    y_ *= value;
    z_ *= value;
}

Linear_combination_handler Point_3D_impl::
linear_combination (double a)
{
    return Linear_combination_handler (new Affine_combination (a));
}
//*/
}//MM









