simpleBox3.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: simpleBox3.h,v 1.9 2004/05/27 19:49:42 oliver Exp $
00005 //
00006 
00007 #ifndef BALL_MATHS_SIMPLEBOX3_H
00008 #define BALL_MATHS_SIMPLEBOX3_H
00009 
00010 #ifndef BALL_COMMON_H
00011 # include <BALL/common.h>
00012 #endif
00013 
00014 #ifndef BALL_MATHS_VECTOR3_H
00015 # include <BALL/MATHS/vector3.h>
00016 #endif
00017 
00018 namespace BALL 
00019 {
00024 
00030   template <typename T>
00031   class TSimpleBox3
00032   {
00033     public:
00034 
00035     BALL_CREATE(TSimpleBox3<T>)
00036 
00037     
00040 
00045     TSimpleBox3()
00046       ;
00047 
00052     TSimpleBox3(const TSimpleBox3& box);
00053 
00059     TSimpleBox3(const TVector3<T>& a, const TVector3<T>& b);
00060 
00070     TSimpleBox3(const T& ax, const T& ay, const T& az, const T& bx, const T& by, const T& bz);
00071 
00076     virtual ~TSimpleBox3()
00077       
00078     {
00079     }
00080 
00084     virtual void clear();
00085 
00087 
00090 
00094     void set(const TSimpleBox3& box);
00095 
00100     void set(const TVector3<T>& lower, const TVector3<T>& upper);
00101 
00110     void set(const T& ax, const T& ay, const T& az, const T& bx, const T& by, const T& bz)
00111       ;
00112 
00117     const TSimpleBox3& operator = (const TSimpleBox3& box)
00118       ;
00119 
00124     void get(TSimpleBox3& box) const;
00125 
00130     void get(TVector3<T>& lower, TVector3<T>& upper) const
00131       ;
00132 
00141     void get(T& ax, T& ay, T& az, T& bx, T& by, T& bz) const;
00142 
00146     void swap(TSimpleBox3& box);
00147 
00149 
00150 
00157     T getSurface() const
00158       ;
00159 
00163     T getVolume() const
00164       ;
00165 
00169     T getWidth() const
00170       ;
00171   
00175     T getHeight() const
00176       ;
00177   
00181     T getDepth() const
00182       ;
00183   
00189     void join(const TSimpleBox3& box)
00190       ;
00191 
00193 
00196 
00200     bool operator == (const TSimpleBox3& box) const
00201       ;
00202 
00206     bool operator != (const TSimpleBox3& box) const
00207       ;
00208 
00215     bool has(const TVector3<T>& point, bool on_surface = false) const
00216       ;
00217 
00222     bool isIntersecting(const TSimpleBox3& box) const
00223       ;
00225 
00229 
00234     bool isValid() const
00235       ;
00236 
00243     void dump(std::ostream& s = std::cout, Size depth = 0) const
00244       ;
00246 
00247 
00251 
00254     TVector3<T> a;
00255 
00258     TVector3<T> b;
00260   };
00262 
00263   template <typename T>
00264   TSimpleBox3<T>::TSimpleBox3()
00265     
00266     : a(),
00267       b()
00268   {
00269   }
00270 
00271   template <typename T>
00272   TSimpleBox3<T>::TSimpleBox3(const TSimpleBox3<T>& box)
00273     
00274     : a(box.a),
00275       b(box.b)
00276   {
00277   }
00278 
00279   template <typename T>
00280   TSimpleBox3<T>::TSimpleBox3(const TVector3<T>& lower, const TVector3<T>& upper)
00281     
00282     : a(lower),
00283       b(upper)
00284   {
00285   }
00286 
00287   template <typename T>
00288   TSimpleBox3<T>::TSimpleBox3(const T& ax, const T& ay, const T& az,
00289                   const T& bx, const T& by, const T& bz)
00290     
00291     : a(ax, ay, az),
00292       b(bx, by, bz)
00293   {
00294   }
00295 
00296   template <typename T>
00297   BALL_INLINE 
00298   void TSimpleBox3<T>::set(const TSimpleBox3<T>& box)
00299     
00300   {
00301     a.set(box.a);
00302     b.set(box.b);
00303   }
00304 
00305   template <typename T>
00306   BALL_INLINE 
00307   void TSimpleBox3<T>::set(const TVector3<T>& lower, const TVector3<T>& upper)
00308     
00309   {
00310     a.set(lower);
00311     b.set(upper);
00312   }
00313 
00314   template <typename T>
00315   BALL_INLINE 
00316   void TSimpleBox3<T>::set(const T& ax, const T& ay, const T& az,
00317                      const T& bx, const T& by, const T& bz)
00318     
00319   {
00320     a.set(ax, ay, az);
00321     b.set(bx, by, bz);
00322   }
00323 
00324   template <typename T>
00325   BALL_INLINE
00326   const TSimpleBox3<T>& TSimpleBox3<T>::operator = (const TSimpleBox3<T> &box)
00327     
00328   {
00329     set(box);
00330     return *this;
00331   }
00332 
00333   template <typename T>
00334   BALL_INLINE 
00335   void TSimpleBox3<T>::get(TSimpleBox3<T>& box) const
00336     
00337   {
00338     box.set(*this);
00339   }
00340 
00341   template <typename T>
00342   BALL_INLINE 
00343   void TSimpleBox3<T>::get(TVector3<T>& lower, TVector3<T>& upper) const
00344     
00345   {
00346     lower.set(a);
00347     upper.set(b);
00348   }
00349 
00350   template <typename T>
00351   BALL_INLINE 
00352   void TSimpleBox3<T>::get(T& ax, T& ay, T& az, T& bx, T& by, T& bz) const
00353     
00354   {
00355     a.get(ax, ay, az);
00356     b.get(bx, by, bz);
00357   }
00358 
00359   template <typename T>
00360   BALL_INLINE 
00361   void TSimpleBox3<T>::swap(TSimpleBox3<T>& box)
00362     
00363   {
00364     a.swap(box.a);
00365     b.swap(box.b);
00366   }
00367 
00368   template <typename T>
00369   BALL_INLINE
00370   void TSimpleBox3<T>::clear()
00371     
00372   {
00373     a.set((T)0, (T)0, (T)0);
00374     b.set((T)0, (T)0, (T)0);
00375   }
00376 
00377   template <typename T>
00378   BALL_INLINE 
00379   T TSimpleBox3<T>::getSurface() const
00380     
00381   {
00382     T width  = Maths::abs(b.x - a.x);
00383     T height = Maths::abs(b.y - a.y);
00384     T depth  = Maths::abs(b.z - a.z);
00385     
00386     return ((width  * height + width  * depth  + height * depth) * 2);
00387   }
00388 
00389   template <typename T>
00390   BALL_INLINE 
00391   T TSimpleBox3<T>::getVolume() const
00392     
00393   {
00394     T width  = Maths::abs(b.x - a.x);
00395     T height = Maths::abs(b.y - a.y);
00396     T depth  = Maths::abs(b.z - a.z);
00397     
00398     return (width * height * depth);
00399   }
00400 
00401   template <typename T>
00402   BALL_INLINE 
00403   T TSimpleBox3<T>::getWidth() const
00404     
00405   {
00406     return Maths::abs(b.x - a.x);
00407   }
00408 
00409   template <typename T>
00410   BALL_INLINE
00411   T TSimpleBox3<T>::getHeight() const
00412     
00413   {
00414     return Maths::abs(b.y - a.y);
00415   }
00416 
00417   template <typename T>
00418   BALL_INLINE
00419   T TSimpleBox3<T>::getDepth() const
00420     
00421   {
00422     return Maths::abs(b.z - a.z);
00423   }
00424 
00425   template <typename T>
00426   void TSimpleBox3<T>::join(const TSimpleBox3<T>& box)
00427     
00428   {
00429     T minimum = a.x;
00430     minimum = Maths::min(minimum, b.x);
00431     minimum = Maths::min(minimum, box.a.x);
00432     minimum = Maths::min(minimum, box.b.x);
00433     
00434     T maximum = a.x;
00435     maximum = Maths::max(maximum, b.x);
00436     maximum = Maths::max(maximum, box.a.x);
00437     maximum = Maths::max(maximum, box.b.x);
00438     
00439     a.x = minimum;
00440     b.x = maximum;
00441     
00442     minimum = a.y;
00443     minimum = Maths::min(minimum, b.y);
00444     minimum = Maths::min(minimum, box.a.y);
00445     minimum = Maths::min(minimum, box.b.y);
00446 
00447     maximum = a.y;
00448     maximum = Maths::max(maximum, b.y);
00449     maximum = Maths::max(maximum, box.a.y);
00450     maximum = Maths::max(maximum, box.b.y);
00451     
00452     a.y = minimum;
00453     b.y = maximum;
00454     
00455     minimum = a.z;
00456     minimum = Maths::min(minimum, b.z);
00457     minimum = Maths::min(minimum, box.a.z);
00458     minimum = Maths::min(minimum, box.b.z);
00459 
00460     maximum = a.z;
00461     maximum = Maths::max(maximum, b.z);
00462     maximum = Maths::max(maximum, box.a.z);
00463     maximum = Maths::max(maximum, box.b.z);
00464 
00465     a.z = minimum;
00466     b.z = maximum;
00467   }
00468 
00469   template <typename T>
00470   BALL_INLINE 
00471   bool TSimpleBox3<T>::operator == (const TSimpleBox3<T>& box) const
00472     
00473   {
00474     return (a == box.a && b == box.b);
00475   }
00476 
00477   template <typename T>
00478   BALL_INLINE 
00479   bool TSimpleBox3<T>::operator != (const TSimpleBox3<T> &box) const
00480     
00481   {
00482     return !(*this == box);
00483   }
00484 
00485   template <typename T>
00486   BALL_INLINE 
00487   bool TSimpleBox3<T>::isValid() const
00488     
00489   {
00490     return (a.isValid() && b.isValid());
00491   }
00492 
00493   template <typename T>
00494   bool TSimpleBox3<T>::has(const TVector3<T>& point, bool on_surface) const
00495     
00496   {
00497     if (!on_surface)
00498     {
00499       if (Maths::isLess(b[0],a[0]) || Maths::isLess(b[1],a[1]) || Maths::isLess(b[2],a[2]))
00500       {
00501         for (int i = 0; i < 3; i++)
00502         {
00503           if (Maths::isLess(point[i],b[i]) || Maths::isLess(a[i],point[i]))
00504           {
00505             return false;
00506           }           
00507         }
00508       }
00509       else
00510       {
00511         for (int i = 0; i < 3; i++)
00512         {
00513           if (Maths::isLess(point[i],a[i]) || Maths::isLess(b[i],point[i]))
00514           {
00515             return false;
00516           }           
00517         }
00518       }
00519       return true;
00520     }
00521 
00522     bool temp = false;
00523     for (int i = 0; i < 3; i++)
00524     {
00525       if (Maths::isEqual(point[i],a[i]) || Maths::isEqual(point[i],b[i]))
00526       {
00527         temp = true;
00528         break;
00529       }
00530     }
00531     return (temp && has(point, false));
00532   }
00533 
00534   template <typename T>
00535   bool TSimpleBox3<T>::isIntersecting(const TSimpleBox3& box) const
00536     
00537   {
00538     const TVector3<T>* lower;
00539     const TVector3<T>* higher;
00540     const TVector3<T>* box_lower;
00541     const TVector3<T>* box_higher;
00542 
00543     if (Maths::isLess(b[0],a[0]) || 
00544         Maths::isLess(b[1],a[1]) || 
00545         Maths::isLess(b[2],a[2]))
00546     {
00547       lower  = &b;
00548       higher = &a;
00549     }
00550     else
00551     {
00552       lower  = &a; 
00553       higher = &b;
00554     }
00555 
00556     if (Maths::isLess(box.b[0],box.a[0]) || 
00557         Maths::isLess(box.b[1],box.a[1]) ||
00558         Maths::isLess(box.b[2],box.a[2]))
00559     {
00560       box_lower  = &box.b;
00561       box_higher = &box.a;
00562     }
00563     else
00564     {
00565       box_lower  = &box.a;
00566       box_higher = &box.b;;
00567     }
00568 
00569     for (int i = 0; i < 3; i++)
00570     {
00571       if (Maths::isLess((*box_higher)[i],(*lower)[i]) || Maths::isLess((*higher)[i],(*box_lower)[i]))
00572       {
00573         return false;
00574       }
00575     }
00576     
00577     return true;
00578   }
00579 
00580   template <typename T>
00581   void TSimpleBox3<T>::dump(std::ostream& s, Size depth) const
00582     
00583   {
00584     BALL_DUMP_STREAM_PREFIX(s);
00585     
00586     BALL_DUMP_HEADER(s, this, this);
00587     
00588     BALL_DUMP_DEPTH(s, depth);
00589     s << "  a: " << a << std::endl;
00590     
00591     BALL_DUMP_DEPTH(s, depth);
00592     s << "  b: " << b << std::endl;
00593     
00594     BALL_DUMP_STREAM_SUFFIX(s);
00595   }
00596 
00600 
00605   template <typename T>
00606   std::istream& operator >> (std::istream& s, TSimpleBox3<T>& box)
00607     
00608   {
00609     char c;
00610     s >> c >> box.a >> box.b >> c;
00611     return s;
00612   }
00613 
00622   template <typename T>
00623   std::ostream& operator << (std::ostream& s, const TSimpleBox3<T>& box)
00624     
00625   {
00626     return s << "(" << box.a << ' ' << box.b << ')';
00627   }
00628 
00632   typedef TSimpleBox3<float> SimpleBox3;
00633 
00634 } // namespace BALL
00635 
00636 #endif // BALL_MATHS_SimpleBox3_H