$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
core/site_set/box.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2013 EPITA Research and
2 // Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_CORE_SITE_SET_BOX_HH
28 # define MLN_CORE_SITE_SET_BOX_HH
29 
35 
36 # include <mln/core/concept/box.hh>
37 # include <mln/core/internal/box_impl.hh>
38 # include <mln/core/point.hh>
39 # include <mln/literal/origin.hh>
40 
41 
42 namespace mln
43 {
44 
45  // Fwd decls.
46  template <typename P> class box;
47  template <typename P> class box_fwd_piter_;
48  template <typename P> class box_bkd_piter_;
49 
50 
51  namespace trait
52  {
53 
54  template <typename P>
55  struct site_set_< box<P> >
56  {
57  typedef trait::site_set::nsites::known nsites;
58  typedef trait::site_set::bbox::straight bbox;
59  typedef trait::site_set::contents::fixed contents;
60  typedef trait::site_set::arity::unique arity;
61  };
62 
63  template <typename P>
64  struct set_precise_unary_< op::ord, box<P> >
65  {
66  typedef set_precise_unary_< op::ord, box<P> > ret; // Itself.
67  bool strict(const box<P>& lhs, const box<P>& rhs) const;
68  };
69 
70  } // end of namespace mln::trait
71 
72 
79  //
80  template <typename P>
81  class box : public Box< box<P> >,
82  public internal::box_impl_< P::dim, mln_coord(P), box<P> >,
83  private mlc_is_unqualif(P)::check_t
84  {
85  public:
87  enum { dim = P::dim };
88 
90  typedef P element;
91 
93  typedef P psite;
94 
96  typedef P site;
97 
100 
102  typedef fwd_piter piter;
103 
106 
108  P pmin() const;
109 
111  P& pmin();
112 
114  P pmax() const;
115 
117  P& pmax();
118 
120  box();
121 
123  box(const site& pmin, const site& pmax);
124 
127  explicit box(mln_coord(P) ninds);
128  box(mln_coord(P) nrows, mln_coord(P) ncols);
129  box(mln_coord(P) nslis, mln_coord(P) nrows, mln_coord(P) ncols);
131 
136  bool has(const P& p) const;
137 
139  void enlarge(unsigned b);
140 
142  void enlarge(unsigned dim, unsigned b);
143 
145  box<P> to_larger(unsigned b) const;
146 
148  P pcenter() const;
149 
152  bool is_valid() const;
153 
155  void crop_wrt(const box<P>& b);
156 
158  void merge(const box<P>& b);
159 
161  std::size_t memory_size() const;
162 
163  protected:
164 
166  };
167 
168 
178  template <typename P>
179  std::ostream& operator<<(std::ostream& ostr, const box<P>& b);
180 
181 
184  template <typename P>
185  inline
186  box<P>
187  larger_than(const box<P> a, const box<P> b);
188 
189 
190 
191 # ifndef MLN_INCLUDE_ONLY
192 
193  template <typename P>
194  inline
195  bool
196  box<P>::is_valid() const
197  {
198  // Validity is: for all i, pmin_[i] <= pmax_[i].
199  // Nota bene: a one-point box is valid.
200  return util::ord_weak(pmin_, pmax_);
201  }
202 
203  template <typename P>
204  inline
205  void
206  box<P>::crop_wrt(const box<P>& ref)
207  {
208  if (pmin_.col() < ref.pmin().col())
209  pmin_.col() = ref.pmin().col();
210  if (pmin_.row() < ref.pmin().row())
211  pmin_.row() = ref.pmin().row();
212 
213  if (pmax_.col() > ref.pmax().col())
214  pmax_.col() = ref.pmax().col();
215  if (pmax_.row() > ref.pmax().row())
216  pmax_.row() = ref.pmax().row();
217  }
218 
219  template <typename P>
220  inline
221  void
222  box<P>::merge(const box<P>& b)
223  {
224  mln_precondition(is_valid());
225  if (! b.is_valid())
226  {
227  // no-op
228  return;
229  }
230 
231  for (unsigned i = 0; i < P::dim; ++i)
232  {
233  if (b.pmin()[i] < pmin_[i])
234  pmin_[i] = b.pmin()[i];
235  if (b.pmax()[i] > pmax_[i])
236  pmax_[i] = b.pmax()[i];
237  }
238  }
239 
240  template <typename P>
241  inline
242  P
243  box<P>::pmin() const
244  {
245  mln_precondition(is_valid());
246  return pmin_;
247  }
248 
249  template <typename P>
250  inline
251  P&
252  box<P>::pmin()
253  {
254  return pmin_;
255  }
256 
257  template <typename P>
258  inline
259  P
260  box<P>::pmax() const
261  {
262  mln_precondition(is_valid());
263  return pmax_;
264  }
265 
266  template <typename P>
267  inline
268  P&
269  box<P>::pmax()
270  {
271  return pmax_;
272  }
273 
274  template <typename P>
275  inline
276  box<P>::box()
277  : pmin_(P::plus_infty()),
278  pmax_(P::minus_infty())
279  {
280  // FIXME: The code above can be slow; think about removing it...
281  }
282 
283  template <typename P>
284  inline
285  box<P>::box(const site& pmin, const site& pmax)
286  : pmin_(pmin),
287  pmax_(pmax)
288  {
289  mln_precondition(is_valid());
290  }
291 
292  template <typename P>
293  inline
294  box<P>::box(mln_coord(P) ninds)
295  {
296  metal::bool_<(dim == 1)>::check();
297  pmin_ = literal::origin;
298  pmax_ = P(ninds - 1);
299  }
300 
301  template <typename P>
302  inline
303  box<P>::box(mln_coord(P) nrows, mln_coord(P) ncols)
304  {
305  metal::bool_<(dim == 2)>::check();
306  mln_precondition(nrows != 0 && ncols != 0);
307 
308  pmin_ = literal::origin;
309  pmax_ = P(--nrows, --ncols);
310  mln_postcondition(is_valid());
311  }
312 
313  template <typename P>
314  inline
315  box<P>::box(mln_coord(P) nslis, mln_coord(P) nrows, mln_coord(P) ncols)
316  {
317  metal::bool_<(dim == 3)>::check();
318  pmin_ = literal::origin;
319  pmax_ = P(nslis - 1, nrows - 1, ncols - 1);
320  mln_postcondition(is_valid());
321  }
322 
323  template <typename P>
324  inline
325  bool
326  box<P>::has(const P& p) const
327  {
328  mln_precondition(is_valid());
329  for (unsigned i = 0; i < P::dim; ++i)
330  if (p[i] < pmin_[i] || p[i] > pmax_[i])
331  return false;
332  return true;
333  }
334 
335  template <typename P>
336  inline
337  void
338  box<P>::enlarge(unsigned b)
339  {
340  mln_precondition(is_valid());
341  for (unsigned i = 0; i < P::dim; ++i)
342  {
343  pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] - b);
344  pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] + b);
345  }
346  mln_postcondition(is_valid());
347  }
348 
349  template <typename P>
350  inline
351  void
352  box<P>::enlarge(unsigned dim, unsigned b)
353  {
354  mln_precondition(is_valid());
355  pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] - b);
356  pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] + b);
357  mln_postcondition(is_valid());
358  }
359 
360  template <typename P>
361  inline
362  box<P>
363  larger_than(const box<P> a, const box<P> b)
364  {
365  P pmin,pmax;
366 
367  for (unsigned i = 0; i < P::dim; i++)
368  {
369  pmin[i] = (a.pmin()[i] < b.pmin()[i]) ? a.pmin()[i] : b.pmin()[i];
370  pmax[i] = (a.pmax()[i] > b.pmax()[i]) ? a.pmax()[i] : b.pmax()[i];
371  }
372 
373  return box<P>(pmin, pmax);
374  }
375 
376  template <typename P>
377  inline
378  box<P>
379  box<P>::to_larger(unsigned b) const
380  {
381  mln_precondition(is_valid());
382  box<P> tmp(*this);
383 
384  for (unsigned i = 0; i < P::dim; ++i)
385  {
386  tmp.pmin_[i] = static_cast<mln_coord(P)>(tmp.pmin_[i] - b);
387  tmp.pmax_[i] = static_cast<mln_coord(P)>(tmp.pmax_[i] + b);
388  }
389  mln_postcondition(tmp.is_valid());
390  return tmp;
391  }
392 
393  template <typename P>
394  inline
395  P
396  box<P>::pcenter() const
397  {
398  mln_precondition(is_valid());
399  P center;
400  for (unsigned i = 0; i < P::dim; ++i)
401  center[i] = static_cast<mln_coord(P)>(pmin_[i] + ((pmax_[i] - pmin_[i]) / 2));
402  return center;
403  }
404 
405  template <typename P>
406  inline
407  std::size_t
408  box<P>::memory_size() const
409  {
410  return sizeof(*this);
411  }
412 
413  template <typename P>
414  inline
415  std::ostream& operator<<(std::ostream& ostr, const box<P>& b)
416  {
417  mln_precondition(b.is_valid());
418  return ostr << "[" << b.pmin() << ".." << b.pmax() << ']';
419  }
420 
421  namespace trait
422  {
423 
424  template <typename P>
425  inline
426  bool
427  set_precise_unary_< op::ord, box<P> >::strict(const box<P>& lhs, const box<P>& rhs) const
428  {
429  // Lexicographical over "pmin then pmax".
430  return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(),
431  rhs.pmin(), rhs.pmax());
432  }
433 
434  } // end of namespace mln::trait
435 
436 # endif // ! MLN_INCLUDE_ONLY
437 
438 } // end of namespace mln
439 
440 
441 # include <mln/core/site_set/box_piter.hh>
442 
443 
444 #endif // ! MLN_CORE_SITE_SET_BOX_HH