// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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_ANGLEAXIS_H
#define EIGEN_ANGLEAXIS_H

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

namespace Eigen {

/** \geometry_module \ingroup Geometry_Module
 *
 * \class AngleAxis
 *
 * \brief Represents a 3D rotation as a rotation angle around an arbitrary 3D axis
 *
 * \param Scalar_ the scalar type, i.e., the type of the coefficients.
 *
 * \warning When setting up an AngleAxis object, the axis vector \b must \b be \b normalized.
 *
 * The following two typedefs are provided for convenience:
 * \li \c AngleAxisf for \c float
 * \li \c AngleAxisd for \c double
 *
 * Combined with MatrixBase::Unit{X,Y,Z}, AngleAxis can be used to easily
 * mimic Euler-angles. Here is an example:
 * \include AngleAxis_mimic_euler.cpp
 * Output: \verbinclude AngleAxis_mimic_euler.out
 *
 * \note This class is not aimed to be used to store a rotation transformation,
 * but rather to make easier the creation of other rotation (Quaternion, rotation Matrix)
 * and transformation objects.
 *
 * \sa class Quaternion, class Transform, MatrixBase::UnitX()
 */

namespace internal {
template <typename Scalar_>
struct traits<AngleAxis<Scalar_> > {
  using Scalar = Scalar_;
};
}  // namespace internal

template <typename Scalar_>
class AngleAxis : public RotationBase<AngleAxis<Scalar_>, 3> {
  using Base = RotationBase<AngleAxis<Scalar_>, 3>;

 public:
  using Base::operator*;

  enum { Dim = 3 };
  /** the scalar type of the coefficients */
  using Scalar = Scalar_;
  using Matrix3 = Matrix<Scalar, 3, 3>;
  using Vector3 = Matrix<Scalar, 3, 1>;
  using QuaternionType = Quaternion<Scalar>;

 protected:
  Vector3 m_axis;
  Scalar m_angle;

 public:
  /** Default constructor without initialization. */
  EIGEN_DEVICE_FUNC AngleAxis() {}
  /** Constructs and initialize the angle-axis rotation from an \a angle in radian
   * and an \a axis which \b must \b be \b normalized.
   *
   * \warning If the \a axis vector is not normalized, then the angle-axis object
   *          represents an invalid rotation. */
  template <typename Derived>
  EIGEN_DEVICE_FUNC inline AngleAxis(const Scalar& angle, const MatrixBase<Derived>& axis)
      : m_axis(axis), m_angle(angle) {}
  /** Constructs and initialize the angle-axis rotation from a quaternion \a q.
   * This function implicitly normalizes the quaternion \a q.
   */
  template <typename QuatDerived>
  EIGEN_DEVICE_FUNC inline explicit AngleAxis(const QuaternionBase<QuatDerived>& q) {
    *this = q;
  }
  /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */
  template <typename Derived>
  EIGEN_DEVICE_FUNC inline explicit AngleAxis(const MatrixBase<Derived>& m) {
    *this = m;
  }

  /** \returns the value of the rotation angle in radian */
  EIGEN_DEVICE_FUNC Scalar angle() const { return m_angle; }
  /** \returns a read-write reference to the stored angle in radian */
  EIGEN_DEVICE_FUNC Scalar& angle() { return m_angle; }

  /** \returns the rotation axis */
  EIGEN_DEVICE_FUNC const Vector3& axis() const { return m_axis; }
  /** \returns a read-write reference to the stored rotation axis.
   *
   * \warning The rotation axis must remain a \b unit vector.
   */
  EIGEN_DEVICE_FUNC Vector3& axis() { return m_axis; }

  /** Concatenates two rotations */
  EIGEN_DEVICE_FUNC inline QuaternionType operator*(const AngleAxis& other) const {
    return QuaternionType(*this) * QuaternionType(other);
  }

  /** Concatenates two rotations */
  EIGEN_DEVICE_FUNC inline QuaternionType operator*(const QuaternionType& other) const {
    return QuaternionType(*this) * other;
  }

  /** Concatenates two rotations */
  friend EIGEN_DEVICE_FUNC inline QuaternionType operator*(const QuaternionType& a, const AngleAxis& b) {
    return a * QuaternionType(b);
  }

  /** \returns the inverse rotation, i.e., an angle-axis with opposite rotation angle */
  EIGEN_DEVICE_FUNC AngleAxis inverse() const { return AngleAxis(-m_angle, m_axis); }

  template <class QuatDerived>
  EIGEN_DEVICE_FUNC AngleAxis& operator=(const QuaternionBase<QuatDerived>& q);
  template <typename Derived>
  EIGEN_DEVICE_FUNC AngleAxis& operator=(const MatrixBase<Derived>& m);

  template <typename Derived>
  EIGEN_DEVICE_FUNC AngleAxis& fromRotationMatrix(const MatrixBase<Derived>& m);
  EIGEN_DEVICE_FUNC Matrix3 toRotationMatrix(void) const;

  /** Applies the rotation to a 3D vector using Rodrigues' formula directly,
   * without constructing the full rotation matrix. */
  template <typename OtherVectorType>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Vector3 _transformVector(const OtherVectorType& v) const {
    EIGEN_USING_STD(sin)
    EIGEN_USING_STD(cos)
    eigen_assert(v.size() == 3);

    // Rodrigues' rotation formula: v' = v*cos(θ) + (k×v)*sin(θ) + k*(k·v)*(1-cos(θ))
    const Vector3 v3(v);
    const Scalar c = cos(m_angle);
    const Scalar s = sin(m_angle);
    return v3 * c + m_axis.cross(v3) * s + m_axis * (m_axis.dot(v3) * (Scalar(1) - c));
  }

  /** \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<AngleAxis, AngleAxis<NewScalarType> >::type cast()
      const {
    return typename internal::cast_return_type<AngleAxis, AngleAxis<NewScalarType> >::type(*this);
  }

  /** Copy constructor with scalar type conversion */
  template <typename OtherScalarType>
  EIGEN_DEVICE_FUNC inline explicit AngleAxis(const AngleAxis<OtherScalarType>& other) {
    m_axis = other.axis().template cast<Scalar>();
    m_angle = Scalar(other.angle());
  }

  EIGEN_DEVICE_FUNC static inline const AngleAxis Identity() { return AngleAxis(Scalar(0), Vector3::UnitX()); }

  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
   * determined by \a prec.
   *
   * \sa MatrixBase::isApprox() */
  EIGEN_DEVICE_FUNC bool isApprox(const AngleAxis& other, const typename NumTraits<Scalar>::Real& prec =
                                                              NumTraits<Scalar>::dummy_precision()) const {
    return m_axis.isApprox(other.m_axis, prec) && internal::isApprox(m_angle, other.m_angle, prec);
  }
};

/** \ingroup Geometry_Module
 * single precision angle-axis type */
using AngleAxisf = AngleAxis<float>;
/** \ingroup Geometry_Module
 * double precision angle-axis type */
using AngleAxisd = AngleAxis<double>;

/** Set \c *this from a \b unit quaternion.
 *
 * The resulting axis is normalized, and the computed angle is in the [0,pi] range.
 *
 * This function implicitly normalizes the quaternion \a q.
 */
template <typename Scalar>
template <typename QuatDerived>
EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q) {
  EIGEN_USING_STD(atan2)
  EIGEN_USING_STD(abs)
  Scalar n = q.vec().norm();
  if (n < NumTraits<Scalar>::epsilon()) n = q.vec().stableNorm();

  if (n != Scalar(0)) {
    m_angle = Scalar(2) * atan2(n, abs(q.w()));
    if (q.w() < Scalar(0)) n = -n;
    m_axis = q.vec() / n;
  } else {
    m_angle = Scalar(0);
    m_axis << Scalar(1), Scalar(0), Scalar(0);
  }
  return *this;
}

/** Set \c *this from a 3x3 rotation matrix \a mat.
 */
template <typename Scalar>
template <typename Derived>
EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const MatrixBase<Derived>& mat) {
  return fromRotationMatrix(mat);
}

/**
 * \brief Sets \c *this from a 3x3 rotation matrix.
 **/
template <typename Scalar>
template <typename Derived>
EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat) {
  EIGEN_USING_STD(atan2)
  EIGEN_USING_STD(sqrt)
  EIGEN_STATIC_ASSERT(
      (std::is_same<Scalar, typename Derived::Scalar>::value),
      YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
  eigen_assert(mat.cols() == 3 && mat.rows() == 3);

  const typename internal::nested_eval<Derived, 3>::type m(mat.derived());

  // Skew-symmetric part gives sin(angle) * axis.
  const Scalar sx = m.coeff(2, 1) - m.coeff(1, 2);
  const Scalar sy = m.coeff(0, 2) - m.coeff(2, 0);
  const Scalar sz = m.coeff(1, 0) - m.coeff(0, 1);
  const Scalar s = sqrt(sx * sx + sy * sy + sz * sz);  // = 2*sin(angle)

  // trace = 1 + 2*cos(angle)
  const Scalar c = m.trace() - Scalar(1);  // = 2*cos(angle)

  // Use atan2 for the angle: accurate at all angles including near 0 and pi.
  m_angle = atan2(s, c);

  // Use the skew-symmetric part only when sin(angle) is large enough for
  // accurate axis extraction. Near angle=0 or angle=pi, sin(angle) is small
  // and the axis must be computed differently.
  const Scalar sin_threshold = sqrt(NumTraits<Scalar>::epsilon());
  if (s > sin_threshold) {
    // General case: axis from skew-symmetric part.
    const Scalar inv_s = Scalar(1) / s;
    m_axis << sx * inv_s, sy * inv_s, sz * inv_s;
  } else if (c > Scalar(0)) {
    // Near identity (angle ≈ 0): axis is arbitrary, use (1,0,0).
    m_axis << Scalar(1), Scalar(0), Scalar(0);
  } else {
    // Near angle = pi: extract axis from the symmetric part (R + I) / 2.
    // The axis is the eigenvector corresponding to eigenvalue 1.
    // Use the column of (R + I) with the largest diagonal entry for robustness.
    const Scalar d0 = m.coeff(0, 0);
    const Scalar d1 = m.coeff(1, 1);
    const Scalar d2 = m.coeff(2, 2);
    if (d0 >= d1 && d0 >= d2) {
      // x is the largest component
      const Scalar x = sqrt(numext::maxi(d0 - d1 - d2 + Scalar(1), Scalar(0)) * Scalar(0.5));
      const Scalar inv_2x = Scalar(0.5) / (x + NumTraits<Scalar>::epsilon());
      m_axis << x, (m.coeff(0, 1) + m.coeff(1, 0)) * inv_2x, (m.coeff(0, 2) + m.coeff(2, 0)) * inv_2x;
    } else if (d1 >= d2) {
      // y is the largest component
      const Scalar y = sqrt(numext::maxi(d1 - d0 - d2 + Scalar(1), Scalar(0)) * Scalar(0.5));
      const Scalar inv_2y = Scalar(0.5) / (y + NumTraits<Scalar>::epsilon());
      m_axis << (m.coeff(0, 1) + m.coeff(1, 0)) * inv_2y, y, (m.coeff(1, 2) + m.coeff(2, 1)) * inv_2y;
    } else {
      // z is the largest component
      const Scalar z = sqrt(numext::maxi(d2 - d0 - d1 + Scalar(1), Scalar(0)) * Scalar(0.5));
      const Scalar inv_2z = Scalar(0.5) / (z + NumTraits<Scalar>::epsilon());
      m_axis << (m.coeff(0, 2) + m.coeff(2, 0)) * inv_2z, (m.coeff(1, 2) + m.coeff(2, 1)) * inv_2z, z;
    }
    m_axis.normalize();
  }

  return *this;
}

/** Constructs and \returns an equivalent 3x3 rotation matrix.
 */
template <typename Scalar>
typename AngleAxis<Scalar>::Matrix3 EIGEN_DEVICE_FUNC AngleAxis<Scalar>::toRotationMatrix(void) const {
  EIGEN_USING_STD(sin)
  EIGEN_USING_STD(cos)
  Matrix3 res;
  Vector3 sin_axis = sin(m_angle) * m_axis;
  Scalar c = cos(m_angle);
  Vector3 cos1_axis = (Scalar(1) - c) * m_axis;

  Scalar tmp;
  tmp = cos1_axis.x() * m_axis.y();
  res.coeffRef(0, 1) = tmp - sin_axis.z();
  res.coeffRef(1, 0) = tmp + sin_axis.z();

  tmp = cos1_axis.x() * m_axis.z();
  res.coeffRef(0, 2) = tmp + sin_axis.y();
  res.coeffRef(2, 0) = tmp - sin_axis.y();

  tmp = cos1_axis.y() * m_axis.z();
  res.coeffRef(1, 2) = tmp - sin_axis.x();
  res.coeffRef(2, 1) = tmp + sin_axis.x();

  res.diagonal() = cos1_axis.cwiseProduct(m_axis).array() + c;

  return res;
}

}  // end namespace Eigen

#endif  // EIGEN_ANGLEAXIS_H
