00001
00002 #ifndef vgl_box_2d_txx_
00003 #define vgl_box_2d_txx_
00004
00005
00006
00007 #include "vgl_box_2d.h"
00008 #include <vcl_iostream.h>
00009 #include <vcl_algorithm.h>
00010 #include <vcl_cassert.h>
00011 #include <vcl_cmath.h>
00012 #include <vgl/vgl_point_2d.h>
00013
00014
00015
00016 template <class Type>
00017 vgl_box_2d<Type>::vgl_box_2d()
00018 {
00019 min_pos_[0]=min_pos_[1]=(Type)1;
00020 max_pos_[0]=max_pos_[1]=(Type)0;
00021 }
00022
00023 template <class Type>
00024 vgl_box_2d<Type>::vgl_box_2d(Type const corner1[2],
00025 Type const corner2[2])
00026 {
00027 min_pos_[0]=max_pos_[0]=corner1[0];
00028 min_pos_[1]=max_pos_[1]=corner1[1];
00029 this->add(corner2);
00030 }
00031
00032 template <class Type>
00033 vgl_box_2d<Type>::vgl_box_2d(vgl_point_2d<Type> const& corner1,
00034 vgl_point_2d<Type> const& corner2)
00035 {
00036 min_pos_[0]=max_pos_[0]=corner1.x();
00037 min_pos_[1]=max_pos_[1]=corner1.y();
00038 this->add(corner2);
00039 }
00040
00041 template <class Type>
00042 vgl_box_2d<Type>::vgl_box_2d(Type xmin, Type xmax, Type ymin, Type ymax)
00043 {
00044 min_pos_[0]=max_pos_[0]=xmin;
00045 min_pos_[1]=max_pos_[1]=ymin;
00046 this->add(vgl_point_2d<Type>(xmax,ymax));
00047 if (xmin > xmax || ymin > ymax) this->empty();
00048 }
00049
00050 template <class Type>
00051 vgl_box_2d<Type>::vgl_box_2d(Type const ref_point[2],
00052 Type w, Type h,
00053 typename vgl_box_2d<Type>::point_type t)
00054 {
00055 if (t == vgl_box_2d<Type>::centre)
00056 {
00057 min_pos_[0]=Type(ref_point[0]-0.5*w);
00058 min_pos_[1]=Type(ref_point[1]-0.5*h);
00059 max_pos_[0]=Type(ref_point[0]+0.5*w);
00060 max_pos_[1]=Type(ref_point[1]+0.5*h);
00061 }
00062 else if (t == vgl_box_2d<Type>::min_pos)
00063 {
00064 min_pos_[0]=ref_point[0];
00065 min_pos_[1]=ref_point[1];
00066 max_pos_[0]=ref_point[0]+w;
00067 max_pos_[1]=ref_point[1]+h;
00068 }
00069 else if (t == vgl_box_2d<Type>::max_pos)
00070 {
00071 min_pos_[0]=ref_point[0]-w;
00072 min_pos_[1]=ref_point[1]-h;
00073 max_pos_[0]=ref_point[0];
00074 max_pos_[1]=ref_point[1];
00075 }
00076 else
00077 assert(!"point_type should be one of: centre, min_pos, max_pos");
00078 }
00079
00080 template <class Type>
00081 vgl_box_2d<Type>::vgl_box_2d(vgl_point_2d<Type> const& ref_point,
00082 Type w, Type h,
00083 typename vgl_box_2d<Type>::point_type t)
00084 {
00085 if (t == vgl_box_2d<Type>::centre)
00086 {
00087 min_pos_[0]=Type(ref_point.x()-0.5*w);
00088 min_pos_[1]=Type(ref_point.y()-0.5*h);
00089 max_pos_[0]=Type(ref_point.x()+0.5*w);
00090 max_pos_[1]=Type(ref_point.y()+0.5*h);
00091 }
00092 else if (t == vgl_box_2d<Type>::min_pos)
00093 {
00094 min_pos_[0]=ref_point.x();
00095 min_pos_[1]=ref_point.y();
00096 max_pos_[0]=ref_point.x()+w;
00097 max_pos_[1]=ref_point.y()+h;
00098 }
00099 else if (t == vgl_box_2d<Type>::max_pos)
00100 {
00101 min_pos_[0]=ref_point.x()-w;
00102 min_pos_[1]=ref_point.y()-h;
00103 max_pos_[0]=ref_point.x();
00104 max_pos_[1]=ref_point.y();
00105 }
00106 else
00107 assert(!"point_type should be one of: centre, min_pos, max_pos");
00108 }
00109
00110 template <class Type>
00111 Type vgl_box_2d<Type>::centroid_x() const
00112 {
00113 assert(!is_empty());
00114 return Type(0.5*(min_pos_[0] + max_pos_[0]));
00115 }
00116
00117 template <class Type>
00118 Type vgl_box_2d<Type>::centroid_y() const
00119 {
00120 assert(!is_empty());
00121 return Type(0.5*(min_pos_[1] + max_pos_[1]));
00122 }
00123
00124 template <class Type>
00125 Type vgl_box_2d<Type>::width() const
00126 {
00127 return (max_pos_[0] > min_pos_[0]) ? max_pos_[0] - min_pos_[0] : 0;
00128 }
00129
00130 template <class Type>
00131 Type vgl_box_2d<Type>::height() const
00132 {
00133 return (max_pos_[1] > min_pos_[1]) ? max_pos_[1] - min_pos_[1] : 0;
00134 }
00135
00136 template <class Type>
00137 vgl_point_2d<Type> vgl_box_2d<Type>::min_point() const
00138 {
00139 assert(!is_empty());
00140 return vgl_point_2d<Type>(min_pos_[0],min_pos_[1]);
00141 }
00142
00143 template <class Type>
00144 vgl_point_2d<Type> vgl_box_2d<Type>::max_point() const
00145 {
00146 assert(!is_empty());
00147 return vgl_point_2d<Type>(max_pos_[0],max_pos_[1]);
00148 }
00149
00150 template <class Type>
00151 vgl_point_2d<Type> vgl_box_2d<Type>::centroid() const
00152 {
00153 assert(!is_empty());
00154 return vgl_point_2d<Type>(centroid_x(),centroid_y());
00155 }
00156
00157 template <class Type>
00158 void vgl_box_2d<Type>::set_centroid_x(Type cent_x)
00159 {
00160 assert(!is_empty());
00161 Type delta = cent_x - centroid_x();
00162 min_pos_[0]= min_pos_[0] + delta;
00163 max_pos_[0]= max_pos_[0] + delta;
00164 }
00165
00166 template <class Type>
00167 void vgl_box_2d<Type>::set_centroid_y(Type cent_y)
00168 {
00169 assert(!is_empty());
00170 Type delta = cent_y - centroid_y();
00171 min_pos_[1]= min_pos_[1] + delta;
00172 max_pos_[1]= max_pos_[1] + delta;
00173 }
00174
00175 template <class T>
00176 inline void set_dim_2d(T & minv, T& maxv, T spread);
00177
00178
00179 VCL_DEFINE_SPECIALIZATION
00180 inline void set_dim_2d(int & minv, int& maxv, int spread)
00181 {
00182 int sum = minv + maxv;
00183 sum = sum | (spread&1);
00184 minv = int(vcl_floor((sum-spread)/2.0));
00185 maxv = minv+spread;
00186 }
00187
00188 template <class T>
00189 inline void set_dim_2d(T & minv, T& maxv, T spread)
00190 {
00191 T x = minv + maxv;
00192 minv = T( (x-spread)*0.5 );
00193 maxv = minv + spread;
00194 }
00195
00196
00197
00198
00199 template <class Type>
00200 void vgl_box_2d<Type>::set_width(Type w)
00201 {
00202 assert(!is_empty());
00203 set_dim_2d(min_pos_[0], max_pos_[0], w);
00204 }
00205
00206
00207
00208
00209 template <class Type>
00210 void vgl_box_2d<Type>::set_height(Type h)
00211 {
00212 assert(!is_empty());
00213 set_dim_2d(min_pos_[1], max_pos_[1], h);
00214 }
00215
00216
00217
00218
00219 template <class Type>
00220 void vgl_box_2d<Type>::expand_about_centroid(Type expand)
00221 {
00222 assert(!is_empty());
00223 set_dim_2d(min_pos_[0], max_pos_[0], width() + expand );
00224 set_dim_2d(min_pos_[1], max_pos_[1], height() + expand );
00225 }
00226
00227
00228 template <class Type>
00229 void vgl_box_2d<Type>::scale_about_centroid(double s)
00230 {
00231 assert(!is_empty());
00232 set_dim_2d(min_pos_[0], max_pos_[0], static_cast<Type>(width()*s));
00233 set_dim_2d(min_pos_[1], max_pos_[1], static_cast<Type>(height()*s));
00234 }
00235
00236
00237
00238 template <class Type>
00239 void vgl_box_2d<Type>::scale_about_origin(double s)
00240 {
00241 min_pos_[0] = static_cast<Type>(min_pos_[0] * s);
00242 min_pos_[1] = static_cast<Type>(min_pos_[1] * s);
00243 max_pos_[0] = static_cast<Type>(max_pos_[0] * s);
00244 max_pos_[1] = static_cast<Type>(max_pos_[1] * s);
00245 }
00246
00247 template <class Type>
00248 void vgl_box_2d<Type>::setmin_position(Type const min_position[2])
00249 {
00250 min_pos_[0]=min_position[0];
00251 min_pos_[1]=min_position[1];
00252 if (max_pos_[0] < min_pos_[0]) {
00253 max_pos_[0]=min_pos_[0];
00254 }
00255 if (max_pos_[1] < min_pos_[1]) {
00256 max_pos_[1]=min_pos_[1];
00257 }
00258 }
00259
00260 template <class Type>
00261 void vgl_box_2d<Type>::setmax_position(Type const max_position[2])
00262 {
00263 max_pos_[0]=max_position[0];
00264 max_pos_[1]=max_position[1];
00265 if (max_pos_[0] < min_pos_[0])
00266 min_pos_[0]=max_pos_[0];
00267 if (max_pos_[1] < min_pos_[1])
00268 min_pos_[1]=max_pos_[1];
00269 }
00270
00271 template <class Type>
00272 void vgl_box_2d<Type>::set_min_point(vgl_point_2d<Type> const& min_pt)
00273 {
00274 min_pos_[0]=min_pt.x(); if (max_pos_[0]<min_pos_[0]) max_pos_[0]=min_pos_[0];
00275 min_pos_[1]=min_pt.y(); if (max_pos_[1]<min_pos_[1]) max_pos_[1]=min_pos_[1];
00276 }
00277
00278 template <class Type>
00279 void vgl_box_2d<Type>::set_max_point(vgl_point_2d<Type> const& max_pt)
00280 {
00281 max_pos_[0]=max_pt.x(); if (max_pos_[0]<min_pos_[0]) min_pos_[0]=max_pos_[0];
00282 max_pos_[1]=max_pt.y(); if (max_pos_[1]<min_pos_[1]) min_pos_[1]=max_pos_[1];
00283 }
00284
00285 template <class Type>
00286 vcl_ostream& vgl_box_2d<Type>::print(vcl_ostream& s) const
00287 {
00288 if (is_empty())
00289 return s << "<vgl_box_2d (empty)>";
00290 else
00291 return s << "<vgl_box_2d "
00292 << min_pos_[0] << ',' << min_pos_[1] << " to "
00293 << max_pos_[0] << ',' << max_pos_[1] << '>';
00294 }
00295
00296 template <class Type>
00297 vcl_ostream& vgl_box_2d<Type>::write(vcl_ostream& s) const
00298 {
00299 return s << min_pos_[0] << ' ' << min_pos_[1] << ' '
00300 << max_pos_[0] << ' ' << max_pos_[1] << '\n';
00301 }
00302
00303 template <class Type>
00304 vcl_istream& vgl_box_2d<Type>::read(vcl_istream& s)
00305 {
00306 return s >> min_pos_[0] >> min_pos_[1]
00307 >> max_pos_[0] >> max_pos_[1];
00308 }
00309
00310
00311
00312
00313 template <class Type>
00314 void vgl_box_2d<Type>::add(vgl_point_2d<Type> const& p)
00315 {
00316 if (is_empty())
00317 {
00318 min_pos_[0] = max_pos_[0] = p.x();
00319 min_pos_[1] = max_pos_[1] = p.y();
00320 }
00321 else
00322 {
00323 if (p.x() > max_pos_[0]) max_pos_[0] = p.x();
00324 if (p.x() < min_pos_[0]) min_pos_[0] = p.x();
00325 if (p.y() > max_pos_[1]) max_pos_[1] = p.y();
00326 if (p.y() < min_pos_[1]) min_pos_[1] = p.y();
00327 }
00328 }
00329
00330
00331
00332
00333
00334 template <class Type>
00335 void vgl_box_2d<Type>::add(vgl_box_2d<Type> const& b)
00336 {
00337 if (b.is_empty()) return;
00338 add(b.min_point());
00339 add(b.max_point());
00340 }
00341
00342
00343 template <class Type>
00344 bool vgl_box_2d<Type>::contains(vgl_point_2d<Type> const& p) const
00345 {
00346 return contains(p.x(), p.y());
00347 }
00348
00349
00350 template <class Type>
00351 bool vgl_box_2d<Type>::contains(vgl_box_2d<Type> const& b) const
00352 {
00353 return
00354 contains(b.min_x(), b.min_y()) &&
00355 contains(b.max_x(), b.max_y());
00356 }
00357
00358
00359 template <class Type>
00360 void vgl_box_2d<Type>::empty()
00361 {
00362 min_pos_[0]=min_pos_[1]=(Type)1;
00363 max_pos_[0]=max_pos_[1]=(Type)0;
00364 }
00365
00366
00367 template <class Type>
00368 vcl_ostream& operator<<(vcl_ostream& s, vgl_box_2d<Type> const& p)
00369 {
00370 return p.print(s);
00371 }
00372
00373
00374 template <class Type>
00375 vcl_istream& operator>>(vcl_istream& is, vgl_box_2d<Type>& p)
00376 {
00377 return p.read(is);
00378 }
00379
00380 #undef VGL_BOX_2D_INSTANTIATE
00381 #define VGL_BOX_2D_INSTANTIATE(Type) \
00382 template class vgl_box_2d<Type >;\
00383 template vcl_istream& operator>>(vcl_istream&, vgl_box_2d<Type >&);\
00384 template vcl_ostream& operator<<(vcl_ostream&, vgl_box_2d<Type > const&)
00385
00386 #endif // vgl_box_2d_txx_