1 /**************************************************************************/ 2 /* Copyright 2012 Tim Day */ 3 /* */ 4 /* This file is part of Evolvotron */ 5 /* */ 6 /* Evolvotron is free software: you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation, either version 3 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* Evolvotron is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14 /* GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with Evolvotron. If not, see <http://www.gnu.org/licenses/>. */ 18 /**************************************************************************/ 19 20 /*! \file 21 \brief Interfaces and implementation for specific Function classes. 22 As much as possible of the implementation should be pushed into the FunctionBoilerplate template. 23 */ 24 25 #ifndef _functions_filter_h_ 26 #define _functions_filter_h_ 27 28 #include "common.h" 29 30 #include "function_boilerplate.h" 31 32 //------------------------------------------------------------------------------------------ 33 34 FUNCTION_BEGIN(FunctionFilter2D,2,1,false,0) 35 36 //! Evaluate function. evaluate(const XYZ & p)37 virtual const XYZ evaluate(const XYZ& p) const 38 { 39 return 40 arg(0)(p) 41 -( 42 arg(0)(p+XYZ(param(0),0.0,0.0)) 43 +arg(0)(p+XYZ(-param(0),0.0,0.0)) 44 +arg(0)(p+XYZ(0.0,param(1),0.0)) 45 +arg(0)(p+XYZ(0.0,-param(1),0.0)) 46 )/4.0; 47 } 48 49 FUNCTION_END(FunctionFilter2D) 50 51 //------------------------------------------------------------------------------------------ 52 53 FUNCTION_BEGIN(FunctionFilter3D,3,1,false,0) 54 55 //! Evaluate function. evaluate(const XYZ & p)56 virtual const XYZ evaluate(const XYZ& p) const 57 { 58 return 59 arg(0)(p) 60 -( 61 arg(0)(p+XYZ(param(0),0.0,0.0)) 62 +arg(0)(p+XYZ(-param(0),0.0,0.0)) 63 +arg(0)(p+XYZ(0.0,param(1),0.0)) 64 +arg(0)(p+XYZ(0.0,-param(1),0.0)) 65 +arg(0)(p+XYZ(0.0,0.0,param(2))) 66 +arg(0)(p+XYZ(0.0,0.0,-param(2))) 67 )/6.0; 68 } 69 70 FUNCTION_END(FunctionFilter3D) 71 72 //------------------------------------------------------------------------------------------ 73 74 //! Function returning average value of evenly spaced samples between two points 75 FUNCTION_BEGIN(FunctionAverageSamples,3,1,true,FnIterative) 76 77 //! Evaluate function. evaluate(const XYZ & p)78 virtual const XYZ evaluate(const XYZ& p) const 79 { 80 const XYZ baseline(param(0),param(1),param(2)); 81 82 XYZ p0; 83 XYZ p1; 84 XYZ delta; 85 86 if (iterations()==1) 87 { 88 p0=p; 89 p1=p; 90 delta=XYZ(0.0,0.0,0.0); 91 } 92 else 93 { 94 // In the case of two iterations the samples will be at p0 and p1 95 p0=p-baseline; 96 p1=p+baseline; 97 delta=(p1-p0)/(iterations()-1); 98 } 99 100 XYZ ret(0.0,0.0,0.0); 101 XYZ ps=p0; 102 103 for (uint i=0;i<iterations();i++) 104 { 105 ret+=arg(0)(ps); 106 ps+=delta; 107 } 108 ret/=iterations(); 109 return ret; 110 } 111 112 FUNCTION_END(FunctionAverageSamples) 113 114 //------------------------------------------------------------------------------------------ 115 116 //! Similar to average samples except one end has a higher weighting 117 FUNCTION_BEGIN(FunctionStreak,3,1,true,FnIterative) 118 119 //! Evaluate function. evaluate(const XYZ & p)120 virtual const XYZ evaluate(const XYZ& p) const 121 { 122 const XYZ baseline(param(0),param(1),param(2)); 123 124 XYZ p0; 125 XYZ p1; 126 XYZ delta; 127 128 if (iterations()==1) 129 { 130 p0=p; 131 p1=p; 132 delta=XYZ(0.0,0.0,0.0); 133 } 134 else 135 { 136 p0=p; 137 p1=p+baseline; 138 delta=(p1-p0)/(iterations()-1); 139 } 140 141 XYZ ret(0.0,0.0,0.0); 142 XYZ ps=p0; 143 real w=0.0; 144 145 for (uint i=0;i<iterations();i++) 146 { 147 const real k=1.0-static_cast<real>(i)/iterations(); 148 ret+=k*arg(0)(ps); 149 w+=k; 150 ps+=delta; 151 } 152 ret/=w; 153 return ret; 154 } 155 156 FUNCTION_END(FunctionStreak) 157 158 //------------------------------------------------------------------------------------------ 159 160 //! Average of samples around a ring 161 FUNCTION_BEGIN(FunctionAverageRing,1,1,true,FnIterative) 162 163 //! Evaluate function. evaluate(const XYZ & p)164 virtual const XYZ evaluate(const XYZ& p) const 165 { 166 if (iterations()==1) return arg(0)(p); 167 168 const real da=2.0*M_PI/iterations(); 169 XYZ ret(0.0,0.0,0.0); 170 for (uint i=0;i<iterations();i++) 171 { 172 const real a=i*da; 173 const XYZ delta(param(0)*cos(a),param(0)*sin(a),0.0); 174 ret+=arg(0)(p+delta); 175 } 176 return ret/iterations(); 177 } 178 179 FUNCTION_END(FunctionAverageRing) 180 181 //------------------------------------------------------------------------------------------ 182 183 //! Like FunctionAverageRing but subtract off the centre value 184 FUNCTION_BEGIN(FunctionFilterRing,1,1,true,FnIterative) 185 186 //! Evaluate function. evaluate(const XYZ & p)187 virtual const XYZ evaluate(const XYZ& p) const 188 { 189 if (iterations()==1) return XYZ(0.0,0.0,0.0); 190 191 const real da=2.0*M_PI/iterations(); 192 XYZ ret(0.0,0.0,0.0); 193 for (uint i=0;i<iterations();i++) 194 { 195 const real a=i*da; 196 const XYZ delta(param(0)*cos(a),param(0)*sin(a),0.0); 197 ret+=arg(0)(p+delta); 198 } 199 return ret/iterations()-arg(0)(p); 200 } 201 202 FUNCTION_END(FunctionFilterRing) 203 204 //------------------------------------------------------------------------------------------ 205 206 //! Function similar to FunctionAverageSamples but doing convolution 207 FUNCTION_BEGIN(FunctionConvolveSamples,3,2,true,FnIterative) 208 209 //! Evaluate function. evaluate(const XYZ & p)210 virtual const XYZ evaluate(const XYZ& p) const 211 { 212 const XYZ baseline(param(0),param(1),param(2)); 213 214 XYZ p0; 215 XYZ p1; 216 XYZ delta; 217 218 if (iterations()==1) 219 { 220 p0=p; 221 p1=p; 222 delta=XYZ(0.0,0.0,0.0); 223 } 224 else 225 { 226 p0=p-baseline; 227 p1=p+baseline; 228 delta=(p1-p0)/(iterations()-1); 229 } 230 231 XYZ ret(0.0,0.0,0.0); 232 XYZ pd(0.0,0.0,0.0); 233 234 for (uint i=0;i<iterations();i++) 235 { 236 //! \todo Hmmm.. this is cross product, not inner product 237 ret+=(arg(0)(p+pd)*arg(1)(pd)); 238 pd+=delta; 239 } 240 ret/=iterations(); 241 return ret; 242 } 243 244 FUNCTION_END(FunctionConvolveSamples) 245 246 //------------------------------------------------------------------------------------------ 247 248 //! Function summing decreasing amounts of higher frequency versions of image 249 FUNCTION_BEGIN(FunctionAccumulateOctaves,0,1,true,FnIterative) 250 251 //! Evaluate function. evaluate(const XYZ & p)252 virtual const XYZ evaluate(const XYZ& p) const 253 { 254 XYZ ret(0.0,0.0,0.0); 255 real k=0.0; 256 for (uint i=0;i<iterations();i++) 257 { 258 const real scale=(1<<i); 259 const real iscale=1.0/scale; 260 ret+=iscale*(arg(0)(scale*p)); 261 k+=iscale; 262 } 263 ret/=k; 264 return ret; 265 } 266 267 FUNCTION_END(FunctionAccumulateOctaves) 268 269 //------------------------------------------------------------------------------------------ 270 271 #endif 272 273