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 #ifndef __VCGLIB_BOX
00050 #define __VCGLIB_BOX
00051
00052 #include <vcg/space/point.h>
00053 #include <vcg/space/space.h>
00054 #include <vcg/math/linear.h>
00055
00056 namespace vcg {
00057
00067 template <int N, class S>
00068 class Box : public Space<N,S> , Linear<Box>
00069 {
00070 public:
00071 typedef S ScalarType;
00072 typedef Point<N,S> ParamType;
00073 typedef Point<N,S> PointType;
00074 enum {Dimension=N};
00075
00077 protected:
00079 Point3<S> _min;
00081 Point3<S> _max;
00082
00083 public:
00084
00085 inline const PointType &Max() const { return _max; }
00086 inline PointType &Max() { return _max; }
00087 inline const PointType &Min() const { return _min; }
00088 inline PointType &Min() { return _min; }
00089
00091 inline Box() {
00092 _min.X()= 1;_max.X()= -1;
00093 _min.Y()= 1;_max.Y()= -1;
00094 if (N>2) {_min.Z()= 1;_max.Z()= -1;}
00095 }
00097 inline Box( const PointType & mi, const PointType & ma ) { _min = mi; _max = ma; }
00099 inline ~Box() { }
00101 inline bool operator == ( Box const & p ) const
00102 {
00103 return _min==p._min && _max==p._max;
00104 }
00106 inline bool operator != ( Box const & p ) const
00107 {
00108 return _min!=p._min || _max!=p._max;
00109 }
00116 void Inflate( const S s )
00117 {
00118 Inflate( (_max-_min)*s );
00119 }
00122 void InflateFix( const S s )
00123 {
00124 S k = Diag()*s;
00125 if (N==2) Inflate( PointType (k,k));
00126 if (N==3) Inflate( PointType (k,k,k));
00127 }
00131 void Inflate( const PointType & delta )
00132 {
00133 _min -= delta;
00134 _max += delta;
00135 }
00137 void Set( const PointType & p )
00138 {
00139 _min = _max = p;
00140 }
00142 void SetNull()
00143 {
00144 _min.X()= 1; _max.X()= -1;
00145 _min.Y()= 1; _max.Y()= -1;
00146 _min.Z()= 1; _max.Z()= -1;
00147 }
00152 void Add( Box const & b )
00153 {
00154 if(IsNull()) *this=b;
00155 else
00156 Add(_min); Add(_max);
00157 }
00162 void Add( const PointType & p )
00163 {
00164 if(IsNull()) Set(p);
00165 else
00166 {
00167 if(_min.X() > p.X()) _min.X() = p.X();
00168 else if(_max.X() < p.X()) _max.X() = p.X();
00169 if(_min.Y() > p.Y()) _min.Y() = p.Y();
00170 else if(_max.Y() < p.Y()) _max.Y() = p.Y();
00171 if (N>2) {
00172 if(_min.Z() > p.Z()) _min.Z() = p.Z();
00173 else if(_max.Z() < p.Z()) _max.Z() = p.Z();
00174 };
00175 }
00176 }
00180 void Intersect( const Box & b )
00181 {
00182 if(_min.X() < b._min.X()) _min.X() = b._min.X();
00183 if(_min.Y() < b._min.Y()) _min.Y() = b._min.Y();
00184 if (N>2) if(_min.Z() < b._min.Z()) _min.Z() = b._min.Z();
00185
00186 if(_max.X() > b._max.X()) _max.X() = b._max.X();
00187 if(_max.Y() > b._max.Y()) _max.Y() = b._max.Y();
00188 if (N>2) if(_max.Z() > b._max.Z()) _max.Z() = b._max.Z();
00189
00190 if(_min.X()>_max.X() || _min.Y()>_max.Y() ) SetNull();
00191 else if (N>2) if (_min.Z()>_max.Z()) SetNull();
00192 }
00196 void Translate( const PointType & p )
00197 {
00198 _min += p;
00199 _max += p;
00200 }
00205 bool IsIn( PointType const & p ) const
00206 {
00207 if (N==2) return (
00208 _min.X() <= p.X() && p.X() <= _max.X() &&
00209 _min.Y() <= p.Y() && p.Y() <= _max.Y()
00210 );
00211 if (N==3) return (
00212 _min.X() <= p.X() && p.X() <= _max.X() &&
00213 _min.Y() <= p.Y() && p.Y() <= _max.Y() &&
00214 _min.Z() <= p.Z() && p.Z() <= _max.Z()
00215 );
00216 }
00221 bool IsInEx( PointType const & p ) const
00222 {
00223 if (N==2) return (
00224 _min.X() <= p.X() && p.X() < _max.X() &&
00225 _min.Y() <= p.Y() && p.Y() < _max.Y()
00226 );
00227 if (N==3) return (
00228 _min.X() <= p.X() && p.X() < _max.X() &&
00229 _min.Y() <= p.Y() && p.Y() < _max.Y() &&
00230 _min.Z() <= p.Z() && p.Z() < _max.Z()
00231 );
00232 }
00241 bool Collide(Box const &b)
00242 {
00243 return b._min.X()<_max.X() && b._max.X()>_min.X() &&
00244 b._min.Y()<_max.Y() && b._max.Y()>_min.Y() &&
00245 b._min.Z()<_max.Z() && b._max.Z()>_min.Z() ;
00246 }
00250 bool IsNull() const { return _min.X()>_max.X() || _min.Y()>_max.Y() || _min.Z()>_max.Z(); }
00254 bool IsEmpty() const { return _min==_max; }
00256 S Diag() const
00257 {
00258 return Distance(_min,_max);
00259 }
00261 S SquaredDiag() const
00262 {
00263 return SquaredDistance(_min,_max);
00264 }
00266 PointType Center() const
00267 {
00268 return (_min+_max)/2;
00269 }
00270
00272 PointType LocalToGlobal(PointType const & p) const{
00273 return PointType(
00274 _min[0] + p[0]*(_max[0]-_min[0]),
00275 _min[1] + p[1]*(_max[1]-_min[1]),
00276 _min[2] + p[2]*(_max[2]-_min[2]));
00277 }
00279 PointType GlobalToLocal(PointType const & p) const{
00280 return PointType(
00281 (p[0]-_min[0])/(_max[0]-_min[0]),
00282 (p[1]-_min[1])/(_max[1]-_min[1]),
00283 (p[2]-_min[2])/(_max[2]-_min[2])
00284 );
00285 }
00287 inline S Volume() const
00288 {
00289 if (N==2) return (_max.X()-_min.X())*(_max.Y()-_min.Y());
00290 if (N==3) return (_max.X()-_min.X())*(_max.Y()-_min.Y())*(_max.Z()-_min.Z());
00291 }
00293 inline S Area() const {
00294 return Volume();
00295 };
00297 PointType Size() const
00298 {
00299 return (_max-_min);
00300 }
00302 inline S SizeX() const { return _max.X()-_min.X();}
00304 inline S SizeY() const { return _max.Y()-_min.Y();}
00306 inline S SizeZ() const { static_assert(N>2); return _max.Z()-_min.Z();}
00307
00311
00312 inline void Zero()
00313 {
00314 _min.SetZero();
00315 _max.SetZero();
00316 }
00317 inline Box operator + ( Box const & p) const
00318 {
00319 return Box(_min+p._min,_max+p._max);
00320 }
00321 inline Box operator - ( Box const & p) const
00322 {
00323 return Box(_min-p._min,_max-p._max);
00324 }
00325 inline Box operator * ( const S s ) const
00326 {
00327 return Box(_min*s,_max*s);
00328 }
00329 inline Box operator / ( const S s ) const
00330 {
00331 S inv=S(1.0)/s;
00332 return Box(_min*inv,_max*inv);
00333 }
00334 inline Box & operator += ( Box const & p)
00335 {
00336 _min+=p._min; _max+=p._max; return *this;
00337 }
00338 inline Box & operator -= ( Box const & p)
00339 {
00340 _min-=p._min; _max-=p._max; return *this;
00341 }
00342 inline Box & operator *= ( const S s )
00343 {
00344 _min*=s; _max*=s; return *this;
00345 }
00346 inline Box & operator /= ( const S s )
00347 {
00348 S inv=S(1.0)/s;
00349 _min*=s; _max*=s; return *this;
00350 return *this;
00351 }
00352 inline Box operator - () const
00353 {
00354 return Box(-_min,-_max);
00355 }
00357
00359
00362
00363 template <int N0, class S0>
00364 inline void Import( const Box<N0,S0> & b )
00365 { _max.Import( b._max );_min.Import( b._min );
00366 }
00367 template <int N0, class S0>
00369 static Box Construct( const Box<N0,S0> & b )
00370 {
00371 return Box(PointType::Construct(b._min),PointType::Construct(b._max));
00372 }
00373
00374
00375 };
00376
00377
00378
00379
00380 typedef Box<3,short> Box3s;
00381 typedef Box<3,int> Box3i;
00382 typedef Box<3,float> Box3f;
00383 typedef Box<3,double> Box3d;
00384
00385 typedef Box<2,short> Box2s;
00386 typedef Box<2,int> Box2i;
00387 typedef Box<2,float> Box2f;
00388 typedef Box<2,double> Box2d;
00389
00390
00393 }
00394 #endif