Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __VCGLIB_BOX3
00024 #define __VCGLIB_BOX3
00025
00026 #include <vcg/space/point3.h>
00027 #include <vcg/math/matrix44.h>
00028 #include <vcg/space/line3.h>
00029 #include <vcg/space/plane3.h>
00030
00031 namespace vcg {
00032
00040 template <class BoxScalarType>
00041 class Box3
00042 {
00043 public:
00044
00046 typedef BoxScalarType ScalarType;
00047
00049 Point3<BoxScalarType> min;
00051 Point3<BoxScalarType> max;
00053 inline Box3() { min.X()= 1;max.X()= -1;min.Y()= 1;max.Y()= -1;min.Z()= 1;max.Z()= -1;}
00055 inline Box3( const Box3 & b ) { min=b.min; max=b.max; }
00057 inline Box3( const Point3<BoxScalarType> & mi, const Point3<BoxScalarType> & ma ) { min = mi; max = ma; }
00059 inline Box3(const Point3<BoxScalarType> & center, const BoxScalarType & radius) {
00060 min = center-Point3<BoxScalarType>(radius,radius,radius);
00061 max = center+Point3<BoxScalarType>(radius,radius,radius);
00062 }
00064 inline ~Box3() { }
00066 inline bool operator == ( Box3<BoxScalarType> const & p ) const
00067 {
00068 return min==p.min && max==p.max;
00069 }
00071 inline bool operator != ( Box3<BoxScalarType> const & p ) const
00072 {
00073 return min!=p.min || max!=p.max;
00074 }
00078 void Offset( const BoxScalarType s )
00079 {
00080 Offset( Point3<BoxScalarType> (s,s,s));
00081 }
00085 void Offset( const Point3<BoxScalarType> & delta )
00086 {
00087 min -= delta;
00088 max += delta;
00089 }
00091 void Set( const Point3<BoxScalarType> & p )
00092 {
00093 min = max = p;
00094 }
00096 void SetNull()
00097 {
00098 min.X()= 1; max.X()= -1;
00099 min.Y()= 1; max.Y()= -1;
00100 min.Z()= 1; max.Z()= -1;
00101 }
00105 void Add( Box3<BoxScalarType> const & b )
00106 {
00107 if(b.IsNull()) return;
00108 if(IsNull()) *this=b;
00109 else
00110 {
00111 if(min.X() > b.min.X()) min.X() = b.min.X();
00112 if(min.Y() > b.min.Y()) min.Y() = b.min.Y();
00113 if(min.Z() > b.min.Z()) min.Z() = b.min.Z();
00114
00115 if(max.X() < b.max.X()) max.X() = b.max.X();
00116 if(max.Y() < b.max.Y()) max.Y() = b.max.Y();
00117 if(max.Z() < b.max.Z()) max.Z() = b.max.Z();
00118 }
00119 }
00124 void Add( const Point3<BoxScalarType> & p )
00125 {
00126 if(IsNull()) Set(p);
00127 else
00128 {
00129 if(min.X() > p.X()) min.X() = p.X();
00130 if(min.Y() > p.Y()) min.Y() = p.Y();
00131 if(min.Z() > p.Z()) min.Z() = p.Z();
00132
00133 if(max.X() < p.X()) max.X() = p.X();
00134 if(max.Y() < p.Y()) max.Y() = p.Y();
00135 if(max.Z() < p.Z()) max.Z() = p.Z();
00136 }
00137 }
00138
00143 void Add( const Point3<BoxScalarType> & p, const BoxScalarType radius )
00144 {
00145 if(IsNull()) Set(p);
00146 else
00147 {
00148 min.X() = std::min(min.X(),p.X()-radius);
00149 min.Y() = std::min(min.Y(),p.Y()-radius);
00150 min.Z() = std::min(min.Z(),p.Z()-radius);
00151
00152 max.X() = std::max(max.X(),p.X()+radius);
00153 max.Y() = std::max(max.Y(),p.Y()+radius);
00154 max.Z() = std::max(max.Z(),p.Z()+radius);
00155 }
00156 }
00157
00158 void Add( const Matrix44<BoxScalarType> &m, const Box3<BoxScalarType> & b )
00159 {
00160 const Point3<BoxScalarType> &mn= b.min;
00161 const Point3<BoxScalarType> &mx= b.max;
00162 Add(m*(Point3<BoxScalarType>(mn[0],mn[1],mn[2])));
00163 Add(m*(Point3<BoxScalarType>(mx[0],mn[1],mn[2])));
00164 Add(m*(Point3<BoxScalarType>(mn[0],mx[1],mn[2])));
00165 Add(m*(Point3<BoxScalarType>(mx[0],mx[1],mn[2])));
00166 Add(m*(Point3<BoxScalarType>(mn[0],mn[1],mx[2])));
00167 Add(m*(Point3<BoxScalarType>(mx[0],mn[1],mx[2])));
00168 Add(m*(Point3<BoxScalarType>(mn[0],mx[1],mx[2])));
00169 Add(m*(Point3<BoxScalarType>(mx[0],mx[1],mx[2])));
00170 }
00174 void Intersect( const Box3<BoxScalarType> & b )
00175 {
00176 if(min.X() < b.min.X()) min.X() = b.min.X();
00177 if(min.Y() < b.min.Y()) min.Y() = b.min.Y();
00178 if(min.Z() < b.min.Z()) min.Z() = b.min.Z();
00179
00180 if(max.X() > b.max.X()) max.X() = b.max.X();
00181 if(max.Y() > b.max.Y()) max.Y() = b.max.Y();
00182 if(max.Z() > b.max.Z()) max.Z() = b.max.Z();
00183
00184 if(min.X()>max.X() || min.Y()>max.Y() || min.Z()>max.Z()) SetNull();
00185 }
00189 void Translate( const Point3<BoxScalarType> & p )
00190 {
00191 min += p;
00192 max += p;
00193 }
00198 bool IsIn( Point3<BoxScalarType> const & p ) const
00199 {
00200 return (
00201 min.X() <= p.X() && p.X() <= max.X() &&
00202 min.Y() <= p.Y() && p.Y() <= max.Y() &&
00203 min.Z() <= p.Z() && p.Z() <= max.Z()
00204 );
00205 }
00210 bool IsInEx( Point3<BoxScalarType> const & p ) const
00211 {
00212 return (
00213 min.X() <= p.X() && p.X() < max.X() &&
00214 min.Y() <= p.Y() && p.Y() < max.Y() &&
00215 min.Z() <= p.Z() && p.Z() < max.Z()
00216 );
00217 }
00223
00224
00225
00226
00227
00228
00229
00230
00231 bool Collide(Box3<BoxScalarType> const &b) const
00232 {
00233 return b.min.X()<max.X() && b.max.X()>min.X() &&
00234 b.min.Y()<max.Y() && b.max.Y()>min.Y() &&
00235 b.min.Z()<max.Z() && b.max.Z()>min.Z() ;
00236 }
00240 bool IsNull() const { return min.X()>max.X() || min.Y()>max.Y() || min.Z()>max.Z(); }
00244 bool IsEmpty() const { return min==max; }
00246 BoxScalarType Diag() const
00247 {
00248 return Distance(min,max);
00249 }
00251 BoxScalarType SquaredDiag() const
00252 {
00253 return SquaredDistance(min,max);
00254 }
00256 Point3<BoxScalarType> Center() const
00257 {
00258 return (min+max)/2;
00259 }
00261 Point3<BoxScalarType> Dim() const
00262 {
00263 return (max-min);
00264 }
00266 Point3<BoxScalarType> LocalToGlobal(Point3<BoxScalarType> const & p) const{
00267 return Point3<BoxScalarType>(
00268 min[0] + p[0]*(max[0]-min[0]),
00269 min[1] + p[1]*(max[1]-min[1]),
00270 min[2] + p[2]*(max[2]-min[2]));
00271 }
00273 Point3<BoxScalarType> GlobalToLocal(Point3<BoxScalarType> const & p) const{
00274 return Point3<BoxScalarType>(
00275 (p[0]-min[0])/(max[0]-min[0]),
00276 (p[1]-min[1])/(max[1]-min[1]),
00277 (p[2]-min[2])/(max[2]-min[2])
00278 );
00279 }
00281 BoxScalarType Volume() const
00282 {
00283 return (max.X()-min.X())*(max.Y()-min.Y())*(max.Z()-min.Z());
00284 }
00286 inline BoxScalarType DimX() const { return max.X()-min.X();}
00288 inline BoxScalarType DimY() const { return max.Y()-min.Y();}
00290 inline BoxScalarType DimZ() const { return max.Z()-min.Z();}
00292 inline unsigned char MaxDim() const {
00293 int i;
00294 Point3<BoxScalarType> diag = max-min;
00295 if(diag[0]>diag[1]) i=0; else i=1;
00296 return (diag[i]>diag[2])? i: 2;
00297 }
00299 inline unsigned char MinDim() const {
00300 int i;
00301 Point3<BoxScalarType> diag = max-min;
00302 if(diag[0]<diag[1]) i=0; else i=1;
00303 return (diag[i]<diag[2])? i: 2;
00304 }
00305
00306 template <class Q>
00307 inline void Import( const Box3<Q> & b )
00308 {
00309 min.Import(b.min);
00310 max.Import(b.max);
00311 }
00312
00313 template <class Q>
00314 static inline Box3 Construct( const Box3<Q> & b )
00315 {
00316 return Box3(Point3<BoxScalarType>::Construct(b.min),Point3<BoxScalarType>::Construct(b.max));
00317 }
00318
00320 Point3<BoxScalarType> P(const int & i) const {
00321 return Point3<BoxScalarType>(
00322 min[0]+ (i%2) * DimX(),
00323 min[1]+ ((i / 2)%2) * DimY(),
00324 min[2]+ (i>3)* DimZ());
00325 }
00326 };
00327
00328 template <class T> Box3<T> Point3<T>::GetBBox(Box3<T> &bb) const {
00329 bb.Set( *this );
00330 }
00331
00332
00333 typedef Box3<short> Box3s;
00334 typedef Box3<int> Box3i;
00335 typedef Box3<float> Box3f;
00336 typedef Box3<double> Box3d;
00337
00338
00341 }
00342 #endif
00343