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
00028 #ifndef OLENA_CORE_BOX_HXX
00029 # define OLENA_CORE_BOX_HXX
00030
00031 # include <oln/arith/ops.hh>
00032
00033 namespace oln {
00034
00035
00036
00037
00038 template <class PointType>
00039 box<PointType>::box() :
00040 top_(ntg_min_val(int), ntg_min_val(int)),
00041 bottom_(ntg_max_val(int), ntg_max_val(int))
00042 {
00043 card_ = 0;
00044 not_consistent_ = true;
00045 make_consistent();
00046 box_card_ = 0;
00047 for (unsigned i = 0; i < dim(); ++i)
00048 {
00049 mass_[i] = 0;
00050 inner_boxes_mean_dim_[i] = 0;
00051 }
00052 }
00053
00054 template <class PointType>
00055 unsigned
00056 box<PointType>::dim() const
00057 {
00058 return d;
00059 }
00060
00061 template <class PointType>
00062 void
00063 box<PointType>::add(point_type p)
00064 {
00065 for (unsigned i = 0; i < dim(); ++i)
00066 {
00067 top_.nth(i) = ntg::max(top_.nth(i), p.nth(i));
00068 bottom_.nth(i) = std::min(bottom_.nth(i), p.nth(i));
00069 mass_[i] += p.nth(i);
00070 }
00071 card_++;
00072 not_consistent_ = true;
00073 }
00074
00075 template <class PointType>
00076 void
00077 box<PointType>::add(const box<PointType>& b)
00078 {
00079 if (b.card() != 0)
00080 {
00081 add(b.top());
00082 add(b.bottom());
00083 card_ += b.card();
00084 box_card_++;
00085 not_consistent_ = true;
00086 for (unsigned i = 0; i < b.dim(); ++i)
00087 {
00088 inner_boxes_mean_dim_[i] += b.width();
00089 mass_[i] += b.mass_[i];
00090 }
00091 }
00092 }
00093
00094 template <class PointType>
00095 float
00096 box<PointType>::inner_boxes_mean_dim(unsigned d) const
00097 {
00098 return inner_boxes_mean_dim_[d] / box_card_;
00099 }
00100
00101 template <class PointType>
00102 bool
00103 box<PointType>::overlay(unsigned dim, const box<PointType>& b) const
00104 {
00105 return
00106 ((top().nth(dim) > b.bottom().nth(dim))
00107 && (bottom().nth(dim) < b.top().nth(dim)));
00108 }
00109
00110 template <class PointType>
00111 void
00112 box<PointType>::make_consistent()
00113 {
00114 if (not_consistent_)
00115 for (unsigned i = 0; i < dim(); ++i)
00116 {
00117 if (card_ != 0)
00118 mass_center_.nth(i) = int(mass_[i] / card_);
00119 dimension_.nth(i) = top_.nth(i) - bottom_.nth(i) + 1;
00120 box_center_.nth(i) = (top_.nth(i) + bottom_.nth(i)) / 2;
00121 not_consistent_ = false;
00122 }
00123 }
00124
00125 template <class PointType>
00126 unsigned
00127 box<PointType>::card() const
00128 {
00129 return card_;
00130 }
00131
00132 template <class PointType>
00133 unsigned
00134 box<PointType>::inner_boxes_card() const
00135 {
00136 return box_card_;
00137 }
00138
00139 template <class PointType>
00140 typename box<PointType>::point_type
00141 box<PointType>::top() const
00142 {
00143 return top_;
00144 }
00145
00146 template <class PointType>
00147 typename box<PointType>::point_type
00148 box<PointType>::bottom() const
00149 {
00150 return bottom_;
00151 }
00152
00153 template <class PointType>
00154 typename box<PointType>::point_type
00155 box<PointType>::mass_center()
00156 {
00157 if (not_consistent_)
00158 make_consistent();
00159 return mass_center_;
00160 }
00161
00162 template <class PointType>
00163 typename box<PointType>::point_type
00164 box<PointType>::mass_center() const
00165 {
00166 return mass_center_;
00167 }
00168
00169 template <class PointType>
00170 typename box<PointType>::point_type
00171 box<PointType>::box_center()
00172 {
00173 if (not_consistent_)
00174 make_consistent();
00175 return box_center_;
00176 }
00177
00178 template <class PointType>
00179 typename box<PointType>::point_type
00180 box<PointType>::box_center() const
00181 {
00182 return box_center_;
00183 }
00184
00185 template <class PointType>
00186 unsigned
00187 box<PointType>::width() const
00188 {
00189 return dimension_.nth(1);
00190 }
00191
00192 template <class PointType>
00193 unsigned
00194 box<PointType>::height() const
00195 {
00196 return dimension_.nth(0);
00197 }
00198
00199 template <class PointType>
00200 unsigned
00201 box<PointType>::integrale() const
00202 {
00203 unsigned acu = 1;
00204 for (unsigned i = 0; i < dim(); ++i)
00205 acu *= i;
00206 return acu;
00207 }
00208
00209 template <class PointType>
00210 unsigned
00211 box<PointType>::volume() const
00212 {
00213 precondition(dim() == 3);
00214 return integrale();
00215 }
00216
00217 template <class PointType>
00218 unsigned
00219 box<PointType>::area() const
00220 {
00221 precondition(dim() == 2);
00222 return integrale();
00223 }
00224
00225 template <class PointType>
00226 float
00227 box<PointType>::density() const
00228 {
00229 return ((float)card_ / (float)integrale());
00230 }
00231
00232 template <class PointType>
00233 float
00234 box<PointType>::square_ratio() const
00235 {
00236 precondition(dim() == 2);
00237 return width() > height() ?
00238 float(height()) / float(width()) :
00239 float(width()) / float(height());
00240 }
00241
00242 }
00243
00244 #endif // OLENA_CORE_BOX_HXX