17 #ifndef __itkBSplineKernelFunction2_h
18 #define __itkBSplineKernelFunction2_h
20 #include "itkKernelFunction.h"
21 #include "vnl/vnl_math.h"
41 template <
unsigned int VSplineOrder = 3>
57 itkStaticConstMacro( SplineOrder,
unsigned int, VSplineOrder );
60 typedef FixedArray<
double,
64 inline double Evaluate(
const double & u )
const
66 return this->Evaluate( Dispatch<VSplineOrder>(), u );
74 this->Evaluate( Dispatch<VSplineOrder>(), u, weights );
81 void PrintSelf( std::ostream & os, Indent indent )
const
83 Superclass::PrintSelf( os, indent );
84 os << indent <<
"Spline Order: " << SplineOrder << std::endl;
89 void operator=(
const Self&);
92 struct DispatchBase {};
93 template<
unsigned int>
94 struct Dispatch : DispatchBase {};
101 inline double Evaluate(
const Dispatch<0> &,
const double & u )
const
103 double absValue = vnl_math_abs( u );
105 if ( absValue < 0.5 )
return 1.0;
106 else if ( absValue == 0.5 )
return 0.5;
111 inline double Evaluate(
const Dispatch<1> &,
const double & u )
const
113 double absValue = vnl_math_abs( u );
115 if ( absValue < 1.0 )
return 1.0 - absValue;
120 inline double Evaluate(
const Dispatch<2> &,
const double & u )
const
122 double absValue = vnl_math_abs( u );
124 if ( absValue < 0.5 )
126 return 0.75 - vnl_math_sqr( absValue );
128 else if ( absValue < 1.5 )
130 return ( 9.0 - 12.0 * absValue + 4.0 * vnl_math_sqr( absValue ) ) / 8.0;
136 inline double Evaluate(
const Dispatch<3> &,
const double & u )
const
138 double absValue = vnl_math_abs( u );
139 double sqrValue = vnl_math_sqr( u );
141 if ( absValue < 1.0 )
143 return ( 4.0 - 6.0 * sqrValue + 3.0 * sqrValue * absValue ) / 6.0;
145 else if ( absValue < 2.0 )
147 return ( 8.0 - 12.0 * absValue + 6.0 * sqrValue - sqrValue * absValue ) / 6.0;
153 inline double Evaluate(
const DispatchBase &,
const double & )
const
155 itkExceptionMacro( <<
"Evaluate not implemented for spline order "
165 inline void Evaluate(
const Dispatch<0> &,
const double & u,
168 if ( u < 0.5 ) weights[ 0 ] = 1.0;
169 else weights[ 0 ] = 0.5;
173 inline void Evaluate(
const Dispatch<1> &,
const double & u,
176 weights[ 0 ] = 1.0 - u;
177 weights[ 1 ] = u - 1.0;
181 inline void Evaluate(
const Dispatch<2> &,
const double & u,
184 const double uu = vnl_math_sqr( u );
186 weights[ 0 ] = ( 9.0 - 12.0 * u + 4.0 * uu ) / 8.0;
187 weights[ 1 ] = -0.25 + 2.0 * u - uu;
188 weights[ 2 ] = ( 1.0 - 4.0 * u + 4.0 * uu ) / 8.0;
192 inline void Evaluate (
const Dispatch<3> &,
const double & u,
195 const double uu = vnl_math_sqr( u );
196 const double uuu = uu * u;
198 weights[ 0 ] = ( 8.0 - 12 * u + 6.0 * uu - uuu ) / 6.0;
199 weights[ 1 ] = ( -5.0 + 21.0 * u - 15.0 * uu + 3.0 * uuu ) / 6.0;
200 weights[ 2 ] = ( 4.0 - 12.0 * u + 12.0 * uu - 3.0 * uuu ) / 6.0;
201 weights[ 3 ] = ( -1.0 + 3.0 * u - 3.0 * uu + uuu ) / 6.0;
205 inline double Evaluate(
const DispatchBase &,
const double &,
208 itkExceptionMacro( <<
"Evaluate not implemented for spline order "