Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include "cinder/CinderMath.h"
00026
00027 namespace cinder {
00028
00029 class FilterBase {
00030 public:
00031 FilterBase( float aSupport ) : mSupport( aSupport ) {}
00032 virtual ~FilterBase() {};
00033
00034 float getSupport() const { return mSupport; }
00035 void setSupport( float aSupport ) { mSupport = aSupport; }
00036
00037 virtual float operator()( float x ) const = 0;
00038 protected:
00039 float mSupport;
00040 };
00041
00042
00043 class FilterBox : public FilterBase {
00044 public:
00045 FilterBox( float aSupport = 0.5f ) : FilterBase( aSupport ) {}
00046
00047 virtual float operator()( float x ) const {
00048 if ( x < -0.5f ) return 0.0f;
00049 else if ( x < 0.5f ) return 1.0f;
00050 return 0.0f;
00051 }
00052 };
00053
00054
00055 class FilterTriangle : public FilterBase {
00056 public:
00057 FilterTriangle( float aSupport = 1.0f ) : FilterBase( aSupport ) {}
00058
00059 virtual float operator()( float x ) const {
00060 if ( x < -1.0f ) return 0.0f;
00061 else if ( x < 0.0f ) return 1.0f + x;
00062 else if ( x < 1.0f ) return 1.0f - x;
00063 return 0.0f;
00064 }
00065 };
00066
00067
00068 class FilterQuadratic : public FilterBase {
00069 public:
00070 FilterQuadratic( float aSupport = 1.5f ) : FilterBase( aSupport ) {}
00071
00072 virtual float operator()( float x ) const {
00073 float t;
00074
00075 if ( x < -1.5f ) return 0.0f;
00076 else if ( x < -0.5f ) { t = x + 1.5f; return 0.5f * t * t; }
00077 else if ( x < 0.5f ) return 0.75f - x * x;
00078 else if ( x < 1.5f ) { t = x - 1.5f; return 0.5f * t * t; }
00079 return 0.0f;
00080 }
00081 };
00082
00083
00084 class FilterCubic : public FilterBase {
00085 public:
00086 FilterCubic( float aSupport = 2.0f ) : FilterBase( aSupport ) {}
00087
00088 virtual float operator()( float x ) const {
00089 float t;
00090
00091 if ( x < -2.0f ) return 0.0f;
00092 else if ( x < -1.0f ) { t = 2.0f + x; return t * t * t / 6.0f; }
00093 else if ( x < 0.0f ) return ( 4.0f + x * x * ( -6.0f + x * -3.0f ) ) / 6.0f;
00094 else if ( x < 1.0f ) return ( 4.0f + x * x * ( -6.0f + x * 3.0f ) ) / 6.0f;
00095 else if ( x < 2.0f ) { t = 2.0f - x; return t * t * t / 6.0f; }
00096 return 0.0f;
00097 }
00098 };
00099
00100
00101 class FilterCatmullRom : public FilterBase {
00102 public:
00103 FilterCatmullRom( float aSupport = 2.0f ) : FilterBase( aSupport ) {}
00104
00105 virtual float operator()( float x ) const {
00106 if ( x < -2.0f ) return 0.0f;
00107 else if ( x < -1.0f ) return 0.5f * ( 4.0f + x * ( 8.0f + x * ( 5.0f + x ) ) );
00108 else if ( x < 0.0f ) return 0.5f * ( 2.0f + x * x * ( -5.0f + x * -3.0f ) );
00109 else if ( x < 1.0f ) return 0.5f * ( 2.0f + x * x * ( -5.0f + x * 3.0f ) );
00110 else if ( x < 2.0f ) return 0.5f * ( 4.0f + x * ( -8.0f + x * ( 5.0f - x ) ) );
00111 return 0.0f;
00112 }
00113 };
00114
00115
00116
00117 class FilterMitchell : public FilterBase {
00118 public:
00119 FilterMitchell( float aSupport = 2.0f, float b = 0.3333333333f, float c = 0.3333333333f ) : FilterBase( aSupport ) {
00120 mP0 = ( 6.0f - 2.0f * b ) / 6.0f;
00121 mP2 = ( -18.0f + 12.0f * b + 6.0f * c ) / 6.0f;
00122 mP3 = ( 12.0f - 9.0f * b - 6.0f * c ) / 6.0f;
00123 mQ0 = ( 8.0f * b + 24.0f * c ) / 6.0f;
00124 mQ1 = ( - 12.0f * b - 48.0f * c ) / 6.0f;
00125 mQ2 = ( 6.0f * b + 30.0f * c ) / 6.0f;
00126 mQ3 = ( -b - 6.0f * c ) / 6.0f;
00127 }
00128
00129 virtual float operator()( float x ) const {
00130 if ( x < -2.0f ) return 0.;
00131 else if ( x < -1.0f ) return mQ0 - x * ( mQ1 - x * ( mQ2 - x * mQ3 ) );
00132 else if ( x < 0.0f ) return mP0 + x * x * ( mP2 - x * mP3 );
00133 else if ( x < 1.0f ) return mP0 + x * x * ( mP2 + x * mP3 );
00134 else if ( x < 2.0f ) return mQ0 + x * ( mQ1 + x * ( mQ2 + x * mQ3 ) );
00135 return 0.0f;
00136 }
00137
00138 private:
00139 float mQ0, mQ1, mQ2, mQ3;
00140 float mP0, mP2, mP3;
00141 };
00142
00143
00144 class FilterSincBlackman : public FilterBase {
00145 public:
00146 FilterSincBlackman( float aSupport = 4.0f ) : FilterBase( aSupport ) {}
00147
00148 virtual float operator()( float x ) const {
00149 float v( ( x == 0.0f ) ? 1.0f : math<float>::sin( 3.14159265358979323846f * x ) / ( 3.14159265358979323846f * x ) );
00150
00151 x /= mSupport;
00152 return v * ( 0.42f + 0.50f * math<float>::cos( 3.14159265358979323846f * x ) + 0.08f * math<float>::cos( 6.2831853071795862f * x ) );
00153 }
00154 };
00155
00156
00157 class FilterGaussian : public FilterBase {
00158 public:
00159 FilterGaussian( float aSupport = 1.25f ) : FilterBase( aSupport ) {}
00160
00161 virtual float operator()( float x ) const {
00162 return ( math<float>::exp( -2.0f * x * x ) * math<float>::sqrt( 2.0f / 3.14159265358979323846f ) );
00163 }
00164 };
00165
00166 #if ! defined( CINDER_COCOA_TOUCH )
00167 class FilterBesselBlackman : public FilterBase {
00168 public:
00169 FilterBesselBlackman( float aSupport = 3.2383f ) : FilterBase( aSupport ) {}
00170
00171 virtual float operator()( float x ) const {
00172 #if defined (CINDER_MSW)
00173
00174 float v( ( x == 0.0f ) ? ( 3.14159265358979323846f / 4.0f ) : static_cast<float>( _j1( 3.14159265358979323846f * x ) ) / ( 2.0f * x ) );
00175 #else
00176 float v( ( x == 0.0f ) ? ( 3.14159265358979323846f / 4.0f ) : static_cast<float>( j1( 3.14159265358979323846f * x ) ) / ( 2.0f * x ) );
00177 #endif
00178
00179 x /= mSupport;
00180 return v * ( 0.42f + 0.50f * math<float>::cos( 3.14159265358979323846f * x ) + 0.08f * math<float>::cos( 6.2831853071795862f * x ) );
00181 }
00182 };
00183 #endif
00184
00185 }