1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.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_SCALING_H 11 #define EIGEN_SCALING_H 12 13 namespace Eigen { 14 15 /** \geometry_module \ingroup Geometry_Module 16 * 17 * \class Scaling 18 * 19 * \brief Represents a generic uniform scaling transformation 20 * 21 * \param _Scalar the scalar type, i.e., the type of the coefficients. 22 * 23 * This class represent a uniform scaling transformation. It is the return 24 * type of Scaling(Scalar), and most of the time this is the only way it 25 * is used. In particular, this class is not aimed to be used to store a scaling transformation, 26 * but rather to make easier the constructions and updates of Transform objects. 27 * 28 * To represent an axis aligned scaling, use the DiagonalMatrix class. 29 * 30 * \sa Scaling(), class DiagonalMatrix, MatrixBase::asDiagonal(), class Translation, class Transform 31 */ 32 template<typename _Scalar> 33 class UniformScaling 34 { 35 public: 36 /** the scalar type of the coefficients */ 37 typedef _Scalar Scalar; 38 39 protected: 40 41 Scalar m_factor; 42 43 public: 44 45 /** Default constructor without initialization. */ 46 UniformScaling() {} 47 /** Constructs and initialize a uniform scaling transformation */ 48 explicit inline UniformScaling(const Scalar& s) : m_factor(s) {} 49 50 inline const Scalar& factor() const { return m_factor; } 51 inline Scalar& factor() { return m_factor; } 52 53 /** Concatenates two uniform scaling */ 54 inline UniformScaling operator* (const UniformScaling& other) const 55 { return UniformScaling(m_factor * other.factor()); } 56 57 /** Concatenates a uniform scaling and a translation */ 58 template<int Dim> 59 inline Transform<Scalar,Dim,Affine> operator* (const Translation<Scalar,Dim>& t) const; 60 61 /** Concatenates a uniform scaling and an affine transformation */ 62 template<int Dim, int Mode, int Options> 63 inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Mode)> operator* (const Transform<Scalar,Dim, Mode, Options>& t) const 64 { 65 Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Mode)> res = t; 66 res.prescale(factor()); 67 return res; 68 } 69 70 /** Concatenates a uniform scaling and a linear transformation matrix */ 71 // TODO returns an expression 72 template<typename Derived> 73 inline typename internal::plain_matrix_type<Derived>::type operator* (const MatrixBase<Derived>& other) const 74 { return other * m_factor; } 75 76 template<typename Derived,int Dim> 77 inline Matrix<Scalar,Dim,Dim> operator*(const RotationBase<Derived,Dim>& r) const 78 { return r.toRotationMatrix() * m_factor; } 79 80 /** \returns the inverse scaling */ 81 inline UniformScaling inverse() const 82 { return UniformScaling(Scalar(1)/m_factor); } 83 84 /** \returns \c *this with scalar type casted to \a NewScalarType 85 * 86 * Note that if \a NewScalarType is equal to the current scalar type of \c *this 87 * then this function smartly returns a const reference to \c *this. 88 */ 89 template<typename NewScalarType> 90 inline UniformScaling<NewScalarType> cast() const 91 { return UniformScaling<NewScalarType>(NewScalarType(m_factor)); } 92 93 /** Copy constructor with scalar type conversion */ 94 template<typename OtherScalarType> 95 inline explicit UniformScaling(const UniformScaling<OtherScalarType>& other) 96 { m_factor = Scalar(other.factor()); } 97 98 /** \returns \c true if \c *this is approximately equal to \a other, within the precision 99 * determined by \a prec. 100 * 101 * \sa MatrixBase::isApprox() */ 102 bool isApprox(const UniformScaling& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const 103 { return internal::isApprox(m_factor, other.factor(), prec); } 104 105 }; 106 107 /** Concatenates a linear transformation matrix and a uniform scaling */ 108 // NOTE this operator is defiend in MatrixBase and not as a friend function 109 // of UniformScaling to fix an internal crash of Intel's ICC 110 template<typename Derived> typename MatrixBase<Derived>::ScalarMultipleReturnType 111 MatrixBase<Derived>::operator*(const UniformScaling<Scalar>& s) const 112 { return derived() * s.factor(); } 113 114 /** Constructs a uniform scaling from scale factor \a s */ 115 static inline UniformScaling<float> Scaling(float s) { return UniformScaling<float>(s); } 116 /** Constructs a uniform scaling from scale factor \a s */ 117 static inline UniformScaling<double> Scaling(double s) { return UniformScaling<double>(s); } 118 /** Constructs a uniform scaling from scale factor \a s */ 119 template<typename RealScalar> 120 static inline UniformScaling<std::complex<RealScalar> > Scaling(const std::complex<RealScalar>& s) 121 { return UniformScaling<std::complex<RealScalar> >(s); } 122 123 /** Constructs a 2D axis aligned scaling */ 124 template<typename Scalar> 125 static inline DiagonalMatrix<Scalar,2> Scaling(const Scalar& sx, const Scalar& sy) 126 { return DiagonalMatrix<Scalar,2>(sx, sy); } 127 /** Constructs a 3D axis aligned scaling */ 128 template<typename Scalar> 129 static inline DiagonalMatrix<Scalar,3> Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz) 130 { return DiagonalMatrix<Scalar,3>(sx, sy, sz); } 131 132 /** Constructs an axis aligned scaling expression from vector expression \a coeffs 133 * This is an alias for coeffs.asDiagonal() 134 */ 135 template<typename Derived> 136 static inline const DiagonalWrapper<const Derived> Scaling(const MatrixBase<Derived>& coeffs) 137 { return coeffs.asDiagonal(); } 138 139 /** \addtogroup Geometry_Module */ 140 //@{ 141 /** \deprecated */ 142 typedef DiagonalMatrix<float, 2> AlignedScaling2f; 143 /** \deprecated */ 144 typedef DiagonalMatrix<double,2> AlignedScaling2d; 145 /** \deprecated */ 146 typedef DiagonalMatrix<float, 3> AlignedScaling3f; 147 /** \deprecated */ 148 typedef DiagonalMatrix<double,3> AlignedScaling3d; 149 //@} 150 151 template<typename Scalar> 152 template<int Dim> 153 inline Transform<Scalar,Dim,Affine> 154 UniformScaling<Scalar>::operator* (const Translation<Scalar,Dim>& t) const 155 { 156 Transform<Scalar,Dim,Affine> res; 157 res.matrix().setZero(); 158 res.linear().diagonal().fill(factor()); 159 res.translation() = factor() * t.vector(); 160 res(Dim,Dim) = Scalar(1); 161 return res; 162 } 163 164 } // end namespace Eigen 165 166 #endif // EIGEN_SCALING_H 167