00001 #ifndef ANIMAL__BOUNDINGBOX___________
00002 #define ANIMAL__BOUNDINGBOX___________
00003
00004 #include <iostream>
00005
00006 #include <animal/vec3.h>
00007 #include <animal/container_traits.h>
00008
00009 namespace animal {
00010
00011
00012
00017
00018
00019 template <
00020 class Point = Vec3,
00021 class Real = typename container_traits<Point>::value_type
00022 >
00023 class BoundingBox3D
00024 {
00025 public:
00026
00029
00033 BoundingBox3D(
00034 Real xm = INFINITY,
00035 Real ym = INFINITY,
00036 Real zm = INFINITY,
00037 Real xM = -INFINITY,
00038 Real yM = -INFINITY,
00039 Real zM = -INFINITY
00040 )
00041 {
00042 _min[0] = xm; _min[1] = ym; _min[2] = zm;
00043 _max[0] = xM; _max[1] = yM; _max[2] = zM;
00044 }
00045
00047 BoundingBox3D( const Point& v )
00048 {
00049 for( int i=0; i<3; ++i ){
00050 _min[i] = _max[i] = v[i];
00051 }
00052 }
00053
00055 BoundingBox3D( const Point& v_min, const Point& v_max )
00056 {
00057 for( int i=0; i<3; ++i ){
00058 _min[i] = v_min[i];
00059 _max[i] = v_max[i];
00060 }
00061 }
00062
00064
00067
00069 Point min() const { return Point(_min[0],_min[1],_min[2]); }
00070
00072 Point max() const { return Point(_max[0], _max[1], _max[2]); }
00073
00075
00076
00079
00081 void insert( const Point& v )
00082 {
00083 for( int i=0; i<3; ++i ){
00084 if( v[i]<_min[i] ) _min[i]=v[i];
00085 else if( v[i]>_max[i] ) _max[i] = v[i];
00086 }
00087 }
00088
00090 void insert( const BoundingBox3D& b )
00091 {
00092 for( int i=0; i<3; ++i ){
00093 if( b._min[i]<_min[i] ) _min[i] = b._min[i];
00094 if( b._max[i]>_max[i] ) _max[i] = b._max[i];
00095 }
00096 }
00097
00099 void shift( const Point& v )
00100 {
00101 for( int i=0; i<3; ++i ){
00102 _min[i] += v[i];
00103 _max[i] += v[i];
00104 }
00105 }
00106
00107
00111 template< class RotationMatrix >
00112 BoundingBox3D move ( const Point& p, const RotationMatrix& r )
00113 {
00114
00115 Real center[3], half[3];
00116 for( int i=0; i<3; ++i ){
00117 center[i] = (_max[i] + _min[i]) /2;
00118 half[i] = (_max[i] - _min[i]) /2;
00119 }
00120
00121
00122 Real newhalf[3] = {0,0,0};
00123 {for( int i=0; i<3; ++i ){
00124 for( int j=0; j<3; ++j ){
00125 newhalf[i] += fabs( r[i][j] * half[j] );
00126 }
00127 }}
00128
00129
00130 Real newcenter[3];
00131 {for( int i=0; i<3; ++i ){
00132 newcenter[i] = p[i];
00133 for( int j=0; j<3; ++j ){
00134 newcenter[i] += r[i][j] * center[j] ;
00135 }
00136 }}
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 return BoundingBox3D(
00150 newcenter[0] - newhalf[0],
00151 newcenter[1] - newhalf[1],
00152 newcenter[2] - newhalf[2],
00153 newcenter[0] + newhalf[0],
00154 newcenter[1] + newhalf[1],
00155 newcenter[2] + newhalf[2]
00156 );
00157
00158 }
00159
00161
00163
00165 template < class P, class R >
00166 friend bool intersect( const BoundingBox3D<P,R>& b1, const BoundingBox3D<P,R>& b2 );
00167
00169
00172
00174 template < class P, class R >
00175 friend std::ostream& operator << ( std::ostream&, const BoundingBox3D<P,R>& );
00176
00178
00179 private:
00180
00181 Real _max[3];
00182 Real _min[3];
00183
00184 };
00185
00189
00190
00194
00195
00197
00199 template < class P, class R >
00200 inline std::ostream& operator<< ( std::ostream& os, const BoundingBox3D<P,R>& b )
00201 {
00202 os<<b._min[0]<<" "<<b._min[1]<<" "<<b._min[2]<<" "
00203 <<b._max[0]<<" "<<b._max[1]<<" "<<b._max[2];
00204 return os;
00205 }
00206
00208 template < class P, class R >
00209 inline bool intersect( const BoundingBox3D<P,R>& b1, const BoundingBox3D<P,R>& b2 )
00210 {
00211 return !(
00212 b1._max[0]<b2._min[0] || b2._max[0]<b1._min[0]
00213 || b1._max[1]<b2._min[1] || b2._max[1]<b1._min[1]
00214 || b1._max[2]<b2._min[2] || b2._max[2]<b1._min[2]
00215 );
00216 }
00218
00219 }
00220 #endif