You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.1 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #ifndef EIGEN_ALIGNED_VECTOR3
  10. #define EIGEN_ALIGNED_VECTOR3
  11. #include <Eigen/Geometry>
  12. namespace Eigen {
  13. /**
  14. * \defgroup AlignedVector3_Module Aligned vector3 module
  15. *
  16. * \code
  17. * #include <unsupported/Eigen/AlignedVector3>
  18. * \endcode
  19. */
  20. //@{
  21. /** \class AlignedVector3
  22. *
  23. * \brief A vectorization friendly 3D vector
  24. *
  25. * This class represents a 3D vector internally using a 4D vector
  26. * such that vectorization can be seamlessly enabled. Of course,
  27. * the same result can be achieved by directly using a 4D vector.
  28. * This class makes this process simpler.
  29. *
  30. */
  31. // TODO specialize Cwise
  32. template<typename _Scalar> class AlignedVector3;
  33. namespace internal {
  34. template<typename _Scalar> struct traits<AlignedVector3<_Scalar> >
  35. : traits<Matrix<_Scalar,3,1,0,4,1> >
  36. {
  37. };
  38. }
  39. template<typename _Scalar> class AlignedVector3
  40. : public MatrixBase<AlignedVector3<_Scalar> >
  41. {
  42. typedef Matrix<_Scalar,4,1> CoeffType;
  43. CoeffType m_coeffs;
  44. public:
  45. typedef MatrixBase<AlignedVector3<_Scalar> > Base;
  46. EIGEN_DENSE_PUBLIC_INTERFACE(AlignedVector3)
  47. using Base::operator*;
  48. inline Index rows() const { return 3; }
  49. inline Index cols() const { return 1; }
  50. inline const Scalar& coeff(Index row, Index col) const
  51. { return m_coeffs.coeff(row, col); }
  52. inline Scalar& coeffRef(Index row, Index col)
  53. { return m_coeffs.coeffRef(row, col); }
  54. inline const Scalar& coeff(Index index) const
  55. { return m_coeffs.coeff(index); }
  56. inline Scalar& coeffRef(Index index)
  57. { return m_coeffs.coeffRef(index);}
  58. inline AlignedVector3(const Scalar& x, const Scalar& y, const Scalar& z)
  59. : m_coeffs(x, y, z, Scalar(0))
  60. {}
  61. inline AlignedVector3(const AlignedVector3& other)
  62. : Base(), m_coeffs(other.m_coeffs)
  63. {}
  64. template<typename XprType, int Size=XprType::SizeAtCompileTime>
  65. struct generic_assign_selector {};
  66. template<typename XprType> struct generic_assign_selector<XprType,4>
  67. {
  68. inline static void run(AlignedVector3& dest, const XprType& src)
  69. {
  70. dest.m_coeffs = src;
  71. }
  72. };
  73. template<typename XprType> struct generic_assign_selector<XprType,3>
  74. {
  75. inline static void run(AlignedVector3& dest, const XprType& src)
  76. {
  77. dest.m_coeffs.template head<3>() = src;
  78. dest.m_coeffs.w() = Scalar(0);
  79. }
  80. };
  81. template<typename Derived>
  82. inline explicit AlignedVector3(const MatrixBase<Derived>& other)
  83. {
  84. generic_assign_selector<Derived>::run(*this,other.derived());
  85. }
  86. inline AlignedVector3& operator=(const AlignedVector3& other)
  87. { m_coeffs = other.m_coeffs; return *this; }
  88. inline AlignedVector3 operator+(const AlignedVector3& other) const
  89. { return AlignedVector3(m_coeffs + other.m_coeffs); }
  90. inline AlignedVector3& operator+=(const AlignedVector3& other)
  91. { m_coeffs += other.m_coeffs; return *this; }
  92. inline AlignedVector3 operator-(const AlignedVector3& other) const
  93. { return AlignedVector3(m_coeffs - other.m_coeffs); }
  94. inline AlignedVector3 operator-=(const AlignedVector3& other)
  95. { m_coeffs -= other.m_coeffs; return *this; }
  96. inline AlignedVector3 operator*(const Scalar& s) const
  97. { return AlignedVector3(m_coeffs * s); }
  98. inline friend AlignedVector3 operator*(const Scalar& s,const AlignedVector3& vec)
  99. { return AlignedVector3(s * vec.m_coeffs); }
  100. inline AlignedVector3& operator*=(const Scalar& s)
  101. { m_coeffs *= s; return *this; }
  102. inline AlignedVector3 operator/(const Scalar& s) const
  103. { return AlignedVector3(m_coeffs / s); }
  104. inline AlignedVector3& operator/=(const Scalar& s)
  105. { m_coeffs /= s; return *this; }
  106. inline Scalar dot(const AlignedVector3& other) const
  107. {
  108. eigen_assert(m_coeffs.w()==Scalar(0));
  109. eigen_assert(other.m_coeffs.w()==Scalar(0));
  110. return m_coeffs.dot(other.m_coeffs);
  111. }
  112. inline void normalize()
  113. {
  114. m_coeffs /= norm();
  115. }
  116. inline AlignedVector3 normalized()
  117. {
  118. return AlignedVector3(m_coeffs / norm());
  119. }
  120. inline Scalar sum() const
  121. {
  122. eigen_assert(m_coeffs.w()==Scalar(0));
  123. return m_coeffs.sum();
  124. }
  125. inline Scalar squaredNorm() const
  126. {
  127. eigen_assert(m_coeffs.w()==Scalar(0));
  128. return m_coeffs.squaredNorm();
  129. }
  130. inline Scalar norm() const
  131. {
  132. using std::sqrt;
  133. return sqrt(squaredNorm());
  134. }
  135. inline AlignedVector3 cross(const AlignedVector3& other) const
  136. {
  137. return AlignedVector3(m_coeffs.cross3(other.m_coeffs));
  138. }
  139. template<typename Derived>
  140. inline bool isApprox(const MatrixBase<Derived>& other, RealScalar eps=NumTraits<Scalar>::dummy_precision()) const
  141. {
  142. return m_coeffs.template head<3>().isApprox(other,eps);
  143. }
  144. };
  145. //@}
  146. }
  147. #endif // EIGEN_ALIGNED_VECTOR3