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
00021
00022
00023
00024 #define CBBOX const BBOX
00025
00026 class BBOX {
00027 protected:
00028 bool _valid;
00029 mlib::Wpt _max;
00030 mlib::Wpt _min;
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
00041 void reset() { _valid = false; }
00042
00043 bool valid() const { return _valid; }
00044
00045 mlib::Wpt min() const { return _min; }
00046
00047 mlib::Wpt max() const { return _max; }
00048
00049 mlib::Wpt center() const { return (_min + _max)/2; }
00050
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
00057 bool points (mlib::Wpt_list&p) const;
00058
00059
00060 bool overlaps (CBBOX &b) const;
00061
00062 bool contains (mlib::CWpt &p) const;
00063
00064 bool intersects(CRAYhit &r, mlib::CWtransf &m) const;
00065
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
00072 BBOX &operator+=(CBBOX &b)
00073 { return (!b.valid() ? *this : update(b.min()).update(b.max())); }
00074
00075
00076 BBOX &operator*=(mlib::CWtransf &x);
00077
00078
00079 friend BBOX operator* (mlib::CWtransf &x, CBBOX &b)
00080 { BBOX nb(b); return nb *= x;}
00081
00082
00083 BBOX &update (mlib::CWpt &p);
00084
00085
00086 BBOX &update (mlib::CWpt_list &p);
00087
00088
00089 void set (mlib::CWpt &l, mlib::CWpt &h) {_valid=true; _min=l; _max=h;}
00090
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
00096 bool operator==(CBBOX &bb) const { return (!bb.valid() && !valid()) ||
00097 bb.valid() == valid() && bb.min() == min() && bb.max()==max(); }
00098 };
00099
00100
00101 inline BBOX
00102 operator+(CBBOX& b1, CBBOX& b2)
00103 {
00104 BBOX ret = b1;
00105 ret += b2;
00106 return ret;
00107 }
00108
00109
00110
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
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