//=========================================================================== // GoTools Core - SINTEF Geometry Tools Core library, version 2.0.1 // // Copyright (C) 2000-2007, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00013 #ifndef _COMPOSITEBOX_H 00014 #define _COMPOSITEBOX_H 00015 00016 #include "GoTools/utils/BoundingBox.h" 00017 00018 namespace Go 00019 { 00020 00021 00030 class GO_API CompositeBox 00031 { 00032 public: 00034 template <typename RandomAccessIterator> 00035 CompositeBox(RandomAccessIterator start, 00036 int dim, 00037 int num_u, 00038 int num_v) 00039 { 00040 obsolete_inner_ = 0; 00041 setFromArray(start, dim, num_u, num_v); 00042 } 00046 CompositeBox(const Point& low, const Point& high) 00047 : inner_(low, high), edge_(low, high), obsolete_inner_(0) 00048 { 00049 } 00051 ~CompositeBox(); 00052 00055 void setFromPoints(const Point& low, const Point& high) 00056 { 00057 inner_.setFromPoints(low, high); 00058 edge_ = inner_; 00059 obsolete_inner_ = 0; 00060 } 00061 00068 template <typename RandomAccessIterator> 00069 void setFromArray(RandomAccessIterator start, 00070 int dim, 00071 int num_u, 00072 int num_v) 00073 { 00074 if (num_u < 3 || num_v == 2) { 00075 // We cannot make a separate inner box. Just make 00076 // two identical boxes. The num_v == 1 case is the curve 00077 // special case, which is handled. 00078 edge_.setFromArray(start, start+dim*num_u*num_v, dim); 00079 Point mid = 0.5*(edge_.low() + edge_.high()); 00080 inner_.setFromPoints(mid, mid); 00081 obsolete_inner_ = 0; 00082 return; 00083 } 00084 // First do the inner box. 00085 int vstart = (num_v == 1) ? 0 : 1; 00086 int vend = (num_v == 1) ? num_v : num_v - 1; 00087 Point il(start + dim*(1 + num_u*vstart), 00088 start + dim*(2 + num_u*vstart)); 00089 Point ih(il); 00090 for (int i = vstart; i < vend; ++i) { 00091 for (int j = 1; j < num_u-1; ++j) { 00092 RandomAccessIterator pnt = start + dim*(j + num_u*i); 00093 for (int d = 0; d < dim; ++d) { 00094 if (pnt[d] < il[d]) { 00095 il[d] = pnt[d]; 00096 } else if (pnt[d] > ih[d]) { 00097 ih[d] = pnt[d]; 00098 } 00099 } 00100 } 00101 } 00102 inner_.setFromPoints(il, ih); 00103 00104 // Then the edge box. 00105 Point el(start, start+dim); 00106 Point eh(el); 00107 if (num_v == 1) { 00108 // We have a curve. Only check the endpoint 00109 RandomAccessIterator pnt = start + dim*(num_u - 1); 00110 for (int d = 0; d < dim; ++d) { 00111 if (pnt[d] < el[d]) { 00112 el[d] = pnt[d]; 00113 } else if (pnt[d] > eh[d]) { 00114 eh[d] = pnt[d]; 00115 } 00116 } 00117 } else { 00118 // We have a 2D-array, check all boundary points 00119 for (int i = 0; i < num_v; ++i) { 00120 for (int j = 0; j < num_u; j += num_u-1) { 00121 RandomAccessIterator pnt = start + dim*(j + num_u*i); 00122 for (int d = 0; d < dim; ++d) { 00123 if (pnt[d] < el[d]) { 00124 el[d] = pnt[d]; 00125 } else if (pnt[d] > eh[d]) { 00126 eh[d] = pnt[d]; 00127 } 00128 } 00129 } 00130 } 00131 for (int j = 0; j < num_u; ++j) { 00132 for (int i = 0; i < num_v; i += num_v-1) { 00133 RandomAccessIterator pnt = start + dim*(j + num_u*i); 00134 for (int d = 0; d < dim; ++d) { 00135 if (pnt[d] < el[d]) { 00136 el[d] = pnt[d]; 00137 } else if (pnt[d] > eh[d]) { 00138 eh[d] = pnt[d]; 00139 } 00140 } 00141 } 00142 } 00143 } 00144 edge_.setFromPoints(el, eh); 00145 } 00146 00148 void read(std::istream& is); 00150 void write(std::ostream& os) const; 00151 00153 int dimension() const 00154 { 00155 return inner_.dimension(); 00156 } 00157 00159 Point low(double toli = 0.0, 00160 double tole = 0.0) const; 00161 00162 00164 Point high(double toli = 0.0, 00165 double tole = 0.0) const; 00166 00167 00169 const BoundingBox& inner() const 00170 { 00171 return inner_; 00172 } 00174 const BoundingBox& edge() const 00175 { 00176 return edge_; 00177 } 00178 00182 bool containsPoint(const Point& pt, 00183 double toli = 0.0, 00184 double tole = 0.0) const; 00185 00189 bool overlaps(const CompositeBox& box, 00190 double toli = 0.0, 00191 double tole = 0.0) const; 00192 00195 bool getOverlap(const CompositeBox& box, 00196 double& overlap, 00197 double toli = 0.0, 00198 double tole = 0.0) const; 00199 00203 bool containsBox(const CompositeBox& box, 00204 double toli = 0.0, 00205 double tole = 0.0) const; 00206 00207 00208 private: 00209 // Data members 00210 BoundingBox inner_; 00211 BoundingBox edge_; 00212 int obsolete_inner_; 00213 }; 00214 00215 } // namespace Go 00216 00217 00218 #endif // _COMPOSITEBOX_H 00219