00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef SHAPE_BOX_H
00010 #define SHAPE_BOX_H
00011
00012 #include <core/imaging2.hpp>
00013 #include <core/utilities.hpp>
00014
00015 namespace imaging
00016 {
00017 template <std::size_t N>
00018 class Box;
00019
00025 template <std::size_t N>
00026 void compute_intersection_box(const Box<N> & box_a, const Box<N> & box_b, Box<N> & result);
00027
00033 template <std::size_t N>
00034 class Box
00035 {
00036 friend void compute_intersection_box<>(const Box<N> & box_a, const Box<N> & box_b, Box<N> & result);
00037
00038 ublas::fixed_vector<float_t, N> _lower_corner;
00039 ublas::fixed_vector<float_t, N> _upper_corner;
00040
00041 public:
00042 Box() : _lower_corner(), _upper_corner() {}
00043
00045 Box(const ublas::fixed_vector<float_t, N> & lower_corner, const ublas::fixed_vector<float_t, N> & upper_corner) : _lower_corner(lower_corner), _upper_corner(upper_corner)
00046 {}
00047
00049 template <class image_accessor_t>
00050 Box(const image_accessor_t & accessor)
00051 {
00052 for(size_t i = 0; i < N; ++i)
00053 _lower_corner = 0.0;
00054
00055 _upper_corner = accessor.size();
00056 }
00057
00059 void set_empty()
00060 {
00061 for(std::size_t i = 0; i < N; ++i)
00062 {
00063 _lower_corner(i) = 0.0;
00064 _upper_corner(i) = 0.0;
00065 }
00066 }
00067
00069 bool is_empty() const
00070 {
00071 for(std::size_t i = 0; i < N; ++i)
00072 if(_lower_corner(i) >= _upper_corner(i))
00073 return true;
00074
00075 return false;
00076 }
00077
00079 float_t compute_volume() const
00080 {
00081 float_t v = 1.0;
00082
00083 if(is_empty())
00084 return 0.0;
00085
00086 for(size_t i = 0; i < N; ++i)
00087 v *= _upper_corner(i) - _lower_corner(i);
00088
00089 return v;
00090 }
00091
00093 void add_point(const ublas::fixed_vector<float_t, N> & point)
00094 {
00095 for(size_t i = 0; i < N; ++i)
00096 {
00097 if(point(i) > _upper_corner(i)) _upper_corner(i) = point(i);
00098 if(point(i) < _lower_corner(i)) _lower_corner(i) = point(i);
00099 }
00100 }
00101 };
00102
00103
00109 template <std::size_t N>
00110 bool do_intersect(const Box<N> & box_a, const Box<N> & box_b)
00111 {
00112 if(box_a.is_empty() || box_b.is_empty())
00113 return false;
00114
00115 Box<N> intersection_box;
00116 compute_intersection_box(box_a, box_b, intersection_box);
00117
00118 if(intersection_box.is_empty())
00119 return false;
00120
00121 return true;
00122 }
00123
00124 template <std::size_t N>
00125 void compute_intersection_box(const Box<N> & box_a, const Box<N> & box_b, Box<N> & result)
00126 {
00127 for(size_t i = 0; i < N; ++i)
00128 {
00129 result._lower_corner(i) = max(box_a._lower_corner(i), box_b._lower_corner(i));
00130 result._upper_corner(i) = min(box_a._upper_corner(i), box_b._upper_corner(i));
00131 }
00132 }
00133
00139 template <std::size_t N>
00140 float_t compute_intersection_volume(const Box<N> & box_a, const Box<N> & box_b)
00141 {
00142 if(! do_intersect(box_a, box_b))
00143 return 0.0;
00144
00145 Box<N> intersection_box;
00146
00147 compute_intersection_box(box_a, box_b, intersection_box);
00148
00149 return intersection_box.compute_volume();
00150 }
00151 }
00152
00153
00154 #endif