TuttleOFX
1
|
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