CompositeBox.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _COMPOSITEBOX_H
00034 #define _COMPOSITEBOX_H
00035 
00036 #include "BoundingBox.h"
00037 
00038 namespace Go
00039 {
00042 
00043 
00044 
00053 class CompositeBox
00054 {
00055 public:
00057     template <typename RandomAccessIterator>
00058     CompositeBox(RandomAccessIterator start,
00059                  int dim,
00060                  int num_u,
00061                  int num_v)
00062     {
00063         obsolete_inner_ = 0;
00064         setFromArray(start, dim, num_u, num_v);
00065     }
00069     CompositeBox(const Point& low, const Point& high)
00070         : inner_(low, high), edge_(low, high), obsolete_inner_(0)
00071     {
00072     }
00074     ~CompositeBox();
00075 
00078     void setFromPoints(const Point& low, const Point& high)
00079     {
00080         inner_.setFromPoints(low, high);
00081         edge_ = inner_;
00082         obsolete_inner_ = 0;
00083     }
00084 
00091     template <typename RandomAccessIterator>
00092     void setFromArray(RandomAccessIterator start,
00093                       int dim,
00094                       int num_u,
00095                       int num_v)
00096     {
00097         if (num_u < 3 || num_v == 2) {
00098             // We cannot make a separate inner box. Just make
00099             // two identical boxes. The num_v == 1 case is the curve
00100             // special case, which is handled.
00101             edge_.setFromArray(start, start+dim*num_u*num_v, dim);
00102             Point mid = 0.5*(edge_.low() + edge_.high());
00103             inner_.setFromPoints(mid, mid);
00104             obsolete_inner_ = 0;
00105             return;
00106         }
00107         // First do the inner box.
00108         int vstart = (num_v == 1) ? 0 : 1;
00109         int vend = (num_v == 1) ? num_v : num_v - 1;
00110         Point il(start + dim*(1 + num_u*vstart),
00111                  start + dim*(2 + num_u*vstart));
00112         Point ih(il);
00113         for (int i = vstart; i < vend; ++i) {
00114             for (int j = 1; j < num_u-1; ++j) {
00115                 RandomAccessIterator pnt = start + dim*(j + num_u*i);
00116                 for (int d = 0; d < dim; ++d) {
00117                     if (pnt[d] < il[d]) {
00118                         il[d] = pnt[d];
00119                     } else if (pnt[d] > ih[d]) {
00120                         ih[d] = pnt[d];
00121                     }
00122                 }
00123             }
00124         }
00125         inner_.setFromPoints(il, ih);
00126 
00127         // Then the edge box.
00128         Point el(start, start+dim);
00129         Point eh(el);
00130         if (num_v == 1) {
00131             // We have a curve. Only check the endpoint
00132             RandomAccessIterator pnt = start + dim*(num_u - 1);
00133             for (int d = 0; d < dim; ++d) {
00134                 if (pnt[d] < el[d]) {
00135                     el[d] = pnt[d];
00136                 } else if (pnt[d] > eh[d]) {
00137                     eh[d] = pnt[d];
00138                 }
00139             }
00140         } else {
00141             // We have a 2D-array, check all boundary points
00142             for (int i = 0; i < num_v; ++i) {
00143                 for (int j = 0; j < num_u; j += num_u-1) {
00144                     RandomAccessIterator pnt = start + dim*(j + num_u*i);
00145                     for (int d = 0; d < dim; ++d) {
00146                         if (pnt[d] < el[d]) {
00147                             el[d] = pnt[d];
00148                         } else if (pnt[d] > eh[d]) {
00149                             eh[d] = pnt[d];
00150                         }
00151                     }
00152                 }
00153             }
00154             for (int j = 0; j < num_u; ++j) {
00155                 for (int i = 0; i < num_v; i += num_v-1) {
00156                     RandomAccessIterator pnt = start + dim*(j + num_u*i);
00157                     for (int d = 0; d < dim; ++d) {
00158                         if (pnt[d] < el[d]) {
00159                             el[d] = pnt[d];
00160                         } else if (pnt[d] > eh[d]) {
00161                             eh[d] = pnt[d];
00162                         }
00163                     }
00164                 }
00165             }
00166         }
00167         edge_.setFromPoints(el, eh);
00168     }
00169 
00171     void read(std::istream& is);
00173     void write(std::ostream& os) const;
00174 
00176     int  dimension()  const
00177     {
00178         return inner_.dimension();
00179     }
00180 
00182     Point low(double toli = 0.0,
00183               double tole = 0.0) const;
00184 
00185 
00187     Point high(double toli = 0.0,
00188                double tole = 0.0) const;
00189 
00190 
00192     const BoundingBox& inner() const
00193     {
00194         return inner_;
00195     }
00197     const BoundingBox& edge() const
00198     {
00199         return edge_;
00200     }
00201 
00205     bool containsPoint(const Point& pt,
00206                        double toli = 0.0,
00207                        double tole = 0.0) const;
00208 
00212     bool overlaps(const CompositeBox& box,
00213                   double toli = 0.0,
00214                   double tole = 0.0) const;
00215 
00218     bool getOverlap(const CompositeBox& box,
00219                   double& overlap,
00220                   double toli = 0.0,
00221                   double tole = 0.0) const;
00222 
00226     bool containsBox(const CompositeBox& box,
00227                      double toli = 0.0,
00228                      double tole = 0.0) const;
00229 
00230 
00231 private:
00232     // Data members
00233     BoundingBox inner_;
00234     BoundingBox edge_;
00235     int obsolete_inner_;
00236 };
00237 
00239 } // namespace Go
00240 
00241 
00242 #endif // _COMPOSITEBOX_H
00243 
00244 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1