00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_CORE_SITE_SET_BOX_HH
00028 # define MLN_CORE_SITE_SET_BOX_HH
00029
00035
00036 # include <mln/core/concept/box.hh>
00037 # include <mln/core/internal/box_impl.hh>
00038 # include <mln/core/point.hh>
00039 # include <mln/literal/origin.hh>
00040
00041
00042 namespace mln
00043 {
00044
00045
00046 template <typename P> struct box;
00047 template <typename P> struct box_fwd_piter_;
00048 template <typename P> struct box_bkd_piter_;
00049
00050
00051 namespace trait
00052 {
00053
00054 template <typename P>
00055 struct site_set_< box<P> >
00056 {
00057 typedef trait::site_set::nsites::known nsites;
00058 typedef trait::site_set::bbox::straight bbox;
00059 typedef trait::site_set::contents::fixed contents;
00060 typedef trait::site_set::arity::unique arity;
00061 };
00062
00063 template <typename P>
00064 struct set_precise_unary_< op::ord, box<P> >
00065 {
00066 typedef set_precise_unary_< op::ord, box<P> > ret;
00067 bool strict(const box<P>& lhs, const box<P>& rhs) const;
00068 };
00069
00070 }
00071
00072
00079
00080 template <typename P>
00081 struct box : public Box< box<P> >,
00082 public internal::box_impl_< P::dim, mln_coord(P), box<P> >,
00083 private mlc_is_unqualif(P)::check_t
00084 {
00086 enum { dim = P::dim };
00087
00089 typedef P element;
00090
00092 typedef P psite;
00093
00095 typedef P site;
00096
00098 typedef box_fwd_piter_<P> fwd_piter;
00099
00101 typedef fwd_piter piter;
00102
00104 typedef box_bkd_piter_<P> bkd_piter;
00105
00107 P pmin() const;
00108
00110 P& pmin();
00111
00113 P pmax() const;
00114
00116 P& pmax();
00117
00119 box();
00120
00122 box(const site& pmin, const site& pmax);
00123
00126 explicit box(mln_coord(P) ninds);
00127 box(mln_coord(P) nrows, mln_coord(P) ncols);
00128 box(mln_coord(P) nslices, mln_coord(P) nrows, mln_coord(P) ncols);
00130
00135 bool has(const P& p) const;
00136
00138 void enlarge(unsigned b);
00139
00141 void enlarge(unsigned dim, unsigned b);
00142
00144 box<P> to_larger(unsigned b) const;
00145
00147 P pcenter() const;
00148
00151 bool is_valid() const;
00152
00154 void crop_wrt(const box<P>& b);
00155
00157 void merge(const box<P>& b);
00158
00160 std::size_t memory_size() const;
00161
00162 protected:
00163
00164 P pmin_, pmax_;
00165 };
00166
00167
00177 template <typename P>
00178 std::ostream& operator<<(std::ostream& ostr, const box<P>& b);
00179
00180
00182 template <typename P>
00183 inline
00184 box<P>
00185 larger_than(const box<P> a, const box<P> b);
00186
00187
00188
00189 # ifndef MLN_INCLUDE_ONLY
00190
00191 template <typename P>
00192 inline
00193 bool
00194 box<P>::is_valid() const
00195 {
00196
00197
00198 return util::ord_weak(pmin_, pmax_);
00199 }
00200
00201 template <typename P>
00202 inline
00203 void
00204 box<P>::crop_wrt(const box<P>& ref)
00205 {
00206 if (pmin_.col() < ref.pmin().col())
00207 pmin_.col() = ref.pmin().col();
00208 if (pmin_.row() < ref.pmin().row())
00209 pmin_.row() = ref.pmin().row();
00210
00211 if (pmax_.col() > ref.pmax().col())
00212 pmax_.col() = ref.pmax().col();
00213 if (pmax_.row() > ref.pmax().row())
00214 pmax_.row() = ref.pmax().row();
00215 }
00216
00217 template <typename P>
00218 inline
00219 void
00220 box<P>::merge(const box<P>& b)
00221 {
00222 mln_precondition(is_valid());
00223 if (! b.is_valid())
00224 {
00225
00226 return;
00227 }
00228
00229 for (unsigned i = 0; i < P::dim; ++i)
00230 {
00231 if (b.pmin()[i] < pmin_[i])
00232 pmin_[i] = b.pmin()[i];
00233 if (b.pmax()[i] > pmax_[i])
00234 pmax_[i] = b.pmax()[i];
00235 }
00236 }
00237
00238 template <typename P>
00239 inline
00240 P
00241 box<P>::pmin() const
00242 {
00243 mln_precondition(is_valid());
00244 return pmin_;
00245 }
00246
00247 template <typename P>
00248 inline
00249 P&
00250 box<P>::pmin()
00251 {
00252 return pmin_;
00253 }
00254
00255 template <typename P>
00256 inline
00257 P
00258 box<P>::pmax() const
00259 {
00260 mln_precondition(is_valid());
00261 return pmax_;
00262 }
00263
00264 template <typename P>
00265 inline
00266 P&
00267 box<P>::pmax()
00268 {
00269 return pmax_;
00270 }
00271
00272 template <typename P>
00273 inline
00274 box<P>::box()
00275 : pmin_(P::plus_infty()),
00276 pmax_(P::minus_infty())
00277 {
00278
00279 }
00280
00281 template <typename P>
00282 inline
00283 box<P>::box(const site& pmin, const site& pmax)
00284 : pmin_(pmin),
00285 pmax_(pmax)
00286 {
00287 mln_precondition(is_valid());
00288 }
00289
00290 template <typename P>
00291 inline
00292 box<P>::box(mln_coord(P) ninds)
00293 {
00294 metal::bool_<(dim == 1)>::check();
00295 pmin_ = literal::origin;
00296 pmax_ = P(ninds - 1);
00297 }
00298
00299 template <typename P>
00300 inline
00301 box<P>::box(mln_coord(P) nrows, mln_coord(P) ncols)
00302 {
00303 metal::bool_<(dim == 2)>::check();
00304 mln_precondition(nrows != 0 && ncols != 0);
00305
00306 pmin_ = literal::origin;
00307 pmax_ = P(--nrows, --ncols);
00308 mln_postcondition(is_valid());
00309 }
00310
00311 template <typename P>
00312 inline
00313 box<P>::box(mln_coord(P) nslices, mln_coord(P) nrows, mln_coord(P) ncols)
00314 {
00315 metal::bool_<(dim == 3)>::check();
00316 pmin_ = literal::origin;
00317 pmax_ = P(nslices - 1, nrows - 1, ncols - 1);
00318 mln_postcondition(is_valid());
00319 }
00320
00321 template <typename P>
00322 inline
00323 bool
00324 box<P>::has(const P& p) const
00325 {
00326 mln_precondition(is_valid());
00327 for (unsigned i = 0; i < P::dim; ++i)
00328 if (p[i] < pmin_[i] || p[i] > pmax_[i])
00329 return false;
00330 return true;
00331 }
00332
00333 template <typename P>
00334 inline
00335 void
00336 box<P>::enlarge(unsigned b)
00337 {
00338 mln_precondition(is_valid());
00339 for (unsigned i = 0; i < P::dim; ++i)
00340 {
00341 pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] - b);
00342 pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] + b);
00343 }
00344 mln_postcondition(is_valid());
00345 }
00346
00347 template <typename P>
00348 inline
00349 void
00350 box<P>::enlarge(unsigned dim, unsigned b)
00351 {
00352 mln_precondition(is_valid());
00353 pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] - b);
00354 pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] + b);
00355 mln_postcondition(is_valid());
00356 }
00357
00358 template <typename P>
00359 inline
00360 box<P>
00361 larger_than(const box<P> a, const box<P> b)
00362 {
00363 P pmin,pmax;
00364
00365 for (unsigned i = 0; i < P::dim; i++)
00366 {
00367 pmin[i] = (a.pmin()[i] < b.pmin()[i]) ? a.pmin()[i] : b.pmin()[i];
00368 pmax[i] = (a.pmax()[i] > b.pmax()[i]) ? a.pmax()[i] : b.pmax()[i];
00369 }
00370
00371 return box<P>(pmin, pmax);
00372 }
00373
00374 template <typename P>
00375 inline
00376 box<P>
00377 box<P>::to_larger(unsigned b) const
00378 {
00379 mln_precondition(is_valid());
00380 box<P> tmp(*this);
00381
00382 for (unsigned i = 0; i < P::dim; ++i)
00383 {
00384 tmp.pmin_[i] = static_cast<mln_coord(P)>(tmp.pmin_[i] - b);
00385 tmp.pmax_[i] = static_cast<mln_coord(P)>(tmp.pmax_[i] + b);
00386 }
00387 mln_postcondition(tmp.is_valid());
00388 return tmp;
00389 }
00390
00391 template <typename P>
00392 inline
00393 P
00394 box<P>::pcenter() const
00395 {
00396 mln_precondition(is_valid());
00397 P center;
00398 for (unsigned i = 0; i < P::dim; ++i)
00399 center[i] = static_cast<mln_coord(P)>(pmin_[i] + ((pmax_[i] - pmin_[i]) / 2));
00400 return center;
00401 }
00402
00403 template <typename P>
00404 inline
00405 std::size_t
00406 box<P>::memory_size() const
00407 {
00408 return sizeof(*this);
00409 }
00410
00411 template <typename P>
00412 inline
00413 std::ostream& operator<<(std::ostream& ostr, const box<P>& b)
00414 {
00415 mln_precondition(b.is_valid());
00416 return ostr << "[" << b.pmin() << ".." << b.pmax() << ']';
00417 }
00418
00419 namespace trait
00420 {
00421
00422 template <typename P>
00423 inline
00424 bool
00425 set_precise_unary_< op::ord, box<P> >::strict(const box<P>& lhs, const box<P>& rhs) const
00426 {
00427
00428 return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(),
00429 rhs.pmin(), rhs.pmax());
00430 }
00431
00432 }
00433
00434 # endif // ! MLN_INCLUDE_ONLY
00435
00436 }
00437
00438
00439 # include <mln/core/site_set/box_piter.hh>
00440
00441
00442 #endif // ! MLN_CORE_SITE_SET_BOX_HH