00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_ALIGNEDBOX_H
00026 #define EIGEN_ALIGNEDBOX_H
00027
00040 template <typename _Scalar, int _AmbientDim>
00041 class AlignedBox
00042 {
00043 public:
00044 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
00045 enum { AmbientDimAtCompileTime = _AmbientDim };
00046 typedef _Scalar Scalar;
00047 typedef NumTraits<Scalar> ScalarTraits;
00048 typedef DenseIndex Index;
00049 typedef typename ScalarTraits::Real RealScalar;
00050 typedef typename ScalarTraits::NonInteger NonInteger;
00051 typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
00052
00054 enum CornerType
00055 {
00057 Min=0, Max=1,
00058
00060 BottomLeft=0, BottomRight=1,
00061 TopLeft=2, TopRight=3,
00062
00064 BottomLeftFloor=0, BottomRightFloor=1,
00065 TopLeftFloor=2, TopRightFloor=3,
00066 BottomLeftCeil=4, BottomRightCeil=5,
00067 TopLeftCeil=6, TopRightCeil=7
00068 };
00069
00070
00072 inline explicit AlignedBox()
00073 { if (AmbientDimAtCompileTime!=Dynamic) setEmpty(); }
00074
00076 inline explicit AlignedBox(Index _dim) : m_min(_dim), m_max(_dim)
00077 { setEmpty(); }
00078
00080 template<typename OtherVectorType1, typename OtherVectorType2>
00081 inline AlignedBox(const OtherVectorType1& _min, const OtherVectorType2& _max) : m_min(_min), m_max(_max) {}
00082
00084 template<typename Derived>
00085 inline explicit AlignedBox(const MatrixBase<Derived>& a_p)
00086 {
00087 const typename internal::nested<Derived,2>::type p(a_p.derived());
00088 m_min = p;
00089 m_max = p;
00090 }
00091
00092 ~AlignedBox() {}
00093
00095 inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : Index(AmbientDimAtCompileTime); }
00096
00098 inline bool isNull() const { return isEmpty(); }
00099
00101 inline void setNull() { setEmpty(); }
00102
00104 inline bool isEmpty() const { return (m_min.array() > m_max.array()).any(); }
00105
00107 inline void setEmpty()
00108 {
00109 m_min.setConstant( ScalarTraits::highest() );
00110 m_max.setConstant( ScalarTraits::lowest() );
00111 }
00112
00114 inline const VectorType& min() const { return m_min; }
00116 inline VectorType& min() { return m_min; }
00118 inline const VectorType& max() const { return m_max; }
00120 inline VectorType& max() { return m_max; }
00121
00123 inline const CwiseUnaryOp<internal::scalar_quotient1_op<Scalar>,
00124 const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const VectorType, const VectorType> >
00125 center() const
00126 { return (m_min+m_max)/2; }
00127
00132 inline const CwiseBinaryOp< internal::scalar_difference_op<Scalar>, const VectorType, const VectorType> sizes() const
00133 { return m_max - m_min; }
00134
00136 inline Scalar volume() const
00137 { return sizes().prod(); }
00138
00143 inline CwiseBinaryOp< internal::scalar_difference_op<Scalar>, const VectorType, const VectorType> diagonal() const
00144 { return sizes(); }
00145
00155 inline VectorType corner(CornerType corner) const
00156 {
00157 EIGEN_STATIC_ASSERT(_AmbientDim <= 3, THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE);
00158
00159 VectorType res;
00160
00161 Index mult = 1;
00162 for(Index d=0; d<dim(); ++d)
00163 {
00164 if( mult & corner ) res[d] = m_max[d];
00165 else res[d] = m_min[d];
00166 mult *= 2;
00167 }
00168 return res;
00169 }
00170
00173 inline VectorType sample() const
00174 {
00175 VectorType r;
00176 for(Index d=0; d<dim(); ++d)
00177 {
00178 if(!ScalarTraits::IsInteger)
00179 {
00180 r[d] = m_min[d] + (m_max[d]-m_min[d])
00181 * internal::random<Scalar>(Scalar(0), Scalar(1));
00182 }
00183 else
00184 r[d] = internal::random(m_min[d], m_max[d]);
00185 }
00186 return r;
00187 }
00188
00190 template<typename Derived>
00191 inline bool contains(const MatrixBase<Derived>& a_p) const
00192 {
00193 const typename internal::nested<Derived,2>::type p(a_p.derived());
00194 return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all();
00195 }
00196
00198 inline bool contains(const AlignedBox& b) const
00199 { return (m_min.array()<=b.min().array()).all() && (b.max().array()<=m_max.array()).all(); }
00200
00202 template<typename Derived>
00203 inline AlignedBox& extend(const MatrixBase<Derived>& a_p)
00204 {
00205 const typename internal::nested<Derived,2>::type p(a_p.derived());
00206 m_min = m_min.cwiseMin(p);
00207 m_max = m_max.cwiseMax(p);
00208 return *this;
00209 }
00210
00212 inline AlignedBox& extend(const AlignedBox& b)
00213 {
00214 m_min = m_min.cwiseMin(b.m_min);
00215 m_max = m_max.cwiseMax(b.m_max);
00216 return *this;
00217 }
00218
00220 inline AlignedBox& clamp(const AlignedBox& b)
00221 {
00222 m_min = m_min.cwiseMax(b.m_min);
00223 m_max = m_max.cwiseMin(b.m_max);
00224 return *this;
00225 }
00226
00228 inline AlignedBox intersection(const AlignedBox& b) const
00229 {return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); }
00230
00232 inline AlignedBox merged(const AlignedBox& b) const
00233 { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); }
00234
00236 template<typename Derived>
00237 inline AlignedBox& translate(const MatrixBase<Derived>& a_t)
00238 {
00239 const typename internal::nested<Derived,2>::type t(a_t.derived());
00240 m_min += t;
00241 m_max += t;
00242 return *this;
00243 }
00244
00249 template<typename Derived>
00250 inline Scalar squaredExteriorDistance(const MatrixBase<Derived>& a_p) const;
00251
00256 inline Scalar squaredExteriorDistance(const AlignedBox& b) const;
00257
00262 template<typename Derived>
00263 inline NonInteger exteriorDistance(const MatrixBase<Derived>& p) const
00264 { return internal::sqrt(NonInteger(squaredExteriorDistance(p))); }
00265
00270 inline NonInteger exteriorDistance(const AlignedBox& b) const
00271 { return internal::sqrt(NonInteger(squaredExteriorDistance(b))); }
00272
00278 template<typename NewScalarType>
00279 inline typename internal::cast_return_type<AlignedBox,
00280 AlignedBox<NewScalarType,AmbientDimAtCompileTime> >::type cast() const
00281 {
00282 return typename internal::cast_return_type<AlignedBox,
00283 AlignedBox<NewScalarType,AmbientDimAtCompileTime> >::type(*this);
00284 }
00285
00287 template<typename OtherScalarType>
00288 inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
00289 {
00290 m_min = other.min().template cast<Scalar>();
00291 m_max = other.max().template cast<Scalar>();
00292 }
00293
00298 bool isApprox(const AlignedBox& other, RealScalar prec = ScalarTraits::dummy_precision()) const
00299 { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
00300
00301 protected:
00302
00303 VectorType m_min, m_max;
00304 };
00305
00306
00307
00308 template<typename Scalar,int AmbientDim>
00309 template<typename Derived>
00310 inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const MatrixBase<Derived>& a_p) const
00311 {
00312 const typename internal::nested<Derived,2*AmbientDim>::type p(a_p.derived());
00313 Scalar dist2 = 0.;
00314 Scalar aux;
00315 for (Index k=0; k<dim(); ++k)
00316 {
00317 if( m_min[k] > p[k] )
00318 {
00319 aux = m_min[k] - p[k];
00320 dist2 += aux*aux;
00321 }
00322 else if( p[k] > m_max[k] )
00323 {
00324 aux = p[k] - m_max[k];
00325 dist2 += aux*aux;
00326 }
00327 }
00328 return dist2;
00329 }
00330
00331 template<typename Scalar,int AmbientDim>
00332 inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const AlignedBox& b) const
00333 {
00334 Scalar dist2 = 0.;
00335 Scalar aux;
00336 for (Index k=0; k<dim(); ++k)
00337 {
00338 if( m_min[k] > b.m_max[k] )
00339 {
00340 aux = m_min[k] - b.m_max[k];
00341 dist2 += aux*aux;
00342 }
00343 else if( b.m_min[k] > m_max[k] )
00344 {
00345 aux = b.m_min[k] - m_max[k];
00346 dist2 += aux*aux;
00347 }
00348 }
00349 return dist2;
00350 }
00351
00352 #endif // EIGEN_ALIGNEDBOX_H