TuttleOFX
1
|
00001 #ifndef _TUTTLE_PLUGIN_COLORGRADIENT_1DLINEARFUNCTOR_HPP_ 00002 #define _TUTTLE_PLUGIN_COLORGRADIENT_1DLINEARFUNCTOR_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 00012 #include <boost/gil/gil_all.hpp> 00013 #include <boost/math/special_functions/pow.hpp> 00014 00015 #include <cmath> 00016 #include <vector> 00017 00018 namespace tuttle { 00019 namespace plugin { 00020 namespace colorGradient { 00021 typedef boost::gil::point2<double> point_t; 00022 00023 class LineEquation 00024 { 00025 double _a, _b, _c; ///< equation 00026 point_t _AB; ///< BC vector 00027 00028 public: 00029 LineEquation() {} 00030 LineEquation( const point_t& A, const point_t& B ) 00031 : _AB( B - A ) 00032 { 00033 // compute equation BC, ax + by + c = 0 00034 _a = B.y - A.y; 00035 _b = A.x - B.x; 00036 _c = ( A.y - B.y ) * A.x + ( B.x - A.x ) * A.y; 00037 } 00038 00039 template <class Point> 00040 Point pointOrthogonalProjection( const Point& p ) const 00041 { 00042 // compute coordinates of M, the orthogonal projection of p on current line 00043 Point res; 00044 00045 res.y = ( -( _a * p.x ) - ( _a * _AB.y * p.y / _AB.x ) - _c ) / ( _b - ( _a * _AB.y / _AB.x ) ); 00046 res.x = ( -_c - _b * res.y ) / _a; 00047 return res; 00048 } 00049 00050 }; 00051 00052 // Models a Unary Function 00053 template <typename P> 00054 // Models PixelValueConcept 00055 class ColorGrandient1DLinearFunctor 00056 { 00057 public: 00058 typedef boost::gil::point2<double> point_t; 00059 00060 typedef ColorGrandient1DLinearFunctor const_t; 00061 typedef P value_type; 00062 typedef value_type reference; 00063 typedef value_type const_reference; 00064 typedef point_t argument_type; 00065 typedef reference result_type; 00066 BOOST_STATIC_CONSTANT( bool, is_mutable = false ); 00067 00068 /* 00069 struct ColoredPoint 00070 { 00071 point_t _position; 00072 value_type _color; 00073 }; 00074 */ 00075 std::vector<point_t> _points; 00076 std::vector<value_type> _colors; 00077 std::vector<double> _distanceToB; 00078 LineEquation _droiteEquation; 00079 point_t _pB; ///< point B 00080 point_t _pC; ///< point C 00081 00082 ColorGrandient1DLinearFunctor() {} 00083 00084 ColorGrandient1DLinearFunctor( const point_t& size, const std::vector<point_t>& points, const std::vector<value_type>& colors ) 00085 : _points( points ) 00086 , _colors( colors ) 00087 { 00088 assert( _points.size() == _colors.size() ); 00089 assert( _points.size() >= 2 ); 00090 00091 _pB = _points[0] * size; // to canonical coordinates 00092 _pC = _points[1] * size; 00093 _droiteEquation = LineEquation( _pB, _pC ); 00094 00095 // fill _distanceToB 00096 _distanceToB.reserve( _points.size() ); 00097 for( std::vector<point_t>::const_iterator it = _points.begin(), itEnd = _points.end(); 00098 it != itEnd; 00099 ++it ) 00100 { 00101 _distanceToB.push_back( distance( *it, _pB ) ); 00102 } 00103 // sort _points, _colors, _distanceToB 00104 } 00105 00106 double distance( const point_t& a, const point_t& b ) const 00107 { 00108 return std::sqrt( boost::math::pow<2>( b.x - a.x ) + boost::math::pow<2>( b.y - a.y ) ); 00109 } 00110 00111 result_type operator()( const point_t& pA ) const 00112 { 00113 using namespace boost::gil; 00114 using namespace terry; 00115 using namespace terry::numeric; 00116 point_t pM = _droiteEquation.pointOrthogonalProjection( pA ); 00117 // TUTTLE_LOG_INFO( "________________________________________" ); 00118 // TUTTLE_LOG_VAR( TUTTLE_INFO, _pB ); 00119 // TUTTLE_LOG_VAR( TUTTLE_INFO, _pC ); 00120 // TUTTLE_LOG_VAR( TUTTLE_INFO, pA ); 00121 // TUTTLE_LOG_VAR( TUTTLE_INFO, pM ); 00122 double distB = distance( pM, _pB ); 00123 double distC = distance( pM, _pC ); 00124 double norm = distB + distC; 00125 // TUTTLE_LOG_VAR3( TUTTLE_INFO, distB, distC, norm ); 00126 distB /= norm; 00127 distC /= norm; 00128 // TUTTLE_LOG_VAR2( TUTTLE_INFO, _pB, _pC ); 00129 // TUTTLE_LOG_VAR2( TUTTLE_INFO, distB, distC ); 00130 // distB * _colors[0] + distC * _colors[1]; 00131 return pixel_plus_t<result_type, result_type, result_type>() ( 00132 pixel_multiplies_scalar_t<result_type, double, result_type>() ( _colors[0], distB ), 00133 pixel_multiplies_scalar_t<result_type, double, result_type>() ( _colors[1], distC ) 00134 ); 00135 } 00136 00137 }; 00138 00139 } 00140 } 00141 } 00142 00143 #endif