#ifndef PASTELGEOMETRY_LINE_HPP
#define PASTELGEOMETRY_LINE_HPP
#include "pastel/geometry/shape/line.h"
#include "pastel/sys/vector.h"
#include "pastel/sys/vector/vector_tools.h"
namespace Pastel
{
template <typename Real, integer N>
Line<Real, N>::Line()
: position_(0)
, direction_(unitAxis<Real, N>(0))
, inverseDirection_(inverse(direction_))
{
PASTEL_STATIC_ASSERT(N != Dynamic);
}
template <typename Real, integer N>
Line<Real, N>::Line(integer dimension)
: position_(ofDimension(dimension), 0)
, direction_(unitAxis<Real, N>(dimension, 0))
, inverseDirection_(inverse(direction_))
{
}
template <typename Real, integer N>
Line<Real, N>::Line(
const Vector<Real, N>& position,
const Vector<Real, N>& unitDirection)
: position_(position)
, direction_(unitDirection)
, inverseDirection_(inverse(unitDirection))
{
PASTEL_STATIC_ASSERT(N != Dynamic);
}
template <typename Real, integer N>
Line<Real, N>::Line(
integer dimension,
const Vector<Real, N>& position,
const Vector<Real, N>& unitDirection)
: position_(position)
, direction_(unitDirection)
, inverseDirection_(inverse(unitDirection))
{
PENSURE_OP(dimension, ==, position.n());
PENSURE_OP(dimension, ==, unitDirection.n());
}
template <typename Real, integer N>
Line<Real, N>::~Line()
{
PASTEL_STATIC_ASSERT(N == Dynamic || N > 0);
}
template <typename Real, integer N>
void Line<Real, N>::swap(Line<Real, N>& that)
{
using std::swap;
using std::swap;
swap(position_, that.position_);
swap(direction_, that.direction_);
swap(inverseDirection_, that.inverseDirection_);
}
template <typename Real, integer N>
integer Line<Real, N>::n() const
{
return position_.n();
}
template <typename Real, integer N>
void Line<Real, N>::set(
const Vector<Real, N>& position,
const Vector<Real, N>& unitDirection)
{
setPosition(position);
setDirection(unitDirection);
}
template <typename Real, integer N>
void Line<Real, N>::setPosition(
const Vector<Real, N>& position)
{
PENSURE_OP(position_.n(), ==, position.n());
position_ = position;
}
template <typename Real, integer N>
const Vector<Real, N>& Line<Real, N>::position() const
{
return position_;
}
template <typename Real, integer N>
void Line<Real, N>::setDirection(
const Vector<Real, N>& unitDirection)
{
PENSURE_OP(direction_.n(), ==, unitDirection.n());
direction_ = unitDirection;
inverseDirection_ =
inverse(unitDirection);
}
template <typename Real, integer N>
const Vector<Real, N>& Line<Real, N>::direction() const
{
return direction_;
}
template <typename Real, integer N>
const Vector<Real, N>& Line<Real, N>::inverseDirection() const
{
return inverseDirection_;
}
template <typename Real, integer N>
Vector<Real, N> Line<Real, N>::at(const Real& t) const
{
return position_ + direction_ * t;
}
template <typename Real, integer N>
Line<Real, N>& Line<Real, N>::operator+=(
const Vector<Real, N>& that)
{
position_ += that;
return *this;
}
template <typename Real, integer N>
Line<Real, N>& Line<Real, N>::operator-=(
const Vector<Real, N>& that)
{
position_ -= that;
return *this;
}
template <typename Real, integer N>
Line<Real, N>& Line<Real, N>::operator*=(
const Real& that)
{
// Do nothing.
unused(that);
return *this;
}
template <typename Real, integer N>
Line<Real, N>& Line<Real, N>::operator/=(
const Real& that)
{
PENSURE_OP(that, !=, 0);
// Do nothing.
return *this;
}
}
#endif