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
00029
00030
00031
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
00099
00100
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
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
00128 Point el(start, start+dim);
00129 Point eh(el);
00130 if (num_v == 1) {
00131
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
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
00233 BoundingBox inner_;
00234 BoundingBox edge_;
00235 int obsolete_inner_;
00236 };
00237
00239 }
00240
00241
00242 #endif // _COMPOSITEBOX_H
00243
00244