// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_PARAMETRIZEDLINE_H
#define EIGEN_PARAMETRIZEDLINE_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

/** \geometry_module \ingroup Geometry_Module
 *
 * \class ParametrizedLine
 *
 * \brief A parametrized line
 *
 * A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit
 * direction vector \f$ \mathbf{d} \f$ such that the line corresponds to
 * the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ t \in \mathbf{R} \f$.
 * The origin is part of the parametrization: two ParametrizedLine objects may
 * describe the same geometric line while using different origins.
 *
 * \tparam Scalar_ the scalar type, i.e., the type of the coefficients
 * \tparam AmbientDim_ the dimension of the ambient space, can be a compile time value or Dynamic.
 */
template <typename Scalar_, int AmbientDim_, int Options_>
class ParametrizedLine {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar_, AmbientDim_)
  enum { AmbientDimAtCompileTime = AmbientDim_, Options = Options_ };
  using Scalar = Scalar_;
  using RealScalar = typename NumTraits<Scalar>::Real;
  using Index = Eigen::Index;  ///< \deprecated since Eigen 3.3
  using VectorType = Matrix<Scalar, AmbientDimAtCompileTime, 1, Options>;

  /** Default constructor without initialization */
  EIGEN_DEVICE_FUNC inline ParametrizedLine() {}

  template <int OtherOptions>
  EIGEN_DEVICE_FUNC ParametrizedLine(const ParametrizedLine<Scalar, AmbientDimAtCompileTime, OtherOptions>& other)
      : m_origin(other.origin()), m_direction(other.direction()) {}

  /** Constructs a dynamic-size line with \a _dim the dimension
   * of the ambient space */
  EIGEN_DEVICE_FUNC inline explicit ParametrizedLine(Index _dim) : m_origin(_dim), m_direction(_dim) {}

  /** Initializes a parametrized line of direction \a direction and origin \a origin.
   * \warning the origin is part of the parametrization and is not canonicalized.
   * \warning the vector direction is assumed to be normalized.
   */
  EIGEN_DEVICE_FUNC ParametrizedLine(const VectorType& origin, const VectorType& direction)
      : m_origin(origin), m_direction(direction) {}

  template <int OtherOptions>
  EIGEN_DEVICE_FUNC explicit ParametrizedLine(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane);

  /** Constructs a parametrized line going from \a p0 to \a p1. */
  EIGEN_DEVICE_FUNC static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1) {
    return ParametrizedLine(p0, (p1 - p0).normalized());
  }

  /** \returns the dimension in which the line holds */
  EIGEN_DEVICE_FUNC inline Index dim() const { return m_direction.size(); }

  EIGEN_DEVICE_FUNC const VectorType& origin() const { return m_origin; }
  EIGEN_DEVICE_FUNC VectorType& origin() { return m_origin; }

  EIGEN_DEVICE_FUNC const VectorType& direction() const { return m_direction; }
  EIGEN_DEVICE_FUNC VectorType& direction() { return m_direction; }

  /** \returns the squared distance of a point \a p to its projection onto the line \c *this.
   * \sa distance()
   */
  EIGEN_DEVICE_FUNC RealScalar squaredDistance(const VectorType& p) const {
    VectorType diff = p - origin();
    return (diff - direction().dot(diff) * direction()).squaredNorm();
  }
  /** \returns the distance of a point \a p to its projection onto the line \c *this.
   * \sa squaredDistance()
   */
  EIGEN_DEVICE_FUNC RealScalar distance(const VectorType& p) const {
    EIGEN_USING_STD(sqrt) return sqrt(squaredDistance(p));
  }

  /** \returns the projection of a point \a p onto the line \c *this. */
  EIGEN_DEVICE_FUNC VectorType projection(const VectorType& p) const {
    return origin() + direction().dot(p - origin()) * direction();
  }

  EIGEN_DEVICE_FUNC VectorType pointAt(const Scalar& t) const;

  template <int OtherOptions>
  EIGEN_DEVICE_FUNC Scalar
  intersectionParameter(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const;

  template <int OtherOptions>
  EIGEN_DEVICE_FUNC Scalar intersection(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const;

  template <int OtherOptions>
  EIGEN_DEVICE_FUNC VectorType
  intersectionPoint(const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const;

  /** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this.
   *
   * \param mat the Dim x Dim transformation matrix
   * \param traits specifies whether the matrix \a mat represents an #Isometry
   *               or a more generic #Affine transformation. The default is #Affine.
   */
  template <typename XprType>
  EIGEN_DEVICE_FUNC inline ParametrizedLine& transform(const MatrixBase<XprType>& mat,
                                                       TransformTraits traits = Affine) {
    if (traits == Affine)
      direction() = (mat * direction()).normalized();
    else if (traits == Isometry)
      direction() = mat * direction();
    else {
      eigen_assert(0 && "invalid traits value in ParametrizedLine::transform()");
    }
    origin() = mat * origin();
    return *this;
  }

  /** Applies the transformation \a t to \c *this and returns a reference to \c *this.
   *
   * \param t the transformation of dimension Dim
   * \param traits specifies whether the transformation \a t represents an #Isometry
   *               or a more generic #Affine transformation. The default is #Affine.
   *               Other kind of transformations are not supported.
   */
  template <int TrOptions>
  EIGEN_DEVICE_FUNC inline ParametrizedLine& transform(
      const Transform<Scalar, AmbientDimAtCompileTime, Affine, TrOptions>& t, TransformTraits traits = Affine) {
    transform(t.linear(), traits);
    origin() += t.translation();
    return *this;
  }

  /** \returns \c *this with scalar type casted to \a NewScalarType
   *
   * Note that if \a NewScalarType is equal to the current scalar type of \c *this
   * then this function smartly returns a const reference to \c *this.
   */
  template <typename NewScalarType>
  EIGEN_DEVICE_FUNC inline
      typename internal::cast_return_type<ParametrizedLine,
                                          ParametrizedLine<NewScalarType, AmbientDimAtCompileTime, Options> >::type
      cast() const {
    return typename internal::cast_return_type<
        ParametrizedLine, ParametrizedLine<NewScalarType, AmbientDimAtCompileTime, Options> >::type(*this);
  }

  /** Copy constructor with scalar type conversion */
  template <typename OtherScalarType, int OtherOptions>
  EIGEN_DEVICE_FUNC inline explicit ParametrizedLine(
      const ParametrizedLine<OtherScalarType, AmbientDimAtCompileTime, OtherOptions>& other) {
    m_origin = other.origin().template cast<Scalar>();
    m_direction = other.direction().template cast<Scalar>();
  }

  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
   * determined by \a prec.
   *
   * \note This compares both origins and directions. Lines that represent the same set of
   * points but use different origins are not considered approximately equal by this method.
   *
   * \sa MatrixBase::isApprox() */
  EIGEN_DEVICE_FUNC bool isApprox(const ParametrizedLine& other, const typename NumTraits<Scalar>::Real& prec =
                                                                     NumTraits<Scalar>::dummy_precision()) const {
    return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec);
  }

 protected:
  VectorType m_origin, m_direction;
};

/** Constructs a parametrized line from a 2D hyperplane
 *
 * \warning the ambient space must have dimension 2 such that the hyperplane actually describes a line
 */
template <typename Scalar_, int AmbientDim_, int Options_>
template <int OtherOptions>
EIGEN_DEVICE_FUNC inline ParametrizedLine<Scalar_, AmbientDim_, Options_>::ParametrizedLine(
    const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) {
  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
  direction() = hyperplane.normal().unitOrthogonal();
  origin() = -hyperplane.normal() * hyperplane.offset();
}

/** \returns the point at \a t along this line
 */
template <typename Scalar_, int AmbientDim_, int Options_>
EIGEN_DEVICE_FUNC inline typename ParametrizedLine<Scalar_, AmbientDim_, Options_>::VectorType
ParametrizedLine<Scalar_, AmbientDim_, Options_>::pointAt(const Scalar_& t) const {
  return origin() + direction() * t;
}

/** \returns the parameter value of the intersection between \c *this and the given \a hyperplane
 */
template <typename Scalar_, int AmbientDim_, int Options_>
template <int OtherOptions>
EIGEN_DEVICE_FUNC inline Scalar_ ParametrizedLine<Scalar_, AmbientDim_, Options_>::intersectionParameter(
    const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const {
  return -(hyperplane.offset() + hyperplane.normal().dot(origin())) / hyperplane.normal().dot(direction());
}

/** \deprecated use intersectionParameter()
 * \returns the parameter value of the intersection between \c *this and the given \a hyperplane
 */
template <typename Scalar_, int AmbientDim_, int Options_>
template <int OtherOptions>
EIGEN_DEVICE_FUNC inline Scalar_ ParametrizedLine<Scalar_, AmbientDim_, Options_>::intersection(
    const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const {
  return intersectionParameter(hyperplane);
}

/** \returns the point of the intersection between \c *this and the given hyperplane
 */
template <typename Scalar_, int AmbientDim_, int Options_>
template <int OtherOptions>
EIGEN_DEVICE_FUNC inline typename ParametrizedLine<Scalar_, AmbientDim_, Options_>::VectorType
ParametrizedLine<Scalar_, AmbientDim_, Options_>::intersectionPoint(
    const Hyperplane<Scalar_, AmbientDim_, OtherOptions>& hyperplane) const {
  return pointAt(intersectionParameter(hyperplane));
}

}  // end namespace Eigen

#endif  // EIGEN_PARAMETRIZEDLINE_H
