Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

bbox.H

Go to the documentation of this file.
00001 #ifndef BBOX_H
00002 #define BBOX_H
00003 
00004 #include "std/support.H"
00005 #include "mlib/points.H"
00006 
00007 
00008 
00009 #ifdef WIN32
00010 #undef min
00011 #undef max
00012 #endif
00013 
00014 
00015 class RAYhit;
00016 #define CRAYhit const RAYhit
00017 class GELptr;
00018 typedef const GELptr CGELptr;
00019 
00020 /* ------------------ class definitions --------------------- */
00021 ///
00022 /// BBOX - 3D axis aligned bounding box
00023 ///
00024 #define CBBOX const BBOX
00025 
00026 class BBOX {
00027  protected:
00028   bool  _valid; ///< is bounding box valid?
00029   mlib::Wpt   _max; ///< One of the two corners defining the box extent
00030   mlib::Wpt   _min; ///< One of the two corners defining the box extent
00031  public:
00032    BBOX() : _valid(false) {}
00033    BBOX(mlib::CWpt &l, mlib::CWpt &h) :
00034       _valid(true),
00035       _max(::max(l[0],h[0]),::max(l[1],h[1]),::max(l[2],h[2])),
00036       _min(::min(l[0],h[0]),::min(l[1],h[1]),::min(l[2],h[2])) {} 
00037    BBOX(CBBOX& b) : _valid(b._valid),_max(b._max),_min(b._min){}
00038    BBOX(CGELptr  &g, int recurse = 0);
00039 
00040   /// Invalidate
00041    void        reset()                              { _valid = false; }
00042   /// Is bounding box a valid one?
00043    bool        valid()                       const  { return _valid;  }
00044   /// One of the two corners defining the box - the so-called 'minimum' corner
00045    mlib::Wpt   min()                         const  { return _min;    }
00046   /// One of the two corners defining the box - the so-called 'maximum' corner
00047    mlib::Wpt   max()                         const  { return _max;    }
00048   /// Center of the bounding box
00049    mlib::Wpt   center()                      const  { return (_min + _max)/2; }
00050   /// Vector containing the extent of the bounding box along all axes
00051    mlib::Wvec  dim()                         const  { return _max - _min; }
00052 
00053    double  volume()                          const  { return ((_max - _min)[0] * 
00054                                        (_max - _min)[1] * (_max - _min)[2]); }
00055    
00056   /// Return the 8 corners of the box through the reference p, function return value indicating if box is valid or not
00057    bool        points    (mlib::Wpt_list&p)  const;
00058 
00059   /// Does the box (partially) overlap the given box?
00060    bool        overlaps  (CBBOX   &b)                    const;
00061   /// Does the box contain the given point?
00062    bool        contains  (mlib::CWpt &p)                 const;
00063   /// Does box intersect the given ray?
00064    bool        intersects(CRAYhit &r, mlib::CWtransf &m) const;
00065   /// if this returns true, the bbox is definitely offscreen, but if it returns false the bbox may or may not be offscreen.
00066    bool        is_off_screen();
00067 
00068    void      ndcz_bounding_box(mlib::CWtransf &obj_to_ndc, 
00069                                mlib::NDCZpt& min_pt, mlib::NDCZpt& max_pt) const;
00070    
00071   /// Expands to subsume the given bounding box, if it is valid
00072    BBOX     &operator+=(CBBOX &b)
00073       { return (!b.valid() ?  *this : update(b.min()).update(b.max())); }
00074 
00075   /// Apply the given transform to the corner points of this box
00076    BBOX     &operator*=(mlib::CWtransf &x);
00077 
00078   /// The result of transformation of bounding box b by given world-space transform x
00079    friend BBOX  operator* (mlib::CWtransf &x, CBBOX &b)
00080       { BBOX nb(b); return nb *= x;}
00081                                                                 
00082   /// Modify self to bound the given point
00083    BBOX     &update    (mlib::CWpt      &p);
00084 
00085   /// Modify self to bound the given point list
00086    BBOX     &update    (mlib::CWpt_list &p);
00087 
00088   /// Force self to be bounding box between the two points provided
00089    void      set       (mlib::CWpt &l, mlib::CWpt &h) {_valid=true; _min=l; _max=h;}
00090   /// Output bounding box info to text stream
00091    friend ostream &operator <<(ostream &os,CBBOX &b) { if (b.valid()) 
00092                                                           os <<b.min()<<b.max();
00093                                                        else os << "(invalid)";
00094                                                        return os; }
00095   /// Are the two boxes identical?
00096    bool operator==(CBBOX &bb) const { return (!bb.valid() && !valid()) ||
00097                 bb.valid() == valid() && bb.min() == min() && bb.max()==max(); }
00098 };
00099 
00100 /// The bounding box enclosing the two given bounding boxes, neither modified in the process.
00101 inline BBOX
00102 operator+(CBBOX& b1, CBBOX& b2)
00103 {
00104    BBOX ret = b1;
00105    ret += b2;
00106    return ret;
00107 }
00108 
00109 //
00110 // BBOX2D - 2D axis aligned bounding box
00111 //
00112 #define CBBOX2D const BBOX2D
00113 class BBOX2D {
00114  protected:
00115    bool    _valid;
00116    mlib::XYpt    _max, _min;
00117  public:
00118    BBOX2D()                               :_valid(false)                             {}
00119    BBOX2D(mlib::CXYpt &l, mlib::CXYpt &h) :_valid(true),    _max(h),    _min(l)      {}
00120    BBOX2D(CBBOX2D &b)                     :_valid(b._valid),_max(b._max),_min(b._min){}
00121    BBOX2D(CGELptr  &g, int recurse = 0);
00122 
00123    void        reset()                       { _valid = false; }
00124    bool        valid()                const  { return _valid;  }
00125    mlib::XYpt  min()                  const  { return _min;    }
00126    mlib::XYpt  max()                  const  { return _max;    }
00127    mlib::XYpt  center()               const  { return (_min + _max)/2; }
00128    mlib::XYvec dim()                  const  { return _max - _min; }
00129 
00130    void scale(double s) {
00131       if (_valid) {
00132          mlib::XYvec d = dim()*(s/2.0);
00133          mlib::XYpt  c = center();
00134          _min = c - d;
00135          _max = c + d;
00136       }
00137    }
00138    bool      overlaps  (CBBOX2D &b) const;
00139    bool      contains  (mlib::CXYpt   &p) const;
00140    double    dist      (mlib::CXYpt   &p) const;
00141    BBOX2D   &operator+=(CBBOX2D &b)        { return (!b.valid() ? *this:
00142                                               update(b.min()).update(b.max()));}
00143    BBOX2D   &operator+=(mlib::CXYpt_list &pts);
00144    BBOX2D   &update    (mlib::CXYpt      &p);
00145    void      set       (mlib::CXYpt    &l, mlib::CXYpt    &h) {_valid=true; _min=l; _max=h;}
00146 };
00147 
00148 
00149 
00150 //
00151 // BBOXpix - BBOX in picture plane
00152 //
00153 #define CBBOXpix const BBOXpix
00154 class BBOXpix {
00155  protected:
00156    bool    _valid;
00157    mlib::PIXEL    _max, _min;
00158  public:
00159    BBOXpix() : _valid(false) {}
00160    BBOXpix(mlib::CPIXEL &l, mlib::CPIXEL &h) : _valid(true), _max(h), _min(l){}
00161    BBOXpix(CBBOXpix &b) :_valid(b._valid),_max(b._max),_min(b._min){}
00162 
00163    void        reset()         { _valid = false; }
00164    bool        valid()  const  { return _valid;  }
00165    mlib::PIXEL min()    const  { return _min;    }
00166    mlib::PIXEL max()    const  { return _max;    }
00167    mlib::PIXEL center() const  { return (_min + _max)/2; }
00168    mlib::VEXEL dim()    const  { return _max - _min; }
00169    double      width()  const  { return dim()*mlib::VEXEL(1.0, 0.0); }
00170    double      height()  const { return dim()*mlib::VEXEL(0.0, 1.0); }
00171 
00172    void scale(double s) {
00173      if (_valid) {
00174        mlib::VEXEL d = dim()*(s/2.0);
00175        mlib::PIXEL  c = center();
00176        _min = c - d;
00177        _max = c + d;
00178      }
00179    }
00180 
00181    bool      overlaps    (CBBOXpix &b) const;
00182    bool      contains    (mlib::CPIXEL   &p) const;
00183    double    dist        (mlib::CPIXEL   &p) const;
00184    BBOXpix   &operator+= (CBBOXpix &b) { return (!b.valid() ? *this:
00185                                                update(b.min()).update(b.max()));}
00186    BBOXpix   &operator+= (mlib::CPIXEL_list &pts);
00187    BBOXpix   &update     (mlib::CPIXEL &p);
00188    void      set         (mlib::CPIXEL &l, mlib::CPIXEL &h) {_valid=true; _min=l; _max=h;}
00189 };
00190 
00191 #endif

Generated on Mon Sep 18 11:39:28 2006 for jot by  doxygen 1.4.4