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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #ifndef __VCGLIB_BOX3
00089 #define __VCGLIB_BOX3
00090
00091 #include <vcg/space/point3.h>
00092 #include <vcg/math/matrix44.h>
00093 #include <vcg/space/line3.h>
00094 #include <vcg/space/plane3.h>
00095
00096 namespace vcg {
00097
00105 template <class BoxScalarType>
00106 class Box3
00107 {
00108 public:
00109
00111 typedef BoxScalarType ScalarType;
00112
00114 Point3<BoxScalarType> min;
00116 Point3<BoxScalarType> max;
00118 inline Box3() { min.X()= 1;max.X()= -1;min.Y()= 1;max.Y()= -1;min.Z()= 1;max.Z()= -1;}
00120 inline Box3( const Box3 & b ) { min=b.min; max=b.max; }
00122 inline Box3( const Point3<BoxScalarType> & mi, const Point3<BoxScalarType> & ma ) { min = mi; max = ma; }
00124 inline Box3(const Point3<BoxScalarType> & center, const BoxScalarType & radius) {
00125 min = center-Point3<BoxScalarType>(radius,radius,radius);
00126 max = center+Point3<BoxScalarType>(radius,radius,radius);
00127 }
00129 inline ~Box3() { }
00131 inline bool operator == ( Box3<BoxScalarType> const & p ) const
00132 {
00133 return min==p.min && max==p.max;
00134 }
00136 inline bool operator != ( Box3<BoxScalarType> const & p ) const
00137 {
00138 return min!=p.min || max!=p.max;
00139 }
00143 void Offset( const BoxScalarType s )
00144 {
00145 Offset( Point3<BoxScalarType> (s,s,s));
00146 }
00150 void Offset( const Point3<BoxScalarType> & delta )
00151 {
00152 min -= delta;
00153 max += delta;
00154 }
00156 void Set( const Point3<BoxScalarType> & p )
00157 {
00158 min = max = p;
00159 }
00161 void SetNull()
00162 {
00163 min.X()= 1; max.X()= -1;
00164 min.Y()= 1; max.Y()= -1;
00165 min.Z()= 1; max.Z()= -1;
00166 }
00170 void Add( Box3<BoxScalarType> const & b )
00171 {
00172 if(b.IsNull()) return;
00173 if(IsNull()) *this=b;
00174 else
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 }
00189 void Add( const Point3<BoxScalarType> & p )
00190 {
00191 if(IsNull()) Set(p);
00192 else
00193 {
00194 if(min.X() > p.X()) min.X() = p.X();
00195 if(min.Y() > p.Y()) min.Y() = p.Y();
00196 if(min.Z() > p.Z()) min.Z() = p.Z();
00197
00198 if(max.X() < p.X()) max.X() = p.X();
00199 if(max.Y() < p.Y()) max.Y() = p.Y();
00200 if(max.Z() < p.Z()) max.Z() = p.Z();
00201 }
00202 }
00203
00204
00205 void Add( const Matrix44<BoxScalarType> &m, const Box3<BoxScalarType> & b )
00206 {
00207 const Point3<BoxScalarType> &mn= b.min;
00208 const Point3<BoxScalarType> &mx= b.max;
00209 Add(m*(Point3<BoxScalarType>(mn[0],mn[1],mn[2])));
00210 Add(m*(Point3<BoxScalarType>(mx[0],mn[1],mn[2])));
00211 Add(m*(Point3<BoxScalarType>(mn[0],mx[1],mn[2])));
00212 Add(m*(Point3<BoxScalarType>(mx[0],mx[1],mn[2])));
00213 Add(m*(Point3<BoxScalarType>(mn[0],mn[1],mx[2])));
00214 Add(m*(Point3<BoxScalarType>(mx[0],mn[1],mx[2])));
00215 Add(m*(Point3<BoxScalarType>(mn[0],mx[1],mx[2])));
00216 Add(m*(Point3<BoxScalarType>(mx[0],mx[1],mx[2])));
00217 }
00221 void Intersect( const Box3<BoxScalarType> & b )
00222 {
00223 if(min.X() < b.min.X()) min.X() = b.min.X();
00224 if(min.Y() < b.min.Y()) min.Y() = b.min.Y();
00225 if(min.Z() < b.min.Z()) min.Z() = b.min.Z();
00226
00227 if(max.X() > b.max.X()) max.X() = b.max.X();
00228 if(max.Y() > b.max.Y()) max.Y() = b.max.Y();
00229 if(max.Z() > b.max.Z()) max.Z() = b.max.Z();
00230
00231 if(min.X()>max.X() || min.Y()>max.Y() || min.Z()>max.Z()) SetNull();
00232 }
00236 void Translate( const Point3<BoxScalarType> & p )
00237 {
00238 min += p;
00239 max += p;
00240 }
00245 bool IsIn( Point3<BoxScalarType> const & p ) const
00246 {
00247 return (
00248 min.X() <= p.X() && p.X() <= max.X() &&
00249 min.Y() <= p.Y() && p.Y() <= max.Y() &&
00250 min.Z() <= p.Z() && p.Z() <= max.Z()
00251 );
00252 }
00257 bool IsInEx( Point3<BoxScalarType> const & p ) const
00258 {
00259 return (
00260 min.X() <= p.X() && p.X() < max.X() &&
00261 min.Y() <= p.Y() && p.Y() < max.Y() &&
00262 min.Z() <= p.Z() && p.Z() < max.Z()
00263 );
00264 }
00270
00271
00272
00273
00274
00275
00276
00277
00278 bool Collide(Box3<BoxScalarType> const &b) const
00279 {
00280 return b.min.X()<max.X() && b.max.X()>min.X() &&
00281 b.min.Y()<max.Y() && b.max.Y()>min.Y() &&
00282 b.min.Z()<max.Z() && b.max.Z()>min.Z() ;
00283 }
00287 bool IsNull() const { return min.X()>max.X() || min.Y()>max.Y() || min.Z()>max.Z(); }
00291 bool IsEmpty() const { return min==max; }
00293 BoxScalarType Diag() const
00294 {
00295 return Distance(min,max);
00296 }
00298 BoxScalarType SquaredDiag() const
00299 {
00300 return SquaredDistance(min,max);
00301 }
00303 Point3<BoxScalarType> Center() const
00304 {
00305 return (min+max)/2;
00306 }
00308 Point3<BoxScalarType> Dim() const
00309 {
00310 return (max-min);
00311 }
00313 Point3<BoxScalarType> LocalToGlobal(Point3<BoxScalarType> const & p) const{
00314 return Point3<BoxScalarType>(
00315 min[0] + p[0]*(max[0]-min[0]),
00316 min[1] + p[1]*(max[1]-min[1]),
00317 min[2] + p[2]*(max[2]-min[2]));
00318 }
00320 Point3<BoxScalarType> GlobalToLocal(Point3<BoxScalarType> const & p) const{
00321 return Point3<BoxScalarType>(
00322 (p[0]-min[0])/(max[0]-min[0]),
00323 (p[1]-min[1])/(max[1]-min[1]),
00324 (p[2]-min[2])/(max[2]-min[2])
00325 );
00326 }
00328 BoxScalarType Volume() const
00329 {
00330 return (max.X()-min.X())*(max.Y()-min.Y())*(max.Z()-min.Z());
00331 }
00333 inline BoxScalarType DimX() const { return max.X()-min.X();}
00335 inline BoxScalarType DimY() const { return max.Y()-min.Y();}
00337 inline BoxScalarType DimZ() const { return max.Z()-min.Z();}
00339 inline unsigned char MaxDim() const {
00340 int i;
00341 Point3<BoxScalarType> diag = max-min;
00342 if(diag[0]>diag[1]) i=0; else i=1;
00343 return (diag[i]>diag[2])? i: 2;
00344 }
00346 inline unsigned char MinDim() const {
00347 int i;
00348 Point3<BoxScalarType> diag = max-min;
00349 if(diag[0]<diag[1]) i=0; else i=1;
00350 return (diag[i]<diag[2])? i: 2;
00351 }
00352
00353 template <class Q>
00354 inline void Import( const Box3<Q> & b )
00355 {
00356 min.Import(b.min);
00357 max.Import(b.max);
00358 }
00359
00360 template <class Q>
00361 static inline Box3 Construct( const Box3<Q> & b )
00362 {
00363 return Box3(Point3<BoxScalarType>::Construct(b.min),Point3<BoxScalarType>::Construct(b.max));
00364 }
00365
00367 Point3<BoxScalarType> P(const int & i) const {
00368 return Point3<BoxScalarType>(
00369 min[0]+ (i%2) * DimX(),
00370 min[1]+ ((i / 2)%2) * DimY(),
00371 min[2]+ (i>3)* DimZ());
00372 }
00373 };
00374
00375 template <class T> Box3<T> Point3<T>::GetBBox(Box3<T> &bb) const {
00376 bb.Set( *this );
00377 }
00378
00379
00380 template <class ScalarType>
00381 ScalarType DistancePoint3Box3(const Point3<ScalarType> &p,
00382 const Box3<ScalarType> &b)
00383 {
00385 if (b.IsIn(p))
00386 {
00387 const ScalarType dx = std::min<ScalarType>(b.max.X()-p.X(), p.X()-b.min.X());
00388 const ScalarType dy = std::min<ScalarType>(b.max.Y()-p.Y(), p.Y()-b.min.Y());
00389 const ScalarType dz = std::min<ScalarType>(b.max.Z()-p.Z(), p.Z()-b.min.Z());
00390
00391 return std::min<ScalarType>(dx, std::min<ScalarType>(dy, dz));
00392 }
00393
00394 {
00395 ScalarType sq_dist = ScalarType(0);
00396 for (int i=0; i<3; ++i)
00397 {
00398 ScalarType delta = ScalarType(0);
00399 if (p[i] < b.min[i]) delta = p[i] - b.min[i];
00400 else if (p[i] > b.max[i]) delta = p[i] - b.max[i];
00401 sq_dist += delta * delta;
00402 }
00403
00404 return math::Sqrt(sq_dist);
00405 }
00406 }
00407
00408
00409 typedef Box3<short> Box3s;
00410 typedef Box3<int> Box3i;
00411 typedef Box3<float> Box3f;
00412 typedef Box3<double> Box3d;
00413
00414
00417 }
00418 #endif
00419