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 _GOBOUNDINGBOX_H
00034 #define _GOBOUNDINGBOX_H
00035
00036 #include "Point.h"
00037 #include <vector>
00038
00039 namespace Go
00040 {
00043
00044
00045
00051 class BoundingBox
00052 {
00053 public:
00056 BoundingBox() : valid_(false) {}
00059 explicit BoundingBox(int dim)
00060 : low_(dim), high_(dim), valid_(false) {}
00064 BoundingBox(const Point& low, const Point& high)
00065 : low_(low), high_(high), valid_(false) { check(); }
00067 ~BoundingBox();
00068
00071 void setFromPoints(const Point& low, const Point& high);
00072
00076 template <typename FloatType>
00077 void setFromArray(const FloatType* start, const FloatType* end, int dim)
00078 {
00079 low_ = Point(start, start+dim);
00080 high_ = Point(start, start+dim);
00081 start += dim;
00082 while (start != end) {
00083 for (int d = 0; d < dim; ++d) {
00084 if (start[d] < low_[d]) {
00085 low_[d] = start[d];
00086 } else if (start[d] > high_[d]) {
00087 high_[d] = start[d];
00088 }
00089 }
00090 start += dim;
00091 }
00092
00093 check();
00094 }
00098 template <typename ForwardIterator>
00099 void setFromArray(ForwardIterator start,
00100 ForwardIterator end, int dim)
00101 {
00102 low_ = Point(start, start+dim);
00103 high_ = Point(start, start+dim);
00104 start += dim;
00105 while (start != end) {
00106 for (int d = 0; d < dim; ++d) {
00107 if (start[d] < low_[d]) {
00108 low_[d] = start[d];
00109 } else if (start[d] > high_[d]) {
00110 high_[d] = start[d];
00111 }
00112 }
00113 start += dim;
00114 }
00115
00116 check();
00117 }
00120 void setFromPoints(const std::vector<Point>& points)
00121 {
00122 int dim = points[0].dimension();
00123 low_ = points[0];
00124 high_ = points[0];
00125 for (size_t i = 1; i < points.size(); ++i) {
00126 for (int d = 0; d < dim; ++d) {
00127 if (points[i][d] < low_[d]) {
00128 low_[d] = points[i][d];
00129 } else if (points[i][d] > high_[d]) {
00130 high_[d] = points[i][d];
00131 }
00132 }
00133 }
00134
00135 check();
00136 }
00137
00139 void read(std::istream& is);
00141 void write(std::ostream& os) const;
00142
00144 int dimension() const { return low_.size(); }
00145
00147 const Point& low() const { return low_; }
00149 const Point& high() const { return high_; }
00150
00153 bool containsPoint(const Point& pt, double tol = 0.0) const;
00154
00157 bool overlaps(const BoundingBox& box, double tol = 0.0) const;
00158 bool getOverlap(const BoundingBox& box, double& overlap, double tol = 0.0) const;
00161 bool containsBox(const BoundingBox& box, double tol = 0.0) const;
00162
00165 void addUnionWith(const Point& pt);
00168 void addUnionWith(const BoundingBox& box);
00169
00171 bool valid() const { return valid_; }
00172
00175 void check() const;
00176
00177 private:
00178
00179 Point low_;
00180 Point high_;
00181 mutable bool valid_;
00182 };
00183
00184
00186 }
00187
00188
00190 namespace std {
00193
00194
00195
00197 inline std::istream& operator >> (std::istream& is,
00198 Go::BoundingBox& bbox)
00199 {
00200 bbox.read(is);
00201 return is;
00202 }
00203
00204
00206 inline std::ostream& operator << (std::ostream& os,
00207 const Go::BoundingBox& bbox)
00208 {
00209 bbox.write(os);
00210 return os;
00211 }
00212
00213
00215 }
00216
00217
00218 #endif // _GOBOUNDINGBOX_H
00219