Re: [eigen] Mapping array of scalars into quaternions

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hi,

I add some unit test based on the Map class's ones.

Here the changeset :

* add Map<Quaternion> test based on Map from test/map.cpp
* replace implicit constructor AngleAxis(QuaternionBase&) by an explicit one, it seems ambiguous for the compiler * replace explicit constructor with conversion type Quaternion(Quaternion&) with a convert function: conflict between constructor.

--
Mathieu Gautier


# HG changeset patch
# User Mathieu Gautier <mathieu.gautier@xxxxxx>
# Date 1257782059 -3600
# Node ID c00a3b0a3cf174c737c3dc4e91aacd29fdd97640
# Parent  19c12216d1d004823402e470a88cd682d8651abf
* add Map<Quaternion> test based on Map from test/map.cpp
* replace implicit constructor AngleAxis(QuaternionBase&) by an explicit one, it seems ambiguous for the compiler
* replace explicit constructor with conversion type Quaternion(Quaternion&) with a convert function: conflict between constructor.

diff -r 19c12216d1d0 -r c00a3b0a3cf1 Eigen/src/Geometry/AngleAxis.h
--- a/Eigen/src/Geometry/AngleAxis.h	Mon Nov 09 09:08:03 2009 -0500
+++ b/Eigen/src/Geometry/AngleAxis.h	Mon Nov 09 16:54:19 2009 +0100
@@ -89,7 +89,7 @@
   template<typename Derived>
   inline AngleAxis(Scalar angle, const MatrixBase<Derived>& axis) : m_axis(axis), m_angle(angle) {}
   /** Constructs and initialize the angle-axis rotation from a quaternion \a q. */
-  inline AngleAxis(const QuaternionType& q) { *this = q; }
+  template<typename QuatDerived> inline explicit AngleAxis(const QuaternionBase<QuatDerived>& q) { *this = q; }
   /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */
   template<typename Derived>
   inline explicit AngleAxis(const MatrixBase<Derived>& m) { *this = m; }
@@ -110,13 +110,14 @@
 
   /** Concatenates two rotations */
   friend inline QuaternionType operator* (const QuaternionType& a, const AngleAxis& b)
-  { return a * QuaternionType(b); }
+  { return a.QuaternionType::operator*(QuaternionType(b)); }
 
   /** \returns the inverse rotation, i.e., an angle-axis with opposite rotation angle */
   AngleAxis inverse() const
   { return AngleAxis(-m_angle, m_axis); }
 
-  AngleAxis& operator=(const QuaternionType& q);
+  template<class QuatDerived>
+  AngleAxis& operator=(const QuaternionBase<QuatDerived>& q);
   template<typename Derived>
   AngleAxis& operator=(const MatrixBase<Derived>& m);
 
@@ -160,7 +161,8 @@
   * The axis is normalized.
   */
 template<typename Scalar>
-AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionType& q)
+template<typename QuatDerived>
+AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
 {
   Scalar n2 = q.vec().squaredNorm();
   if (n2 < precision<Scalar>()*precision<Scalar>())
diff -r 19c12216d1d0 -r c00a3b0a3cf1 Eigen/src/Geometry/OrthoMethods.h
--- a/Eigen/src/Geometry/OrthoMethods.h	Mon Nov 09 09:08:03 2009 -0500
+++ b/Eigen/src/Geometry/OrthoMethods.h	Mon Nov 09 16:54:19 2009 +0100
@@ -35,7 +35,7 @@
   */
 template<typename Derived>
 template<typename OtherDerived>
-inline typename MatrixBase<Derived>::PlainMatrixType
+EIGEN_STRONG_INLINE typename MatrixBase<Derived>::PlainMatrixType
 MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
 {
   EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3)
diff -r 19c12216d1d0 -r c00a3b0a3cf1 Eigen/src/Geometry/Quaternion.h
--- a/Eigen/src/Geometry/Quaternion.h	Mon Nov 09 09:08:03 2009 -0500
+++ b/Eigen/src/Geometry/Quaternion.h	Mon Nov 09 16:54:19 2009 +0100
@@ -26,155 +26,6 @@
 #ifndef EIGEN_QUATERNION_H
 #define EIGEN_QUATERNION_H
 
-/***************************************************************************
-* Definition of QuaternionBase<Derived>
-* The implementation is at the end of the file
-***************************************************************************/
-
-template<typename Other,
-         int OtherRows=Other::RowsAtCompileTime,
-         int OtherCols=Other::ColsAtCompileTime>
-struct ei_quaternionbase_assign_impl;
-
-template<class Derived>
-class QuaternionBase : public RotationBase<Derived, 3>
-{
-  typedef RotationBase<Derived, 3> Base;
-public:
-  using Base::operator*;
-  using Base::derived;
-
-  typedef typename ei_traits<Derived>::Scalar Scalar;
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  typedef typename ei_traits<Derived>::Coefficients Coefficients;
-
- // typedef typename Matrix<Scalar,4,1> Coefficients;
-  /** the type of a 3D vector */
-  typedef Matrix<Scalar,3,1> Vector3;
-  /** the equivalent rotation matrix type */
-  typedef Matrix<Scalar,3,3> Matrix3;
-  /** the equivalent angle-axis type */
-  typedef AngleAxis<Scalar> AngleAxisType;
-
-
-
-  /** \returns the \c x coefficient */
-  inline Scalar x() const { return this->derived().coeffs().coeff(0); }
-  /** \returns the \c y coefficient */
-  inline Scalar y() const { return this->derived().coeffs().coeff(1); }
-  /** \returns the \c z coefficient */
-  inline Scalar z() const { return this->derived().coeffs().coeff(2); }
-  /** \returns the \c w coefficient */
-  inline Scalar w() const { return this->derived().coeffs().coeff(3); }
-
-  /** \returns a reference to the \c x coefficient */
-  inline Scalar& x() { return this->derived().coeffs().coeffRef(0); }
-  /** \returns a reference to the \c y coefficient */
-  inline Scalar& y() { return this->derived().coeffs().coeffRef(1); }
-  /** \returns a reference to the \c z coefficient */
-  inline Scalar& z() { return this->derived().coeffs().coeffRef(2); }
-  /** \returns a reference to the \c w coefficient */
-  inline Scalar& w() { return this->derived().coeffs().coeffRef(3); }
-
-  /** \returns a read-only vector expression of the imaginary part (x,y,z) */
-  inline const VectorBlock<Coefficients,3> vec() const { return coeffs().template start<3>(); }
-
-  /** \returns a vector expression of the imaginary part (x,y,z) */
-  inline VectorBlock<Coefficients,3> vec() { return coeffs().template start<3>(); }
-
-  /** \returns a read-only vector expression of the coefficients (x,y,z,w) */
-  inline const typename ei_traits<Derived>::Coefficients& coeffs() const { return derived().coeffs(); }
-
-  /** \returns a vector expression of the coefficients (x,y,z,w) */
-  inline typename ei_traits<Derived>::Coefficients& coeffs() { return derived().coeffs(); }
-
-  template<class OtherDerived> Derived& operator=(const QuaternionBase<OtherDerived>& other);
-
-// disabled this copy operator as it is giving very strange compilation errors when compiling
-// test_stdvector with GCC 4.4.2. This looks like a GCC bug though, so feel free to re-enable it if it's
-// useful; however notice that we already have the templated operator= above and e.g. in MatrixBase
-// we didn't have to add, in addition to templated operator=, such a non-templated copy operator.
-//  Derived& operator=(const QuaternionBase& other)
-//  { return operator=<Derived>(other); }
-
-  Derived& operator=(const AngleAxisType& aa);
-  template<class OtherDerived> Derived& operator=(const MatrixBase<OtherDerived>& m);
-
-  /** \returns a quaternion representing an identity rotation
-    * \sa MatrixBase::Identity()
-    */
-  inline static Quaternion<Scalar> Identity() { return Quaternion<Scalar>(1, 0, 0, 0); }
-
-  /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity()
-    */
-  inline QuaternionBase& setIdentity() { coeffs() << 0, 0, 0, 1; return *this; }
-
-  /** \returns the squared norm of the quaternion's coefficients
-    * \sa QuaternionBase::norm(), MatrixBase::squaredNorm()
-    */
-  inline Scalar squaredNorm() const { return coeffs().squaredNorm(); }
-
-  /** \returns the norm of the quaternion's coefficients
-    * \sa QuaternionBase::squaredNorm(), MatrixBase::norm()
-    */
-  inline Scalar norm() const { return coeffs().norm(); }
-
-  /** Normalizes the quaternion \c *this
-    * \sa normalized(), MatrixBase::normalize() */
-  inline void normalize() { coeffs().normalize(); }
-  /** \returns a normalized copy of \c *this
-    * \sa normalize(), MatrixBase::normalized() */
-  inline Quaternion<Scalar> normalized() const { return Quaternion<Scalar>(coeffs().normalized()); }
-
-    /** \returns the dot product of \c *this and \a other
-    * Geometrically speaking, the dot product of two unit quaternions
-    * corresponds to the cosine of half the angle between the two rotations.
-    * \sa angularDistance()
-    */
-  template<class OtherDerived> inline Scalar dot(const QuaternionBase<OtherDerived>& other) const { return coeffs().dot(other.coeffs()); }
-
-  template<class OtherDerived> inline Scalar angularDistance(const QuaternionBase<OtherDerived>& other) const;
-
-  Matrix3 toRotationMatrix() const;
-
-  template<typename Derived1, typename Derived2>
-  Derived& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
-
-  template<class OtherDerived> inline Quaternion<Scalar> operator* (const QuaternionBase<OtherDerived>& q) const;
-  template<class OtherDerived> inline Derived& operator*= (const QuaternionBase<OtherDerived>& q);
-
-  Quaternion<Scalar> inverse() const;
-  Quaternion<Scalar> conjugate() const;
-
-  template<class OtherDerived> Quaternion<Scalar> slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const;
-
-  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
-    * determined by \a prec.
-    *
-    * \sa MatrixBase::isApprox() */
-  template<class OtherDerived>
-  bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = precision<Scalar>()) const
-  { return coeffs().isApprox(other.coeffs(), prec); }
-
-  Vector3 _transformVector(Vector3 v) const;
-
-  /** \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>
-  inline typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type cast() const
-  {
-    return typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type(
-      coeffs().template cast<NewScalarType>());
-  }
-};
-
-/***************************************************************************
-* Definition/implementation of Quaternion<Scalar>
-***************************************************************************/
-
 /** \geometry_module \ingroup Geometry_Module
   *
   * \class Quaternion
@@ -197,13 +48,154 @@
   * \sa  class AngleAxis, class Transform
   */
 
+template<typename Other,
+         int OtherRows=Other::RowsAtCompileTime,
+         int OtherCols=Other::ColsAtCompileTime>
+struct ei_quaternionbase_assign_impl;
+
+template<typename Scalar> class Quaternion; // [XXX] => remove when Quaternion becomes Quaternion
+
+template<typename Derived>
+struct ei_traits<QuaternionBase<Derived> >
+{
+  typedef typename ei_traits<Derived>::Scalar Scalar;
+  enum {
+    PacketAccess = ei_traits<Derived>::PacketAccess
+  };
+};
+
+template<class Derived>
+class QuaternionBase : public RotationBase<Derived, 3>
+{
+  typedef RotationBase<Derived, 3> Base;
+public:
+  using Base::operator*;
+
+  typedef typename ei_traits<QuaternionBase<Derived> >::Scalar Scalar;
+  typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ // typedef typename Matrix<Scalar,4,1> Coefficients;
+  /** the type of a 3D vector */
+  typedef Matrix<Scalar,3,1> Vector3;
+  /** the equivalent rotation matrix type */
+  typedef Matrix<Scalar,3,3> Matrix3;
+  /** the equivalent angle-axis type */
+  typedef AngleAxis<Scalar> AngleAxisType;
+
+  /** \returns the \c x coefficient */
+  inline Scalar x() const { return this->coeffs().coeff(0); }
+  /** \returns the \c y coefficient */
+  inline Scalar y() const { return this->coeffs().coeff(1); }
+  /** \returns the \c z coefficient */
+  inline Scalar z() const { return this->coeffs().coeff(2); }
+  /** \returns the \c w coefficient */
+  inline Scalar w() const { return this->coeffs().coeff(3); }
+
+  /** \returns a reference to the \c x coefficient */
+  inline Scalar& x() { return this->coeffs().coeffRef(0); }
+  /** \returns a reference to the \c y coefficient */
+  inline Scalar& y() { return this->coeffs().coeffRef(1); }
+  /** \returns a reference to the \c z coefficient */
+  inline Scalar& z() { return this->coeffs().coeffRef(2); }
+  /** \returns a reference to the \c w coefficient */
+  inline Scalar& w() { return this->coeffs().coeffRef(3); }
+
+  /** \returns a read-only vector expression of the imaginary part (x,y,z) */
+  inline const VectorBlock<typename ei_traits<Derived>::Coefficients,3> vec() const { return this->coeffs().template start<3>(); }
+
+  /** \returns a vector expression of the imaginary part (x,y,z) */
+  inline VectorBlock<typename ei_traits<Derived>::Coefficients,3> vec() { return this->coeffs().template start<3>(); }
+
+  /** \returns a read-only vector expression of the coefficients (x,y,z,w) */
+  inline const typename ei_traits<Derived>::Coefficients& coeffs() const { return this->derived().coeffs(); }
+
+  /** \returns a vector expression of the coefficients (x,y,z,w) */
+  EIGEN_STRONG_INLINE typename ei_traits<Derived>::Coefficients& coeffs() { return this->derived().coeffs(); }
+
+  EIGEN_STRONG_INLINE QuaternionBase<Derived>& operator=(const QuaternionBase<Derived>& other);
+  template<class OtherDerived> EIGEN_STRONG_INLINE QuaternionBase<Derived>& operator=(const QuaternionBase<OtherDerived>& other);
+
+  EIGEN_STRONG_INLINE QuaternionBase& operator=(const AngleAxisType& aa);
+  template<class OtherDerived>
+  EIGEN_STRONG_INLINE QuaternionBase& operator=(const MatrixBase<OtherDerived>& m);
+
+  /** \returns a quaternion representing an identity rotation
+    * \sa MatrixBase::Identity()
+    */
+  inline static Quaternion<Scalar> Identity() { return Quaternion<Scalar>(1, 0, 0, 0); }
+
+  /** \sa Quaternion2::Identity(), MatrixBase::setIdentity()
+    */
+  inline QuaternionBase& setIdentity() { coeffs() << 0, 0, 0, 1; return *this; }
+
+  /** \returns the squared norm of the quaternion's coefficients
+    * \sa Quaternion2::norm(), MatrixBase::squaredNorm()
+    */
+  inline Scalar squaredNorm() const { return coeffs().squaredNorm(); }
+
+  /** \returns the norm of the quaternion's coefficients
+    * \sa Quaternion2::squaredNorm(), MatrixBase::norm()
+    */
+  inline Scalar norm() const { return coeffs().norm(); }
+
+  /** Normalizes the quaternion \c *this
+    * \sa normalized(), MatrixBase::normalize() */
+  inline void normalize() { coeffs().normalize(); }
+  /** \returns a normalized version of \c *this
+    * \sa normalize(), MatrixBase::normalized() */
+  inline Quaternion<Scalar> normalized() const { return Quaternion<Scalar>(coeffs().normalized()); }
+
+    /** \returns the dot product of \c *this and \a other
+    * Geometrically speaking, the dot product of two unit quaternions
+    * corresponds to the cosine of half the angle between the two rotations.
+    * \sa angularDistance()
+    */
+  template<class OtherDerived> inline Scalar dot(const QuaternionBase<OtherDerived>& other) const { return coeffs().dot(other.coeffs()); }
+
+  template<class OtherDerived> inline Scalar angularDistance(const QuaternionBase<OtherDerived>& other) const;
+
+  Matrix3 toRotationMatrix(void) const;
+
+  template<typename Derived1, typename Derived2>
+  QuaternionBase& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
+
+  template<class OtherDerived> EIGEN_STRONG_INLINE Quaternion<Scalar> operator* (const QuaternionBase<OtherDerived>& q) const;
+  template<class OtherDerived> EIGEN_STRONG_INLINE QuaternionBase& operator*= (const QuaternionBase<OtherDerived>& q);
+
+  EIGEN_STRONG_INLINE Quaternion<Scalar> inverse(void) const;
+  EIGEN_STRONG_INLINE Quaternion<Scalar> conjugate(void) const;
+
+  template<class OtherDerived> Quaternion<Scalar> slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const;
+
+  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+    * determined by \a prec.
+    *
+    * \sa MatrixBase::isApprox() */
+  bool isApprox(const QuaternionBase& other, RealScalar prec = precision<Scalar>()) const
+  { return coeffs().isApprox(other.coeffs(), prec); }
+
+  Vector3 _transformVector(Vector3 v) const;
+
+  /** \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>
+  inline typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type cast() const
+  {
+    return typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type(
+      coeffs().template cast<NewScalarType>());
+  }
+};
+
 template<typename _Scalar>
 struct ei_traits<Quaternion<_Scalar> >
 {
   typedef _Scalar Scalar;
   typedef Matrix<_Scalar,4,1> Coefficients;
   enum{
-    PacketAccess = Aligned
+    PacketAccess = Aligned 
   };
 };
 
@@ -211,6 +203,7 @@
 class Quaternion : public QuaternionBase<Quaternion<_Scalar> >{
   typedef QuaternionBase<Quaternion<_Scalar> > Base;
 public:
+  using Base::operator*;
   using Base::operator=;
 
   typedef _Scalar Scalar;
@@ -228,15 +221,14 @@
     * while internally the coefficients are stored in the following order:
     * [\c x, \c y, \c z, \c w]
     */
-  inline Quaternion(Scalar w, Scalar x, Scalar y, Scalar z)
-  { coeffs() << x, y, z, w; }
+  EIGEN_STRONG_INLINE Quaternion(Scalar w, Scalar x, Scalar y, Scalar z) : m_coeffs(x, y, z, w){}
 
   /** Constructs and initialize a quaternion from the array data
     * This constructor is also used to map an array */
-  inline Quaternion(const Scalar* data) : m_coeffs(data) {}
+  EIGEN_STRONG_INLINE Quaternion(const Scalar* data) : m_coeffs(data) {}
 
-  /** Copy constructor */
-//  template<class Derived> inline Quaternion(const QuaternionBase<Derived>& other) { m_coeffs = other.coeffs(); } [XXX] redundant with 703
+  //EIGEN_STRONG_INLINE Quaternion(const Quaternion<Scalar>& q) {*this = q;}
+  template<typename Derived> EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& q) {*this = q;}
 
   /** Constructs and initializes a quaternion from the angle-axis \a aa */
   explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; }
@@ -246,94 +238,84 @@
     *  - a 4D vector expression representing quaternion coefficients.
     */
   template<typename Derived>
-  explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
+  explicit EIGEN_STRONG_INLINE Quaternion(const MatrixBase<Derived>& other) { *this = other; }
 
   /** Copy constructor with scalar type conversion */
-  template<typename Derived>
-  inline explicit Quaternion(const QuaternionBase<Derived>& other)
+  template<class Derived>
+  inline Quaternion<Scalar> convert(const QuaternionBase<Derived>& other)
   { m_coeffs = other.coeffs().template cast<Scalar>(); }
 
-  inline Coefficients& coeffs() { return m_coeffs;}
-  inline const Coefficients& coeffs() const { return m_coeffs;}
+  EIGEN_STRONG_INLINE Quaternion<Scalar>& operator=(const Quaternion<Scalar>& q){
+    this->Base::operator=(q);
+    return *this;
+  }
+
+  EIGEN_STRONG_INLINE Coefficients& coeffs() { return m_coeffs;}
+  EIGEN_STRONG_INLINE const Coefficients& coeffs() const { return m_coeffs;}
 
 protected:
   Coefficients m_coeffs;
 };
 
-/** \ingroup Geometry_Module
-  * single precision quaternion type */
+typedef Quaternion<double> Quaterniond;
 typedef Quaternion<float> Quaternionf;
-/** \ingroup Geometry_Module
-  * double precision quaternion type */
-typedef Quaternion<double> Quaterniond;
 
-/***************************************************************************
-* Specialization of Map<Quaternion<Scalar>>
-***************************************************************************/
+/* ########### Map<Quaternion> */
 
 /** \class Map<Quaternion>
   * \nonstableyet
   *
-  * \brief Expression of a quaternion from a memory buffer
+  * \brief Expression of a quaternion
   *
-  * \param _Scalar the type of the Quaternion coefficients
-  * \param PacketAccess see class Map
+  * \param Scalar the type of the vector of diagonal coefficients
   *
-  * This is a specialization of class Map for Quaternion. This class allows to view
-  * a 4 scalar memory buffer as an Eigen's  Quaternion object.
-  *
-  * \sa class Map, class Quaternion, class QuaternionBase
+  * \sa class Quaternion, class QuaternionBase
   */
 template<typename _Scalar, int _PacketAccess>
 struct ei_traits<Map<Quaternion<_Scalar>, _PacketAccess> >:
 ei_traits<Quaternion<_Scalar> >
 {
   typedef _Scalar Scalar;
-  typedef Map<Matrix<_Scalar,4,1> > Coefficients;
+  typedef Map<Matrix<_Scalar,4,1>, _PacketAccess> Coefficients;
   enum {
     PacketAccess = _PacketAccess
   };
 };
 
 template<typename _Scalar, int PacketAccess>
-class Map<Quaternion<_Scalar>, PacketAccess >
-  : public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >,
-    ei_no_assignment_operator
-{
+class Map<Quaternion<_Scalar>, PacketAccess > : public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >{
+    typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
   public:
+    using Base::operator*;
+    using Base::operator=;
 
     typedef _Scalar Scalar;
-    typedef typename ei_traits<Map>::Coefficients Coefficients;
 
-    /** Constructs a Mapped Quaternion object from the pointer \a coeffs
-      *
-      * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
-      * \code *coeffs == {x, y, z, w} \endcode
-      *
-      * If the template paramter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
-    inline Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
+    typedef typename ei_traits<Map<Quaternion<Scalar>, PacketAccess> >::Coefficients Coefficients;
 
-    inline Coefficients& coeffs() { return m_coeffs;}
-    inline const Coefficients& coeffs() const { return m_coeffs;}
+    EIGEN_STRONG_INLINE Map<Quaternion<Scalar>, PacketAccess >(const Scalar* coeffs) : m_coeffs(coeffs) {}
+    
+    EIGEN_STRONG_INLINE Map<Quaternion<Scalar>, PacketAccess >& operator=(const Map<Quaternion<Scalar>, PacketAccess >& q){
+      this->Base::operator=(q);
+      return *this;
+    }
+    
+    EIGEN_STRONG_INLINE Coefficients& coeffs() { return m_coeffs;}
+    EIGEN_STRONG_INLINE const Coefficients& coeffs() const { return m_coeffs;}
 
   protected:
     Coefficients m_coeffs;
 };
 
-typedef Map<Quaternion<double> >          QuaternionMapd;
-typedef Map<Quaternion<float> >           QuaternionMapf;
-typedef Map<Quaternion<double>, Aligned>  QuaternionMapAlignedd;
-typedef Map<Quaternion<float>, Aligned>   QuaternionMapAlignedf;
-
-/***************************************************************************
-* Implementation of QuaternionBase methods
-***************************************************************************/
+typedef Map<Quaternion<double>, 0 > QuaternionMapd;
+typedef Map<Quaternion<float>, 0 > QuaternionMapf;
+typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
+typedef Map<Quaternion<float>, Aligned> QuaternionMapAlignedf;
 
 // Generic Quaternion * Quaternion product
-// This product can be specialized for a given architecture via the Arch template argument.
-template<int Arch, class Derived1, class Derived2, typename Scalar, int PacketAccess> struct ei_quat_product
+template<int Arch, class Derived, class OtherDerived, typename Scalar, int PacketAccess> struct ei_quat_product
 {
-  inline static Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
+  EIGEN_STRONG_INLINE static Quaternion<Scalar> run(const QuaternionBase<Derived>& a, const QuaternionBase<OtherDerived>& b){
     return Quaternion<Scalar>
     (
       a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(),
@@ -347,22 +329,21 @@
 /** \returns the concatenation of two rotations as a quaternion-quaternion product */
 template <class Derived>
 template <class OtherDerived>
-inline Quaternion<typename ei_traits<Derived>::Scalar>
-QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) const
+EIGEN_STRONG_INLINE Quaternion<typename ei_traits<QuaternionBase<Derived> >::Scalar> QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) const
 {
   EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
    YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
-  return ei_quat_product<EiArch, Derived, OtherDerived,
-                         typename ei_traits<Derived>::Scalar,
-                         ei_traits<Derived>::PacketAccess && ei_traits<OtherDerived>::PacketAccess>::run(*this, other);
+   return ei_quat_product<EiArch, Derived, OtherDerived, 
+                          typename ei_traits<Derived>::Scalar,
+                          ei_traits<Derived>::PacketAccess && ei_traits<OtherDerived>::PacketAccess>::run(*this, other);
 }
 
 /** \sa operator*(Quaternion) */
 template <class Derived>
 template <class OtherDerived>
-inline Derived& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other)
+EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other)
 {
-  return (derived() = derived() * other.derived());
+  return (*this = *this * other);
 }
 
 /** Rotation of a vector by a quaternion.
@@ -386,22 +367,29 @@
 }
 
 template<class Derived>
-template<class OtherDerived>
-inline Derived& QuaternionBase<Derived>::operator=(const QuaternionBase<OtherDerived>& other)
+EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(const QuaternionBase<Derived>& other)
 {
   coeffs() = other.coeffs();
-  return derived();
+  return *this;
+}
+
+template<class Derived>
+template<class OtherDerived>
+EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(const QuaternionBase<OtherDerived>& other)
+{
+  coeffs() = other.coeffs();
+  return *this;
 }
 
 /** Set \c *this from an angle-axis \a aa and returns a reference to \c *this
   */
 template<class Derived>
-inline Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
+EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
 {
   Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
   this->w() = ei_cos(ha);
   this->vec() = ei_sin(ha) * aa.axis();
-  return derived();
+  return *this;
 }
 
 /** Set \c *this from the expression \a xpr:
@@ -412,12 +400,12 @@
 
 template<class Derived>
 template<class MatrixDerived>
-inline Derived& QuaternionBase<Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
+EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
 {
   EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename MatrixDerived::Scalar>::ret),
    YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
   ei_quaternionbase_assign_impl<MatrixDerived>::run(*this, xpr.derived());
-  return derived();
+  return *this;
 }
 
 /** Convert the quaternion to a 3x3 rotation matrix. The quaternion is required to
@@ -471,7 +459,7 @@
   */
 template<class Derived>
 template<typename Derived1, typename Derived2>
-inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
+inline QuaternionBase<Derived>& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
 {
   Vector3 v0 = a.normalized();
   Vector3 v1 = b.normalized();
@@ -495,7 +483,7 @@
     Scalar w2 = (Scalar(1)+c)*Scalar(0.5);
     this->w() = ei_sqrt(w2);
     this->vec() = axis * ei_sqrt(Scalar(1) - w2);
-    return derived();
+    return *this;
   }
   Vector3 axis = v0.cross(v1);
   Scalar s = ei_sqrt((Scalar(1)+c)*Scalar(2));
@@ -503,17 +491,17 @@
   this->vec() = axis * invs;
   this->w() = s * Scalar(0.5);
 
-  return derived();
+  return *this;
 }
 
 /** \returns the multiplicative inverse of \c *this
   * Note that in most cases, i.e., if you simply want the opposite rotation,
   * and/or the quaternion is normalized, then it is enough to use the conjugate.
   *
-  * \sa QuaternionBase::conjugate()
+  * \sa Quaternion2::conjugate()
   */
 template <class Derived>
-inline Quaternion<typename ei_traits<Derived>::Scalar> QuaternionBase<Derived>::inverse() const
+EIGEN_STRONG_INLINE Quaternion<typename ei_traits<QuaternionBase<Derived> >::Scalar> QuaternionBase<Derived>::inverse() const
 {
   // FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite()  ??
   Scalar n2 = this->squaredNorm();
@@ -522,7 +510,7 @@
   else
   {
     // return an invalid result to flag the error
-    return Quaternion<Scalar>(Coefficients::Zero());
+    return Quaternion<Scalar>(ei_traits<Derived>::Coefficients::Zero());
   }
 }
 
@@ -533,8 +521,7 @@
   * \sa Quaternion2::inverse()
   */
 template <class Derived>
-inline Quaternion<typename ei_traits<Derived>::Scalar>
-QuaternionBase<Derived>::conjugate() const
+EIGEN_STRONG_INLINE Quaternion<typename ei_traits<QuaternionBase<Derived> >::Scalar> QuaternionBase<Derived>::conjugate() const
 {
   return Quaternion<Scalar>(this->w(),-this->x(),-this->y(),-this->z());
 }
@@ -544,12 +531,11 @@
   */
 template <class Derived>
 template <class OtherDerived>
-inline typename ei_traits<Derived>::Scalar
-QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
+inline typename ei_traits<QuaternionBase<Derived> >::Scalar QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
 {
   double d = ei_abs(this->dot(other));
   if (d>=1.0)
-    return Scalar(0);
+    return 0;
   return Scalar(2) * std::acos(d);
 }
 
@@ -558,14 +544,13 @@
   */
 template <class Derived>
 template <class OtherDerived>
-Quaternion<typename ei_traits<Derived>::Scalar>
-QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
+Quaternion<typename ei_traits<QuaternionBase<Derived> >::Scalar> QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
 {
   static const Scalar one = Scalar(1) - precision<Scalar>();
   Scalar d = this->dot(other);
   Scalar absD = ei_abs(d);
   if (absD>=one)
-    return Quaternion<Scalar>(derived());
+    return Quaternion<Scalar>(*this);
 
   // theta is the angle between the 2 quaternions
   Scalar theta = std::acos(absD);
@@ -589,7 +574,7 @@
     // This algorithm comes from  "Quaternion Calculus and Fast Animation",
     // Ken Shoemake, 1987 SIGGRAPH course notes
     Scalar t = mat.trace();
-    if (t > Scalar(0))
+    if (t > 0)
     {
       t = ei_sqrt(t + Scalar(1.0));
       q.w() = Scalar(0.5)*t;
diff -r 19c12216d1d0 -r c00a3b0a3cf1 test/geo_quaternion.cpp
--- a/test/geo_quaternion.cpp	Mon Nov 09 09:08:03 2009 -0500
+++ b/test/geo_quaternion.cpp	Mon Nov 09 16:54:19 2009 +0100
@@ -27,6 +27,9 @@
 #include <Eigen/LU>
 #include <Eigen/SVD>
 
+#include <iostream> //[XXX]
+using namespace std;
+
 template<typename Scalar> void quaternion(void)
 {
   /* this test covers the following files:
@@ -84,7 +87,7 @@
 
 
   // angle-axis conversion
-  AngleAxisx aa = q1;
+  AngleAxisx aa = AngleAxisx(q1);
   VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
   VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
 
@@ -92,12 +95,9 @@
   VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());
   VERIFY_IS_APPROX( v1.normalized(),(q2.setFromTwoVectors(v1, v1)*v1).normalized());
   VERIFY_IS_APPROX(-v1.normalized(),(q2.setFromTwoVectors(v1,-v1)*v1).normalized());
-  if (ei_is_same_type<Scalar,double>::ret)
-  {
-    v3 = v1.cwise()+eps;
-    VERIFY_IS_APPROX( v3.normalized(),(q2.setFromTwoVectors(v1, v3)*v1).normalized());
-    VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized());
-  }
+  v3 = v1.cwise()+eps;
+  VERIFY_IS_APPROX( v3.normalized(),(q2.setFromTwoVectors(v1, v3)*v1).normalized());
+  VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized());
 
   // inverse and conjugate
   VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);
@@ -110,10 +110,38 @@
   VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
 }
 
+template<typename Scalar> void mapQuaternion(void){
+  typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;
+  typedef Map<Quaternion<Scalar> > MQuaternionUA;
+  typedef Quaternion<Scalar> Quaternionx;
+
+  Scalar* array1 = ei_aligned_new<Scalar>(4);
+  Scalar* array2 = ei_aligned_new<Scalar>(4);
+  Scalar* array3 = new Scalar[4+1];
+  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
+
+  MQuaternionA(array1).coeffs().setRandom();
+  (MQuaternionA(array2)) = MQuaternionA(array1);
+  (MQuaternionUA(array3unaligned)) = MQuaternionA(array1);
+
+  Quaternionx q1 = MQuaternionA(array1);
+  Quaternionx q2 = MQuaternionA(array2);
+  Quaternionx q3 = MQuaternionUA(array3unaligned);
+
+  VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());
+  VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs());
+ // VERIFY_RAISES_ASSERT((MQuaternionUA(array3unaligned)));
+
+  ei_aligned_delete(array1, 4);
+  ei_aligned_delete(array2, 4);
+  delete[] array3;
+}
+
 void test_geo_quaternion()
 {
   for(int i = 0; i < g_repeat; i++) {
-    CALL_SUBTEST_1( quaternion<float>() );
-    CALL_SUBTEST_2( quaternion<double>() );
+//     CALL_SUBTEST( quaternion<float>() );
+    CALL_SUBTEST( quaternion<double>() );
+    CALL_SUBTEST( mapQuaternion<double>() );
   }
 }
diff -r 19c12216d1d0 -r c00a3b0a3cf1 test/geo_transformations.cpp
--- a/test/geo_transformations.cpp	Mon Nov 09 09:08:03 2009 -0500
+++ b/test/geo_transformations.cpp	Mon Nov 09 16:54:19 2009 +0100
@@ -81,7 +81,7 @@
     * (AngleAxisx(Scalar(0.3), Vector3(0,0,1)).toRotationMatrix() * v1)));
 
   // angle-axis conversion
-  AngleAxisx aa = q1;
+  AngleAxisx aa = AngleAxisx(q1);
   VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
   VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
 
# HG changeset patch
# User Mathieu Gautier <mathieu.gautier@xxxxxx>
# Date 1257782927 -3600
# Node ID 605d6e233312c4635e92299645588836a0b2049f
# Parent  c00a3b0a3cf174c737c3dc4e91aacd29fdd97640
some documentation and cleaning

diff -r c00a3b0a3cf1 -r 605d6e233312 Eigen/src/Geometry/Quaternion.h
--- a/Eigen/src/Geometry/Quaternion.h	Mon Nov 09 16:54:19 2009 +0100
+++ b/Eigen/src/Geometry/Quaternion.h	Mon Nov 09 17:08:47 2009 +0100
@@ -53,8 +53,6 @@
          int OtherCols=Other::ColsAtCompileTime>
 struct ei_quaternionbase_assign_impl;
 
-template<typename Scalar> class Quaternion; // [XXX] => remove when Quaternion becomes Quaternion
-
 template<typename Derived>
 struct ei_traits<QuaternionBase<Derived> >
 {
@@ -74,7 +72,6 @@
   typedef typename ei_traits<QuaternionBase<Derived> >::Scalar Scalar;
   typedef typename NumTraits<Scalar>::Real RealScalar;
 
- // typedef typename Matrix<Scalar,4,1> Coefficients;
   /** the type of a 3D vector */
   typedef Matrix<Scalar,3,1> Vector3;
   /** the equivalent rotation matrix type */
@@ -226,10 +223,7 @@
   /** Constructs and initialize a quaternion from the array data
     * This constructor is also used to map an array */
   EIGEN_STRONG_INLINE Quaternion(const Scalar* data) : m_coeffs(data) {}
-
-  //EIGEN_STRONG_INLINE Quaternion(const Quaternion<Scalar>& q) {*this = q;}
-  template<typename Derived> EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& q) {*this = q;}
-
+	
   /** Constructs and initializes a quaternion from the angle-axis \a aa */
   explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; }
 
@@ -240,10 +234,15 @@
   template<typename Derived>
   explicit EIGEN_STRONG_INLINE Quaternion(const MatrixBase<Derived>& other) { *this = other; }
 
-  /** Copy constructor with scalar type conversion */
+  /** Copy a quaternion and convert type */
   template<class Derived>
-  inline Quaternion<Scalar> convert(const QuaternionBase<Derived>& other)
-  { m_coeffs = other.coeffs().template cast<Scalar>(); }
+  inline void convert(const QuaternionBase<Derived>& other)
+  { 
+    coeffs() = other.coeffs().template cast<Scalar>(); 
+  }
+
+  /** Copy constructor from any kinds of quaternion */
+  template<typename Derived> EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& q) {*this = q;}
 
   EIGEN_STRONG_INLINE Quaternion<Scalar>& operator=(const Quaternion<Scalar>& q){
     this->Base::operator=(q);
@@ -260,8 +259,6 @@
 typedef Quaternion<double> Quaterniond;
 typedef Quaternion<float> Quaternionf;
 
-/* ########### Map<Quaternion> */
-
 /** \class Map<Quaternion>
   * \nonstableyet
   *
@@ -290,9 +287,9 @@
     using Base::operator=;
 
     typedef _Scalar Scalar;
-
     typedef typename ei_traits<Map<Quaternion<Scalar>, PacketAccess> >::Coefficients Coefficients;
 
+		/** Map the coeffs array */
     EIGEN_STRONG_INLINE Map<Quaternion<Scalar>, PacketAccess >(const Scalar* coeffs) : m_coeffs(coeffs) {}
     
     EIGEN_STRONG_INLINE Map<Quaternion<Scalar>, PacketAccess >& operator=(const Map<Quaternion<Scalar>, PacketAccess >& q){


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/