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 10#ifndef EIGEN_ALIGNED_VECTOR3 11#define EIGEN_ALIGNED_VECTOR3 12 13#include <Eigen/Geometry> 14 15namespace Eigen { 16 17/** 18 * \defgroup AlignedVector3_Module Aligned vector3 module 19 * 20 * \code 21 * #include <unsupported/Eigen/AlignedVector3> 22 * \endcode 23 */ 24 //@{ 25 26 27/** \class AlignedVector3 28 * 29 * \brief A vectorization friendly 3D vector 30 * 31 * This class represents a 3D vector internally using a 4D vector 32 * such that vectorization can be seamlessly enabled. Of course, 33 * the same result can be achieved by directly using a 4D vector. 34 * This class makes this process simpler. 35 * 36 */ 37// TODO specialize Cwise 38template<typename _Scalar> class AlignedVector3; 39 40namespace internal { 41template<typename _Scalar> struct traits<AlignedVector3<_Scalar> > 42 : traits<Matrix<_Scalar,3,1,0,4,1> > 43{ 44}; 45} 46 47template<typename _Scalar> class AlignedVector3 48 : public MatrixBase<AlignedVector3<_Scalar> > 49{ 50 typedef Matrix<_Scalar,4,1> CoeffType; 51 CoeffType m_coeffs; 52 public: 53 54 typedef MatrixBase<AlignedVector3<_Scalar> > Base; 55 EIGEN_DENSE_PUBLIC_INTERFACE(AlignedVector3) 56 using Base::operator*; 57 58 inline Index rows() const { return 3; } 59 inline Index cols() const { return 1; } 60 61 inline const Scalar& coeff(Index row, Index col) const 62 { return m_coeffs.coeff(row, col); } 63 64 inline Scalar& coeffRef(Index row, Index col) 65 { return m_coeffs.coeffRef(row, col); } 66 67 inline const Scalar& coeff(Index index) const 68 { return m_coeffs.coeff(index); } 69 70 inline Scalar& coeffRef(Index index) 71 { return m_coeffs.coeffRef(index);} 72 73 74 inline AlignedVector3(const Scalar& x, const Scalar& y, const Scalar& z) 75 : m_coeffs(x, y, z, Scalar(0)) 76 {} 77 78 inline AlignedVector3(const AlignedVector3& other) 79 : Base(), m_coeffs(other.m_coeffs) 80 {} 81 82 template<typename XprType, int Size=XprType::SizeAtCompileTime> 83 struct generic_assign_selector {}; 84 85 template<typename XprType> struct generic_assign_selector<XprType,4> 86 { 87 inline static void run(AlignedVector3& dest, const XprType& src) 88 { 89 dest.m_coeffs = src; 90 } 91 }; 92 93 template<typename XprType> struct generic_assign_selector<XprType,3> 94 { 95 inline static void run(AlignedVector3& dest, const XprType& src) 96 { 97 dest.m_coeffs.template head<3>() = src; 98 dest.m_coeffs.w() = Scalar(0); 99 } 100 }; 101 102 template<typename Derived> 103 inline explicit AlignedVector3(const MatrixBase<Derived>& other) 104 { 105 generic_assign_selector<Derived>::run(*this,other.derived()); 106 } 107 108 inline AlignedVector3& operator=(const AlignedVector3& other) 109 { m_coeffs = other.m_coeffs; return *this; } 110 111 112 inline AlignedVector3 operator+(const AlignedVector3& other) const 113 { return AlignedVector3(m_coeffs + other.m_coeffs); } 114 115 inline AlignedVector3& operator+=(const AlignedVector3& other) 116 { m_coeffs += other.m_coeffs; return *this; } 117 118 inline AlignedVector3 operator-(const AlignedVector3& other) const 119 { return AlignedVector3(m_coeffs - other.m_coeffs); } 120 121 inline AlignedVector3 operator-=(const AlignedVector3& other) 122 { m_coeffs -= other.m_coeffs; return *this; } 123 124 inline AlignedVector3 operator*(const Scalar& s) const 125 { return AlignedVector3(m_coeffs * s); } 126 127 inline friend AlignedVector3 operator*(const Scalar& s,const AlignedVector3& vec) 128 { return AlignedVector3(s * vec.m_coeffs); } 129 130 inline AlignedVector3& operator*=(const Scalar& s) 131 { m_coeffs *= s; return *this; } 132 133 inline AlignedVector3 operator/(const Scalar& s) const 134 { return AlignedVector3(m_coeffs / s); } 135 136 inline AlignedVector3& operator/=(const Scalar& s) 137 { m_coeffs /= s; return *this; } 138 139 inline Scalar dot(const AlignedVector3& other) const 140 { 141 eigen_assert(m_coeffs.w()==Scalar(0)); 142 eigen_assert(other.m_coeffs.w()==Scalar(0)); 143 return m_coeffs.dot(other.m_coeffs); 144 } 145 146 inline void normalize() 147 { 148 m_coeffs /= norm(); 149 } 150 151 inline AlignedVector3 normalized() 152 { 153 return AlignedVector3(m_coeffs / norm()); 154 } 155 156 inline Scalar sum() const 157 { 158 eigen_assert(m_coeffs.w()==Scalar(0)); 159 return m_coeffs.sum(); 160 } 161 162 inline Scalar squaredNorm() const 163 { 164 eigen_assert(m_coeffs.w()==Scalar(0)); 165 return m_coeffs.squaredNorm(); 166 } 167 168 inline Scalar norm() const 169 { 170 using std::sqrt; 171 return sqrt(squaredNorm()); 172 } 173 174 inline AlignedVector3 cross(const AlignedVector3& other) const 175 { 176 return AlignedVector3(m_coeffs.cross3(other.m_coeffs)); 177 } 178 179 template<typename Derived> 180 inline bool isApprox(const MatrixBase<Derived>& other, RealScalar eps=NumTraits<Scalar>::dummy_precision()) const 181 { 182 return m_coeffs.template head<3>().isApprox(other,eps); 183 } 184}; 185 186//@} 187 188} 189 190#endif // EIGEN_ALIGNED_VECTOR3 191