00001
00002
00003
00004
00005
00006
00007
00008 #ifndef IMPALGEBRA_BOUNDING_BOX_D_H
00009 #define IMPALGEBRA_BOUNDING_BOX_D_H
00010
00011 #include "VectorD.h"
00012 #include "Transformation3D.h"
00013 #include "algebra_macros.h"
00014
00015 IMPALGEBRA_BEGIN_NAMESPACE
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 template <unsigned int D>
00026 class BoundingBoxD
00027 {
00028 void make_empty() {
00029 for (unsigned int i=0; i< D; ++i) {
00030 b_[0][i]= std::numeric_limits<double>::max();
00031 b_[1][i]=-std::numeric_limits<double>::max();
00032 }
00033 }
00034 public:
00035
00036 IMP_NO_DOXYGEN(typedef BoundingBoxD<D> This);
00037
00038
00039 BoundingBoxD() {
00040 make_empty();
00041 }
00042
00043 BoundingBoxD(const VectorD<D> &lb,
00044 const VectorD<D> &ub){
00045 b_[0]=lb;
00046 b_[1]=ub;
00047 IMP_IF_CHECK(USAGE) {
00048 for (unsigned int i=0; i< D; ++i) {
00049 IMP_USAGE_CHECK(lb[i] <= ub[i],
00050 "Invalid bounding box");
00051 }
00052 }
00053 }
00054
00055 BoundingBoxD(const VectorD<D> &v) {
00056 b_[0]=v; b_[1]=v;
00057 }
00058
00059
00060 BoundingBoxD(const std::vector<VectorD<D> > &points) {
00061 make_empty();
00062 for(unsigned int j=0;j<points.size();j++) {
00063 operator+=(points[j]);
00064 }
00065 }
00066
00067
00068 const BoundingBoxD<D>& operator+=(const BoundingBoxD<D> &o) {
00069 for (unsigned int i=0; i< D; ++i) {
00070 b_[0][i]= std::min(o.get_corner(0)[i], get_corner(0)[i]);
00071 b_[1][i]= std::max(o.get_corner(1)[i], get_corner(1)[i]);
00072 }
00073 return *this;
00074 }
00075
00076
00077 const BoundingBoxD<D>& operator+=(const VectorD<D> &o) {
00078 for (unsigned int i=0; i< D; ++i) {
00079 b_[0][i]= std::min(o[i], b_[0][i]);
00080 b_[1][i]= std::max(o[i], b_[1][i]);
00081 }
00082 return *this;
00083 }
00084
00085
00086 const BoundingBoxD<D>& operator+=(double o) {
00087 for (unsigned int i=0; i< D; ++i) {
00088 b_[0][i]= b_[0][i]-o;
00089 b_[1][i]= b_[1][i]+o;
00090 }
00091 return *this;
00092 }
00093
00094 template <class O>
00095 const BoundingBoxD<D> operator+(const O &o) {
00096 BoundingBoxD<D> ret(*this);
00097 ret+= o;
00098 return ret;
00099 }
00100
00101
00102 const VectorD<D>& get_corner(unsigned int i) const {
00103 IMP_USAGE_CHECK(i < 2, "Can only use 0 or 1");
00104 return b_[i];
00105 }
00106
00107 bool get_contains(const VectorD<D> &o) const {
00108 for (unsigned int i=0; i< D; ++i) {
00109 if (o[i] < get_corner(0)[i]
00110 || o[i] > get_corner(1)[i]) return false;
00111 }
00112 return true;
00113 }
00114
00115 bool get_contains(const BoundingBoxD &bb) const {
00116 return get_contains(bb.get_corner(0)) && get_contains(bb.get_corner(1));
00117 }
00118
00119 IMP_SHOWABLE_INLINE(out << b_[0] << ": " << b_[1]);
00120
00121 private:
00122 VectorD<D> b_[2];
00123 };
00124
00125 IMP_VOLUME_GEOMETRY_METHODS_D(BoundingBox, IMP_NOT_IMPLEMENTED,
00126 return (g.get_corner(1)[0]- g.get_corner(0)[0])
00127 *(g.get_corner(1)[1]- g.get_corner(0)[1])
00128 *(g.get_corner(1)[2]- g.get_corner(0)[2]),
00129 return g);
00130
00131 #ifdef IMP_DOXYGEN
00132
00133 typedef BoundingBoxD<3> BoundingBoxD<3>;
00134 #endif
00135
00136 template <unsigned int D>
00137 BoundingBoxD<D> get_unit_bounding_box_d() {
00138 return BoundingBoxD<D>(get_zero_vector_d<D>(), get_ones_vector_d<D>());
00139 }
00140
00141
00142 inline BoundingBoxD<3> get_transformed(const BoundingBoxD<3> &bb,
00143 const Transformation3D &tr) {
00144 BoundingBoxD<3> nbb;
00145 for (unsigned int i=0; i< 2; ++i) {
00146 for (unsigned int j=0; j< 2; ++j) {
00147 for (unsigned int k=0; k< 2; ++k) {
00148 algebra::VectorD<3> v(bb.get_corner(i)[0],
00149 bb.get_corner(j)[1],
00150 bb.get_corner(k)[2]);
00151 nbb+= tr.get_transformed(v);
00152 }
00153 }
00154 }
00155 return nbb;
00156 }
00157
00158 IMPALGEBRA_END_NAMESPACE
00159
00160 #endif