00001 #ifndef SYNAPS_SHAPE_BASE_AABB_H
00002 #define SYNAPS_SHAPE_BASE_AABB_H
00003 #include <iostream>
00004 #include <realroot/Interval.hpp>
00005 #include <shape/fxv.hpp>
00006
00007 namespace mmx {
00008
00009 template<class C, unsigned N>
00010 struct aabb
00011 {
00012 fxv< Interval<C>, N > data;
00013 Interval<C> & operator[]( int i ) { return data[i]; };
00014 const Interval<C> & operator[]( int i ) const { return data[i]; };
00015 };
00016
00017 template<class C, unsigned N> inline
00018 void fill( aabb<C,N>& box, const fxv<C,N> & v )
00019 {
00020 for ( unsigned i = 0; i < N; box[i] = v[i], i ++ );
00021 };
00022
00023 template<class C, unsigned N> inline
00024 void fill( aabb<C,N> & box, const fxv<C,N> * v, unsigned sz )
00025 {
00026 init(box,v[sz-1]);
00027 double m,M;
00028 const fxv<C,N> * src;
00029 for ( src = v; src != v+sz; src ++ )
00030 {
00031 for ( unsigned i = 0; i < 3; i++ )
00032 {
00033 if ( (*src)[i] > (*(src+1))[i] ) { m = (*(src+1))[i]; M = (*src)[i]; }
00034 else { m = (*src)[i]; M = (*(src+1))[i]; };
00035 if ( box[i].m > m ) box[i].m = m;
00036 if ( box[i].M < M ) box[i].M = M;
00037 };
00038 };
00039 };
00040
00041 template<class C, unsigned N> inline
00042 void fill( aabb<C,N>& box, const fxv<C,N>& a, const fxv<C,N>& b )
00043 {
00044 for ( unsigned d = 0; d < N; d++ )
00045 {
00046 if ( a[d] < b[d] )
00047 { box[d].m = a[d]; box[d].M = b[d]; }
00048 else
00049 { box[d].m = b[d]; box[d].M = a[d]; };
00050 };
00051 };
00052
00053 template<class C, unsigned N> inline
00054 void hull( aabb<C,N>& h, const aabb<C,N>& a, const aabb<C,N>& b )
00055 {
00056 for ( unsigned i = 0; i < N; i++ )
00057 {
00058 h[i].m = std::min(a[i].m,b[i].m);
00059 h[i].M = std::max(a[i].M,b[i].M);
00060 };
00061 };
00062
00063 template<class C, unsigned N> inline
00064 void hull( aabb<C,N>& h, const aabb<C,N> & b )
00065 {
00066 for ( unsigned i = 0; i < 3; i ++ )
00067 if ( h[i].m > b[i] ) h[i].m = b[i]; else if ( h[i].M < b[i] ) h[i].M = b[i];
00068 };
00069
00070 template<class C, unsigned N> inline
00071 bool intersectp( const aabb<C,N>& a, const aabb<C,N>& b )
00072 {
00073 for ( unsigned i = 0; i < 3; i ++ )
00074 if ( a[i].m > b[i].M || b[i].m > a[i].M ) return false;
00075 return true;
00076 };
00077
00078
00079 template<class C, unsigned N> inline
00080 C lmax( const aabb<C,N> & box )
00081 {
00082 C l,s;
00083 l = box[0].width();
00084 for ( unsigned i = 1; i < 3; i ++ )
00085 {
00086 s = box[i].width();
00087 if ( s > l ) l = s;
00088 };
00089 return l;
00090 };
00091
00092 template<class C, unsigned N> inline
00093 C lmin( const aabb<C,N>& box )
00094 {
00095 C l,s;
00096 l = box[0].width();
00097 for ( unsigned i = 1; i < 3; i ++ )
00098 {
00099 s = box[i].width();
00100 if ( s < l ) l = s;
00101 };
00102 return l;
00103 };
00104
00105 template<class C, unsigned N> inline
00106 void fill( aabb<C,N> & box, const fxv<C,N> & a, const fxv<C,N> & b, const fxv<C,N> & c, const fxv<C,N> & d )
00107 {
00108 aabb<C,N> tmp;
00109 fill(box,a,b);
00110 fill(tmp,c,d);
00111 hull(box,tmp);
00112 };
00113
00114 template<class C, unsigned N> inline
00115 std::ostream & operator<<( std::ostream& o, const aabb<C,N> & b )
00116 {
00117 o << "[ ";
00118 for ( int i = 0; i < N; i ++ ) o << b[i] << " ";
00119 o << "] ";
00120 return o;
00121 };
00122 }
00123 #endif
00124
00125
00126
00127
00128