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