line.hpp

Back to Line

pastel/geometry/shape/

#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