00001 // This is core/vgl/vgl_box_3d.h 00002 #ifndef vgl_box_3d_h 00003 #define vgl_box_3d_h 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Contains class to represent a cartesian 3D bounding box. 00010 // \author Don Hamilton, Peter Tu 00011 // \date 15 Feb 2000 00012 // 00013 // \verbatim 00014 // Modifications 00015 // Peter Vanroose, 28 Feb 2000: lots of minor corrections 00016 // NPC (Manchester)14 Mar 2001: Tidied up the documentation + added binary_io 00017 // Peter Vanroose, 10 Jul 2001: Deprecated get_*() in favour of *(), and explicit casts 00018 // Peter Vanroose, 5 Oct 2001: Added operator==() and methods is_empty() and contains() 00019 // Peter Vanroose, 6 Oct 2001: Added method add(vgl_point_3d<T>) to enlarge a box 00020 // Peter Vanroose, 7 Oct 2001: Removed deprecated get_*() functions 00021 // Peter Vanroose, Feb 2002: brief doxygen comment placed on single line 00022 // Peter Vanroose, 12 Sep 2002: Added method add(vgl_box_3d<T>) to enlarge a box 00023 // Peter Vanroose, 13 May 2003: Constructor interface change (compat with vgl_box_2d) 00024 // Peter Vanroose 15 Oct 2003: Removed deprecated constructors without 5th arg 00025 // Peter Vanroose 16 Oct 2003: Corner pts given to constructor may now be in any order 00026 // Peter Vanroose 16 Oct 2003: Added intersect(box1,box2) 00027 // Gamze Tunali 25 Jan 2007: Moved intersect(box1,box2) to vgl_intersection 00028 // Peter Vanroose 30 Mar 2007: Commented out deprecated intersect() function 00029 // Peter Vanroose 22 Jul 2009: Moved vgl_intersection() to vgl_intersection.h 00030 // \endverbatim 00031 00032 #include <vcl_iosfwd.h> 00033 #include <vcl_vector.h> 00034 #include <vgl/vgl_fwd.h> // forward declare vgl_point_3d 00035 00036 //: Represents a cartesian 3D box 00037 // A 3d box with sides aligned with \a x, \a y and \a z axes. Supports operations 00038 // required of a bounding box for geometric volume tests. 00039 // 00040 // A box can be empty; this is what the default constructor creates, or what 00041 // is left after applying the empty() method. Use the add() methods to enlarge 00042 // a box, and use the contains() methods to check for inclusion of a point or 00043 // an other box. 00044 // 00045 // To make the convex union of two boxes, use box1.add(box2). 00046 // \verbatim 00047 // MaxPosition 00048 // |<--width-->| 00049 // O-----------O --- 00050 // / /| ^ 00051 // / / | | 00052 // O-----------O | height 00053 // | o | | | 00054 // | centroid | | v 00055 // | | O --- 00056 // Y | | / /_____depth 00057 // | Z | |/ / 00058 // | / O-----------O --- 00059 // | / MinPosition 00060 // O-----X 00061 // \endverbatim 00062 // \sa vgl_box_2d 00063 00064 template <class Type> 00065 class vgl_box_3d 00066 { 00067 public: 00068 00069 //: Default constructor (creates empty box) 00070 vgl_box_3d(); 00071 00072 //: Construct using two corner points 00073 vgl_box_3d(Type const corner1[3], 00074 Type const corner2[3]); 00075 00076 //: Construct using two corner points 00077 vgl_box_3d(vgl_point_3d<Type> const& corner1, 00078 vgl_point_3d<Type> const& corner2); 00079 00080 //: Construct from ranges in \a x,y,z (take care with order of inputs). 00081 // The \a x range is given by the 1st and 4th coordinates, 00082 // the \a y range is given by the 2nd and 5th coordinates, 00083 // the \a z range is given by the 3rd and 6th coordinates. 00084 vgl_box_3d(Type xmin, Type ymin, Type zmin, 00085 Type xmax, Type ymax, Type zmax); 00086 00087 enum point_type { centre=0, min_pos, max_pos }; 00088 00089 //: Construct a box sized width x height x depth at a given reference point. 00090 // The box will either be centered at ref_point or will have ref_point 00091 // as its min-position or max-position, as specified by the 5th argument. 00092 vgl_box_3d(Type const ref_point[3], 00093 Type width, Type height, Type depth, 00094 point_type); 00095 00096 //: Construct a box sized width x height x depth at a given reference point. 00097 // The box will either be centered at ref_point or will have ref_point 00098 // as its min-position or max-position, as specified by the 5th argument. 00099 vgl_box_3d(vgl_point_3d<Type> const& ref_point, 00100 Type width, Type height, Type depth, 00101 point_type); 00102 00103 //: Equality test 00104 inline bool operator==(vgl_box_3d<Type> const& b) const { 00105 // All empty boxes are equal: 00106 if (b.is_empty()) return is_empty(); 00107 return min_x() == b.min_x() && min_y() == b.min_y() && min_z() == b.min_z() 00108 && max_x() == b.max_x() && max_y() == b.max_y() && max_z() == b.max_z(); 00109 } 00110 00111 // Data Access--------------------------------------------------------------- 00112 00113 //: Get width of this box (= \a x dimension) 00114 Type width() const; 00115 //: Get height of this box (= \a y dimension) 00116 Type height() const; 00117 //: Get depth of this box (= \a z dimension) 00118 Type depth() const; 00119 00120 //: Get volume of this box 00121 inline Type volume() const { return width()*height()*depth(); } 00122 00123 //: Get min \a x 00124 inline Type min_x() const { return min_pos_[0]; } 00125 //: Get min \a y 00126 inline Type min_y() const { return min_pos_[1]; } 00127 //: Get min \a z 00128 inline Type min_z() const { return min_pos_[2]; } 00129 00130 //: Get max \a x 00131 inline Type max_x() const { return max_pos_[0]; } 00132 //: Get max \a y 00133 inline Type max_y() const { return max_pos_[1]; } 00134 //: Get max \a z 00135 inline Type max_z() const { return max_pos_[2]; } 00136 00137 //: Get the centroid point 00138 vgl_point_3d<Type> centroid() const; 00139 //: Get \a x component of centroid 00140 Type centroid_x() const; 00141 //: Get \a y component of centroid 00142 Type centroid_y() const; 00143 //: Get \a z component of centroid 00144 Type centroid_z() const; 00145 00146 //: Return lower left corner of box 00147 vgl_point_3d<Type> min_point() const; 00148 00149 //: Return upper right corner of box 00150 vgl_point_3d<Type> max_point() const; 00151 00152 //: Return the 8 vertices of the box 00153 vcl_vector<vgl_point_3d<Type> > vertices() const; 00154 00155 // Data Control-------------------------------------------------------------- 00156 00157 //: Return true if this box is empty 00158 inline bool is_empty() const { 00159 return min_x() > max_x() || min_y() > max_y() || min_z() > max_z(); 00160 } 00161 00162 //: Add a point to this box. 00163 // Do this by possibly enlarging the box so that the point just falls within the box. 00164 // Adding a point to an empty box makes it a size zero box only containing p. 00165 void add(vgl_point_3d<Type> const& p); 00166 00167 //: Make the convex union of two boxes. 00168 // Do this by possibly enlarging this box so that the corner points of the 00169 // given box just fall within the box. 00170 // Adding an empty box does not change the current box. 00171 void add(vgl_box_3d<Type> const& b); 00172 00173 //: Return true iff the point p is inside this box 00174 bool contains(vgl_point_3d<Type> const& p) const; 00175 00176 //: Return true iff the corner points of b are inside this box 00177 bool contains(vgl_box_3d<Type> const& b) const; 00178 00179 //: Return true if \a (x,y,z) is inside this box, ie \a x_min <= \a x <= \a x_max etc 00180 inline bool contains(Type const& x, Type const& y, Type const& z) const { 00181 return x >= min_x() && x <= max_x() && 00182 y >= min_y() && y <= max_y() && 00183 z >= min_z() && z <= max_z(); 00184 } 00185 00186 //: Make the box empty 00187 void empty(); 00188 00189 //: Set min \a x ordinate of box (other sides unchanged) 00190 inline void set_min_x(Type m) { min_pos_[0]=m; } 00191 //: Set min \a y ordinate of box (other sides unchanged) 00192 inline void set_min_y(Type m) { min_pos_[1]=m; } 00193 //: Set min \a z ordinate of box (other sides unchanged) 00194 inline void set_min_z(Type m) { min_pos_[2]=m; } 00195 00196 //: Set max \a x ordinate of box (other sides unchanged) 00197 inline void set_max_x(Type m) { max_pos_[0]=m; } 00198 //: Set max \a y ordinate of box (other sides unchanged) 00199 inline void set_max_y(Type m) { max_pos_[1]=m; } 00200 //: Set max \a z ordinate of box (other sides unchanged) 00201 inline void set_max_z(Type m) { max_pos_[2]=m; } 00202 00203 //: Move box so centroid lies at cx (size unchanged) 00204 void set_centroid_x(Type cx); 00205 //: Move box so centroid lies at cy (size unchanged) 00206 void set_centroid_y(Type cy); 00207 //: Move box so centroid lies at cz (size unchanged) 00208 void set_centroid_z(Type cz); 00209 00210 //: Set width (x), centroid unchanged 00211 void set_width(Type width); 00212 //: Set height (y), centroid unchanged 00213 void set_height(Type height); 00214 //: Set depth (z), centroid unchanged 00215 void set_depth(Type depth); 00216 00217 00218 //: Add to width and height, centroid unchanged. 00219 // Will move each side by \p expand / 2. 00220 void expand_about_centroid(Type expand); 00221 //: Scale width, height and depth, centroid unchanged. 00222 void scale_about_centroid(double s); 00223 //: Scale width, height and depth, keeping scaled position of origin unchanged. 00224 void scale_about_origin(double s); 00225 00226 //: Modify min corner point. Max corner point only changed if necessary to avoid empty box 00227 void set_min_position(Type const m[3]); 00228 //: Modify max corner point. Min corner point only changed if necessary to avoid empty box 00229 void set_max_position(Type const m[3]); 00230 //: Modify min corner point. Max corner point only changed if necessary to avoid empty box 00231 void set_min_point(vgl_point_3d<Type> const& min_pt); 00232 //: Modify max corner point. Min corner point only changed if necessary to avoid empty box 00233 void set_max_point(vgl_point_3d<Type> const& max_pt); 00234 //: Move box so centroid lies at c (size unchanged) 00235 inline void set_centroid(Type const c[3]) { set_centroid_x(c[0]); set_centroid_y(c[1]); set_centroid_z(c[2]); } 00236 //: Move box so centroid lies at c (size unchanged) 00237 inline void set_centroid(vgl_point_3d<Type> const& c) { set_centroid_x(c.x()); set_centroid_y(c.y()); set_centroid_z(c.z()); } 00238 00239 // I/O----------------------------------------------------------------------- 00240 00241 //: Write "<vgl_box_3d x0,y0,z0 to x1,y1,z1>" to stream 00242 vcl_ostream& print(vcl_ostream&) const; 00243 00244 //: Write "x0 y0 z0 x1 y1 z1(endl)" to stream 00245 vcl_ostream& write(vcl_ostream&) const; 00246 00247 //: Read x0,y0,z0,x1,y1,z1 from stream 00248 vcl_istream& read(vcl_istream&); 00249 00250 // INTERNALS----------------------------------------------------------------- 00251 protected: 00252 // Data Members-------------------------------------------------------------- 00253 Type min_pos_[3]; 00254 Type max_pos_[3]; 00255 }; 00256 00257 //: Write box to stream 00258 // \relatesalso vgl_box_3d 00259 template <class Type> 00260 vcl_ostream& operator<<(vcl_ostream& s, vgl_box_3d<Type> const& p); 00261 00262 //: Read box from stream 00263 // \relatesalso vgl_box_3d 00264 template <class Type> 00265 vcl_istream& operator>>(vcl_istream& is, vgl_box_3d<Type>& p); 00266 00267 //: Calculate the bounding box of a sequence of points or boxes. 00268 template <class T, class ITER> 00269 void vgl_box_3d_bounds(ITER begin, ITER end, vgl_box_3d<T>& bounding_box) 00270 { 00271 for (; begin != end; ++begin) 00272 bounding_box.add(*begin); 00273 } 00274 00275 #define VGL_BOX_3D_INSTANTIATE(T) extern "please include vgl/vgl_box_3d.txx first" 00276 00277 #endif // vgl_box_3d_h