00001 #ifndef BoundingBox_HEADER
00002 #define BoundingBox_HEADER
00003
00004 #include <algorithm>
00005 #include <utilities/identity.h>
00006
00007 #include "Point.h"
00008 #include "ProjectionPlane.h"
00009
00010 namespace Geometry {
00011
00012
00013
00014
00015 template <unsigned d>
00016 struct BoundingBox {
00017 typedef Geometry::Point<d> Point;
00018 static const unsigned dimension = d;
00019
00020 Point mincorner;
00021 double extent;
00022
00023 BoundingBox(): mincorner(0.0), extent(0.0) { }
00024
00025 BoundingBox(Point p, double e)
00026 : mincorner(p), extent(e) { }
00027
00028
00029 template <class iterator>
00030 BoundingBox(iterator begin, iterator end) {
00031 init(begin, end, hudson::form_identity(*begin));
00032 }
00033
00034
00035
00036 template <class iterator, unsigned ambient>
00037 BoundingBox(iterator begin, iterator end,
00038 const ProjectionPlane<ambient, d>& plane) {
00039 typedef ProjectionPlane<ambient, d> ProjectionPlane;
00040 init(begin, end, std::bind1st(std::mem_fun(&ProjectionPlane::project1), &plane));
00041 }
00042
00043
00044
00045 template <class iterator, class xform>
00046 BoundingBox(iterator begin, iterator end, const xform& x) {
00047 init(begin, end, x);
00048 }
00049
00050
00051
00052
00053 BoundingBox scale(double buffer) const {
00054 BoundingBox bigbox;
00055 bigbox.mincorner = mincorner -
00056 (Point(1.0) * buffer * extent);
00057 bigbox.extent = extent * (1.0 + 2.0 * buffer);
00058 return bigbox;
00059 }
00060
00061 bool bitwiseEqual(const BoundingBox& other) const {
00062 return extent == other.extent
00063 && mincorner.bitwiseEqual(other.mincorner);
00064 }
00065
00066
00067 bool inBox(const Point& p) const {
00068 for(size_t i = 0; i < d; ++i) {
00069 if (p[i] < mincorner[i] || p[i] > mincorner[i] + extent) {
00070 return false;
00071 }
00072 }
00073 return true;
00074 }
00075
00076 bool inClosedBox(const Point& p) const {
00077 for(size_t i = 0; i < d; ++i) {
00078 if (p[i] <= mincorner[i] || p[i] >= mincorner[i] + extent) {
00079 return false;
00080 }
00081 }
00082 return true;
00083 }
00084
00085 std::string toString() const {
00086 char buffer[4096];
00087 sprintf(buffer, ", sidelength = %g", extent);
00088 return mincorner.toString() + buffer;
00089 }
00090
00091 private:
00092 template <class iterator, class xform>
00093 void init(iterator begin, iterator end, const xform& x) {
00094 assert(begin != end);
00095 Point mincoords, maxcoords;
00096 iterator it = begin;
00097 mincoords = maxcoords = x(*it);
00098 Point sum(x(*begin));
00099 size_t n = 1;
00100 for(++it ; it != end; ++it) {
00101 Point p = x(*it);
00102 n++;
00103 for(unsigned i = 0; i < d; i++) {
00104 mincoords[i] = std::min(mincoords[i], p[i]);
00105 maxcoords[i] = std::max(maxcoords[i], p[i]);
00106 }
00107 }
00108 extent = 0.0;
00109 for (unsigned i = 0; i < d; i++) {
00110 extent = std::max(maxcoords[i] - mincoords[i], extent);
00111 }
00112 Point center = (maxcoords + mincoords) * 0.5;
00113 mincorner = center - Point(1) * (extent / 2.0);
00114
00115 if ( (mincoords - mincorner).norm1() < 0.0 ) {
00116 mincorner = mincoords;
00117 }
00118 }
00119 };
00120
00121 }
00122
00123 #endif