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