
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2008-04-04 Matthieu Garrigues <garrigues@lrde.epita.fr> Add bounding box computation to p_image2d. * mln/core/p_image2d.hh: (p_image2d<P>::box_<mln_point(P)>& bbox()): New, give the exact boungind box. (p_image2d<P>::insert(const p_image2d& set)): Rename as.. (p_image2d<P>::insert(const Point_Set<S>& set)): ...this, and update it to be more generic. (p_image2d<P>::remove(const p_image2d& set)): Rename as.. (p_image2d<P>::remove(const Point_Set<S>& set)): ...this, likewise. --- p_image2d.hh | 59 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 13 deletions(-) Index: trunk/milena/mln/core/p_image2d.hh =================================================================== --- trunk/milena/mln/core/p_image2d.hh (revision 1838) +++ trunk/milena/mln/core/p_image2d.hh (revision 1839) @@ -37,9 +37,7 @@ # include <mln/core/internal/point_set_base.hh> # include <mln/core/box2d.hh> # include <mln/core/image2d.hh> -# include <mln/accu/bbox.hh> # include <mln/level/fill.hh> -# include <mln/core/p_array.hh> namespace mln @@ -67,11 +65,13 @@ /// Insert a point \p p. p_image2d<P>& insert(const P p); - p_image2d<P>& insert(const p_image2d& set); + template <typename S> + p_image2d<P>& insert(const Point_Set<S>& set); /// Remove a point \p p. p_image2d<P>& remove(const P p); - p_image2d<P>& remove(const p_image2d& set); + template <typename S> + p_image2d<P>& remove(const Point_Set<S>& set); /// Give the number of points. unsigned npoints() const; @@ -82,6 +82,9 @@ /// Test if the set is empty. bool is_empty() const; + /// Give the exact bounding box. + const box_<mln_point(P)>& bbox();; + /// Clear this set. void clear(); @@ -90,6 +93,8 @@ private: image2d<bool> points_; unsigned npoints_; + accu::bbox<P> bb_; + bool bb_need_update_; }; @@ -98,7 +103,8 @@ template <typename P> p_image2d<P>::p_image2d(int nrows, int ncols) : points_(nrows, ncols), - npoints_(0) + npoints_(0), + bb_need_update_(false) { level::fill(points_, false); @@ -107,7 +113,8 @@ template <typename P> p_image2d<P>::p_image2d(const box2d& b) : points_(b), - npoints_(0) + npoints_(0), + bb_need_update_(false) { level::fill(points_, false); } @@ -119,6 +126,7 @@ { if (points_(p) == false) { + bb_.take(p); points_(p) = true; npoints_++; } @@ -126,12 +134,12 @@ } template <typename P> + template <typename S> p_image2d<P>& - p_image2d<P>::insert(const p_image2d& set) + p_image2d<P>::insert(const Point_Set<S>& set_) { - if (set->is_empty()) - return *this; - mln_fwd_piter(image2d<bool>) p(set.points_ | true); + const S& set = exact(set_); + mln_fwd_piter(S) p(set); for_all(p) if (this->points_.has(p)) this->insert(p); @@ -145,18 +153,21 @@ if (points_(p) == true) { points_(p) = false; + bb_need_update_ = true; npoints_--; } return *this; } template <typename P> + template <typename S> p_image2d<P>& - p_image2d<P>::remove(const p_image2d& set) + p_image2d<P>::remove(const Point_Set<S>& set_) { - if (this->is_empty() || set->is_empty()) + const S& set = exact(set_); + if (this->is_empty()) return *this; - mln_fwd_piter(image2d<bool>) p(set.points_ | true); + mln_fwd_piter(S) p(set); for_all(p) if (this->points_.has(p)) this->remove(p); @@ -184,11 +195,33 @@ return npoints_ == 0; } + + template <typename P> + inline + const box_<mln_point(P)>& + p_image2d<P>::bbox() + { + mln_precondition(npoints() != 0); + if (bb_need_update_) + { + bb_.init(); + + mln_fwd_piter(p_image2d<P>) p(*this); + for_all(p) + bb_.take(p); + bb_need_update_ = false; + } + + return bb_.to_result(); + } + template <typename P> void p_image2d<P>::clear() { level::fill(points_, false); + bb_.init(); + bb_need_update_ = false; } template <typename P>