box.hxx

00001 // Copyright (C) 2001, 2002, 2003  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
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   // FIXME: despite its usefulness, this box class is not good
00036   // FIXME: since it is not generic.
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 } // end of oln.
00243 
00244 #endif // OLENA_CORE_BOX_HXX

Generated on Thu Apr 15 20:13:06 2004 for Olena by doxygen 1.3.6-20040222