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