BoundaryDiscretizer.hpp

00001 // This file is part of the imaging2 class library.
00002 //
00003 // University of Innsbruck, Infmath Imaging, 2009.
00004 // http://infmath.uibk.ac.at
00005 //
00006 // All rights reserved.
00007 
00008 
00009 #ifndef SHAPE_BOUNDARYDISCRETIZER_H
00010 #define SHAPE_BOUNDARYDISCRETIZER_H
00011 
00012 #include <shape/Box.hpp>
00013 
00014 namespace imaging
00015 {
00017   namespace boundary_discretizer_impl
00018   {
00019     float_t compute_curve_curvature(ublas::fixed_vector<float_t, 2> & first_derivative, ublas::fixed_vector<float_t, 2> & second_derivative);
00020     
00021     template <class const_vector_accessor_t>
00022     void compute_zero_extension(const const_vector_accessor_t  & vector_field, const ublas::fixed_vector<float_t, const_vector_accessor_t::dimension> & point, ublas::fixed_vector<float_t, const_vector_accessor_t::dimension> & value)
00023     {
00024       const size_t N = const_vector_accessor_t::dimension;
00025       bool is_valid = true;
00026       bool no_valid_index = true;
00027       ublas::fixed_vector<size_t, N> valid_index;
00028       value = ublas::scalar_vector<float_t>(N, 0.0);
00029       
00030       // check if a coordinate is negative
00031       for(size_t i = 0; i < N; ++i)
00032         if(point(i) < 0.0)
00033           return;
00034         
00035       valid_index = ublas::fixed_vector<size_t, N>(point);
00036       int valid_coordinate;
00037 
00038       for(size_t i = 0; i < N; ++i)
00039         if( ! ( valid_index(i) < vector_field.size()(i) ) )
00040         {
00041           if(! is_valid)
00042             return;
00043           else  
00044           {
00045             valid_index(i) = vector_field.size()(i) - 1;
00046             is_valid = false;
00047           }
00048           valid_coordinate = i;
00049           no_valid_index = false;
00050         }
00051       
00052       if(no_valid_index)
00053       {
00054         value = vector_field[ublas::fixed_vector<size_t, N>(point)];
00055         return;
00056       }
00057       
00058       value(valid_coordinate) = vector_field[valid_index](valid_coordinate);
00059     }
00060   }
00061   
00068   template <size_t N>
00069   class BoundaryDiscretizer
00070   {
00071   protected:
00073     size_t _n_points;
00074     
00075   public:
00077     static const size_t SHAPE_DIMENSION = N;
00078   
00080     BoundaryDiscretizer(size_t n_points) : _n_points(n_points) {}
00081     
00082     virtual ~BoundaryDiscretizer() {}
00083     
00085     size_t n_points() const { return _n_points; }
00086     
00088     virtual void evaluate(size_t i, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & point, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & normal, float_t & curvature) const = 0;
00089     
00091     ublas::fixed_vector<float_t, SHAPE_DIMENSION> operator()(size_t i, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & normal, float_t & curvature) const
00092     {
00093       ublas::fixed_vector<float_t, SHAPE_DIMENSION> point;
00094       evaluate(i, point, normal, curvature);
00095       return point;
00096     }
00097     
00099     ublas::fixed_vector<float_t, SHAPE_DIMENSION> operator()(size_t i, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & normal) const
00100     {
00101       float_t curvature;
00102       return operator()(i, normal, curvature);
00103     }
00104     
00106     ublas::fixed_vector<float_t, SHAPE_DIMENSION> operator()(size_t i) const
00107     {
00108       ublas::fixed_vector<float_t, SHAPE_DIMENSION> normal;
00109       return operator()(i, normal);
00110     }
00111       
00113     template <class const_accessort_t>
00114     typename const_accessort_t::data_t integrate(const const_accessort_t & image) const
00115     {
00116       typename const_accessort_t::data_t result = 0.0;
00117       ublas::fixed_vector<float_t, SHAPE_DIMENSION> point, normal;
00118 
00119       for(size_t i = 0; i < n_points(); ++i)
00120       {
00121         point = (*this)(i, normal);
00122         
00123         // explicit cast of floating point values in "vertex" to pixel position!
00124         ublas::fixed_vector<size_t, const_accessort_t::dimension> pixel_position = ublas::fixed_vector<size_t, const_accessort_t::dimension>(point);
00125         bool is_valid_pixel = true;
00126         
00127         for(size_t i = 0; i < const_accessort_t::dimension; ++i)
00128         {
00129           if( ! ( pixel_position(i) < image.size()(i) ) )
00130           {
00131             is_valid_pixel = false;
00132             break;
00133           }
00134         }
00135         
00136         if(is_valid_pixel)
00137           result += image[pixel_position] * norm_2(normal);
00138       }
00139 
00140       return result;
00141     }
00142     
00144     float_t compute_boundary_area() const
00145     {
00146       float_t result = 0.0;
00147       ublas::fixed_vector<float_t, SHAPE_DIMENSION> point, normal;
00148 
00149       for(size_t i = 0; i < n_points(); ++i)
00150       {
00151         point = (*this)(i, normal);
00152         
00153         result += norm_2(normal);
00154       }
00155 
00156       return result;
00157     }
00158     
00159     
00161     template <class const_vector_accessor_t>
00162     float_t integrate_vector_field
00163     (const const_vector_accessor_t & vector_field) const
00164     {
00165       float_t result = 0.0;
00166       ublas::fixed_vector<float_t, SHAPE_DIMENSION> point, normal;
00167 
00168       for(size_t i = 0; i < n_points(); ++i)
00169       {
00170         point = (*this)(i, normal);
00171         
00172         // explicit cast of floating point values in "vertex" to pixel position!
00173         ublas::fixed_vector<size_t, const_vector_accessor_t::dimension> pixel_position = ublas::fixed_vector<size_t, const_vector_accessor_t::dimension>(point);
00174         bool is_valid_pixel = true;
00175         
00176         for(size_t i = 0; i < const_vector_accessor_t::dimension; ++i)
00177         {
00178           if( ! ( pixel_position(i) < vector_field.size()(i) ) )
00179           {
00180             is_valid_pixel = false;
00181             break;
00182           }
00183         }
00184         
00185         if(is_valid_pixel)
00186           // Note: unit normal * tangential speed = normal
00187           result += inner_prod(vector_field[pixel_position], normal);
00188         else
00189         {
00190           ublas::fixed_vector<float_t, SHAPE_DIMENSION> value;
00191           boundary_discretizer_impl::compute_zero_extension(vector_field, point, value);
00192           result += inner_prod(value, normal);
00193         }
00194       }
00195 
00196       return result;
00197     }
00198     
00199             
00200     
00202     Box<SHAPE_DIMENSION> compute_bounding_box() const
00203     {
00204       ublas::fixed_vector<float_t, SHAPE_DIMENSION> lower_corner, upper_corner, point;
00205       
00206       if(n_points() == 0)
00207         return Box<SHAPE_DIMENSION>();
00208         
00209       lower_corner = (*this)(0);
00210       upper_corner = (*this)(0);
00211           
00212       for(size_t i = 1; i < n_points(); ++i)
00213       {
00214         point = (*this)(i);
00215         for(size_t j = 0; j < SHAPE_DIMENSION; ++j)
00216         {
00217           if(point(j) < lower_corner(j))
00218             lower_corner(j) = point(j);
00219           
00220           if(point(j) > upper_corner(j))
00221             upper_corner(j) = point(j);
00222         }
00223       }
00224       
00225       return Box<SHAPE_DIMENSION>(lower_corner, upper_corner);
00226     }
00227   };
00228   
00230   float_t compute_intersection_volume(const BoundaryDiscretizer<2> & shape_a, const BoundaryDiscretizer<2> & shape_b);    
00231 }
00232 
00233 
00234 #endif

Generated on Tue Feb 10 10:01:30 2009 for imaging2 by  doxygen 1.5.5