TuttleOFX  1
ColorGrandient2DLinearFunctor.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_PLUGIN_COLORGRADIENT_2DLINEARFUNCTOR_HPP_
00002 #define _TUTTLE_PLUGIN_COLORGRADIENT_2DLINEARFUNCTOR_HPP_
00003 
00004 #include "../ColorGradientDefinitions.hpp"
00005 
00006 #include <tuttle/plugin/global.hpp>
00007 
00008 #include <terry/globals.hpp>
00009 #include <terry/point/operations.hpp>
00010 #include <terry/numeric/operations.hpp>
00011 #include <terry/numeric/operations_assign.hpp>
00012 #include <terry/numeric/assign.hpp>
00013 #include <terry/numeric/init.hpp>
00014 
00015 #include <boost/gil/gil_all.hpp>
00016 #include <boost/math/special_functions/pow.hpp>
00017 
00018 #include <cmath>
00019 #include <vector>
00020 
00021 namespace tuttle {
00022 namespace plugin {
00023 namespace colorGradient {
00024 
00025 // Models a Unary Function
00026 template <typename P>
00027 // Models PixelValueConcept
00028 class ColorGrandient2DLinearFunctor
00029 {
00030 public:
00031         typedef double Scalar;
00032         typedef boost::gil::point2<Scalar> point_t;
00033 
00034         typedef ColorGrandient2DLinearFunctor const_t;
00035         typedef P value_type;
00036         typedef value_type reference;
00037         typedef value_type const_reference;
00038         typedef point_t argument_type;
00039         typedef reference result_type;
00040         BOOST_STATIC_CONSTANT( bool, is_mutable = false );
00041 
00042         typedef std::vector<point_t> PointsVector;
00043         typedef std::vector<value_type> ColorsVector;
00044         typedef std::vector<Scalar> DistancesVector;
00045         PointsVector _points;
00046         ColorsVector _colors;
00047 
00048         mutable DistancesVector _distances; // temporary values
00049 
00050         ColorGrandient2DLinearFunctor() {}
00051 
00052         ColorGrandient2DLinearFunctor( const point_t& size, const std::vector<point_t>& points, const std::vector<value_type>& colors )
00053                 : _points( points )
00054                 , _colors( colors )
00055         {
00056                 assert( _points.size() == _colors.size() );
00057                 assert( _points.size() >= 2 );
00058 
00059                 _distances.resize( _points.size() );
00060 
00061                 for( PointsVector::iterator it = _points.begin(), itEnd = _points.end();
00062                      it != itEnd;
00063                      ++it )
00064                 {
00065                         ( *it ) *= size; // to canonical coordinates
00066                 }
00067         }
00068 
00069 private:
00070         Scalar distance( const point_t& a, const point_t& b ) const
00071         {
00072                 //              return std::sqrt( boost::math::pow<2>(b.x - a.x) + boost::math::pow<2>(b.y - a.y) );
00073                 return boost::math::pow<2>( b.x - a.x ) + boost::math::pow<2>( b.y - a.y );
00074         }
00075 
00076         void computeDistances( const point_t& p ) const
00077         {
00078                 double sum                            = 0;
00079                 DistancesVector::iterator it_dist     = _distances.begin(), itEnd_dist = _distances.end();
00080                 PointsVector::const_iterator it_point = _points.begin();
00081 
00082                 for( ;
00083                      it_dist != itEnd_dist;
00084                      ++it_dist, ++it_point )
00085                 {
00086                         *it_dist = 1.0 / distance( p, *it_point );
00087                         sum     += *it_dist;
00088                 }
00089                 for( it_dist = _distances.begin();
00090                      it_dist != itEnd_dist;
00091                      ++it_dist )
00092                 {
00093                         *it_dist /= sum; // normalize values
00094                 }
00095         }
00096 
00097 public:
00098         result_type operator()( const point_t& p ) const
00099         {
00100                 using namespace boost::gil;
00101                 using namespace terry;
00102                 using namespace terry::numeric;
00103                 computeDistances( p );
00104                 result_type outputColor;
00105                 pixel_zeros_t<result_type>() ( outputColor );
00106 
00107                 typename ColorsVector::const_iterator it_color = _colors.begin(), itEnd_color = _colors.end();
00108                 DistancesVector::const_iterator it_dist = _distances.begin();
00109 
00110                 for( ;
00111                      it_color != itEnd_color;
00112                      ++it_color, ++it_dist )
00113                 {
00114                         // outputColor += color * dist
00115                         pixel_plus_assign_t<result_type, result_type>() (
00116                             pixel_multiplies_scalar_t<result_type, Scalar, result_type>() ( *it_color, *it_dist ),
00117                             outputColor
00118                             );
00119                 }
00120                 return outputColor;
00121         }
00122 
00123 };
00124 
00125 }
00126 }
00127 }
00128 
00129 #endif