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 #ifndef MLN_ACCU_SHAPE_BBOX_HH
00027 # define MLN_ACCU_SHAPE_BBOX_HH
00028 
00032 
00033 # include <mln/core/site_set/box.hh>
00034 # include <mln/core/concept/meta_accumulator.hh>
00035 # include <mln/accu/internal/base.hh>
00036 
00037 
00038 namespace mln
00039 {
00040 
00041   namespace accu
00042   {
00043 
00044     namespace shape
00045     {
00046 
00047 
00053       
00054       template <typename P>
00055       struct bbox : public mln::accu::internal::base< const box<P>& , bbox<P> >
00056       {
00057         typedef P argument;
00058 
00059         bbox();
00060 
00063         void init();
00064         void take_as_init_(const P& p);
00065         void take(const P& p);
00066         void take(const bbox<P>& other);
00067         void take(const box<P>& b);
00069 
00071         const box<P>& to_result() const;
00072 
00075         bool is_valid() const;
00076 
00077       protected:
00078 
00079         bool is_valid_;
00080         box<P> b_;
00081       };
00082 
00083 
00084     } 
00085 
00086 
00087     namespace meta
00088     {
00089 
00090       namespace shape
00091       {
00092 
00094         struct bbox : public Meta_Accumulator< bbox >
00095         {
00096           template <typename T>
00097           struct with
00098           {
00099             typedef accu::shape::bbox<T> ret;
00100           };
00101         };
00102 
00103       } 
00104 
00105     } 
00106 
00107 
00108 
00109 # ifndef MLN_INCLUDE_ONLY
00110 
00111     namespace shape
00112     {
00113 
00114       template <typename P>
00115       inline
00116       bbox<P>::bbox()
00117       {
00118         init();
00119       }
00120 
00121       template <typename P>
00122       inline
00123       void
00124       bbox<P>::init()
00125       {
00126         is_valid_ = false;
00127       }
00128 
00129       template <typename P>
00130       inline
00131       void
00132       bbox<P>::take_as_init_(const P& p)
00133       {
00134         b_.pmin() = p;
00135         b_.pmax() = p;
00136         is_valid_ = true;
00137       }
00138 
00139       template <typename P>
00140       inline
00141       void
00142       bbox<P>::take(const P& p)
00143       {
00144         if (! is_valid_)
00145           {
00146             b_.pmin() = p;
00147             b_.pmax() = p;
00148             is_valid_ = true;
00149             return;
00150           }
00151         for (unsigned i = 0; i < P::dim; ++i)
00152           if (p[i] < b_.pmin()[i])
00153             b_.pmin()[i] = p[i];
00154           else if (p[i] > b_.pmax()[i])
00155             b_.pmax()[i] = p[i];
00156       }
00157 
00158       template <typename P>
00159       inline
00160       void
00161       bbox<P>::take(const bbox<P>& other)
00162       {
00163         if (! other.is_valid_)
00164           {
00165             
00166             return;
00167           }
00168         if (! this->is_valid_)
00169           {
00170             
00171             *this = other;
00172             is_valid_ = true;
00173             return;
00174           }
00175         
00176         const box<P>& o_b = other.b_;
00177         for (unsigned i = 0; i < P::dim; ++i)
00178           {
00179             if (o_b.pmin()[i] < b_.pmin()[i])
00180               b_.pmin()[i] = o_b.pmin()[i];
00181             if (o_b.pmax()[i] > b_.pmax()[i])
00182               b_.pmax()[i] = o_b.pmax()[i];
00183           }
00184       }
00185 
00186       template <typename P>
00187       inline
00188       void
00189       bbox<P>::take(const box<P>& b)
00190       {
00191         if (! b.is_valid())
00192           {
00193             
00194             return;
00195           }
00196         if (! this->is_valid_)
00197           {
00198             b_ = b;
00199             is_valid_ = true;
00200             return;
00201           }
00202         
00203         for (unsigned i = 0; i < P::dim; ++i)
00204           {
00205             if (b.pmin()[i] < b_.pmin()[i])
00206               b_.pmin()[i] = b.pmin()[i];
00207             if (b.pmax()[i] > b_.pmax()[i])
00208               b_.pmax()[i] = b.pmax()[i];
00209           }
00210       }
00211 
00212       template <typename P>
00213       inline
00214       const box<P>&
00215       bbox<P>::to_result() const
00216       {
00217         
00218         return b_;
00219       }
00220 
00221       template <typename P>
00222       inline
00223       bool
00224       bbox<P>::is_valid() const
00225       {
00226         return is_valid_;
00227       }
00228 
00229     } 
00230 
00231 # endif // ! MLN_INCLUDE_ONLY
00232 
00233   } 
00234 
00235 } 
00236 
00237 
00238 #endif // ! MLN_ACCU_SHAPE_BBOX_HH