Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Geometry / AlignedBox.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_ALIGNEDBOX_H
26 #define EIGEN_ALIGNEDBOX_H
27
28 /** \geometry_module \ingroup Geometry_Module
29   * \nonstableyet
30   *
31   * \class AlignedBox
32   *
33   * \brief An axis aligned box
34   *
35   * \param _Scalar the type of the scalar coefficients
36   * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
37   *
38   * This class represents an axis aligned box as a pair of the minimal and maximal corners.
39   */
40 template <typename _Scalar, int _AmbientDim>
41 class AlignedBox
42 {
43 public:
44 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1)
45   enum { AmbientDimAtCompileTime = _AmbientDim };
46   typedef _Scalar Scalar;
47   typedef typename NumTraits<Scalar>::Real RealScalar;
48   typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
49
50   /** Default constructor initializing a null box. */
51   inline explicit AlignedBox()
52   { if (AmbientDimAtCompileTime!=Dynamic) setNull(); }
53
54   /** Constructs a null box with \a _dim the dimension of the ambient space. */
55   inline explicit AlignedBox(int _dim) : m_min(_dim), m_max(_dim)
56   { setNull(); }
57
58   /** Constructs a box with extremities \a _min and \a _max. */
59   inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_min(_min), m_max(_max) {}
60
61   /** Constructs a box containing a single point \a p. */
62   inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {}
63
64   ~AlignedBox() {}
65
66   /** \returns the dimension in which the box holds */
67   inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; }
68
69   /** \returns true if the box is null, i.e, empty. */
70   inline bool isNull() const { return (m_min.cwise() > m_max).any(); }
71
72   /** Makes \c *this a null/empty box. */
73   inline void setNull()
74   {
75     m_min.setConstant( std::numeric_limits<Scalar>::max());
76     m_max.setConstant(-std::numeric_limits<Scalar>::max());
77   }
78
79   /** \returns the minimal corner */
80   inline const VectorType& min() const { return m_min; }
81   /** \returns a non const reference to the minimal corner */
82   inline VectorType& min() { return m_min; }
83   /** \returns the maximal corner */
84   inline const VectorType& max() const { return m_max; }
85   /** \returns a non const reference to the maximal corner */
86   inline VectorType& max() { return m_max; }
87
88   /** \returns true if the point \a p is inside the box \c *this. */
89   inline bool contains(const VectorType& p) const
90   { return (m_min.cwise()<=p).all() && (p.cwise()<=m_max).all(); }
91
92   /** \returns true if the box \a b is entirely inside the box \c *this. */
93   inline bool contains(const AlignedBox& b) const
94   { return (m_min.cwise()<=b.min()).all() && (b.max().cwise()<=m_max).all(); }
95
96   /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
97   inline AlignedBox& extend(const VectorType& p)
98   { m_min = m_min.cwise().min(p); m_max = m_max.cwise().max(p); return *this; }
99
100   /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */
101   inline AlignedBox& extend(const AlignedBox& b)
102   { m_min = m_min.cwise().min(b.m_min); m_max = m_max.cwise().max(b.m_max); return *this; }
103
104   /** Clamps \c *this by the box \a b and returns a reference to \c *this. */
105   inline AlignedBox& clamp(const AlignedBox& b)
106   { m_min = m_min.cwise().max(b.m_min); m_max = m_max.cwise().min(b.m_max); return *this; }
107
108   /** Translate \c *this by the vector \a t and returns a reference to \c *this. */
109   inline AlignedBox& translate(const VectorType& t)
110   { m_min += t; m_max += t; return *this; }
111
112   /** \returns the squared distance between the point \a p and the box \c *this,
113     * and zero if \a p is inside the box.
114     * \sa exteriorDistance()
115     */
116   inline Scalar squaredExteriorDistance(const VectorType& p) const;
117
118   /** \returns the distance between the point \a p and the box \c *this,
119     * and zero if \a p is inside the box.
120     * \sa squaredExteriorDistance()
121     */
122   inline Scalar exteriorDistance(const VectorType& p) const
123   { return ei_sqrt(squaredExteriorDistance(p)); }
124
125   /** \returns \c *this with scalar type casted to \a NewScalarType
126     *
127     * Note that if \a NewScalarType is equal to the current scalar type of \c *this
128     * then this function smartly returns a const reference to \c *this.
129     */
130   template<typename NewScalarType>
131   inline typename ei_cast_return_type<AlignedBox,
132            AlignedBox<NewScalarType,AmbientDimAtCompileTime> >::type cast() const
133   {
134     return typename ei_cast_return_type<AlignedBox,
135                     AlignedBox<NewScalarType,AmbientDimAtCompileTime> >::type(*this);
136   }
137
138   /** Copy constructor with scalar type conversion */
139   template<typename OtherScalarType>
140   inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
141   {
142     m_min = other.min().template cast<Scalar>();
143     m_max = other.max().template cast<Scalar>();
144   }
145
146   /** \returns \c true if \c *this is approximately equal to \a other, within the precision
147     * determined by \a prec.
148     *
149     * \sa MatrixBase::isApprox() */
150   bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
151   { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
152
153 protected:
154
155   VectorType m_min, m_max;
156 };
157
158 template<typename Scalar,int AmbiantDim>
159 inline Scalar AlignedBox<Scalar,AmbiantDim>::squaredExteriorDistance(const VectorType& p) const
160 {
161   Scalar dist2 = 0.;
162   Scalar aux;
163   for (int k=0; k<dim(); ++k)
164   {
165     if ((aux = (p[k]-m_min[k]))<0.)
166       dist2 += aux*aux;
167     else if ( (aux = (m_max[k]-p[k]))<0. )
168       dist2 += aux*aux;
169   }
170   return dist2;
171 }
172
173 #endif // EIGEN_ALIGNEDBOX_H