PeriodicBspline.hpp

00001 // This file is part of the imaging2 class library.
00002 //
00003 // University of Innsbruck, Infmath Imaging, 2009.
00004 // http://infmath.uibk.ac.at
00005 //
00006 // All rights reserved.
00007 
00008 
00009 #ifndef PERIODICBSPLINE_H
00010 #define PERIODICBSPLINE_H
00011 
00012 
00013 #include <spline/Bspline.hpp>
00014 
00015 namespace imaging
00016 {
00026   template <class DATA_t>
00027   class PeriodicBspline : Bspline<DATA_t>
00028   {
00029     float_t transform_parameter(float_t t) const
00030     {
00031       // scale to [0, 1]
00032       float_t transformed_t = ( t - first_knot() ) / ( last_knot() - first_knot() );
00033       
00034       // move to [0, 1]
00035       transformed_t = transformed_t - floor(transformed_t);
00036       
00037       //rescale to orginal domain
00038       return transformed_t * ( last_knot() - first_knot() ) + knot(0);
00039     }
00040     
00041   public:
00042     PeriodicBspline() : Bspline<DATA_t>() {}
00043 
00045     PeriodicBspline(const PeriodicBspline & source) : Bspline<DATA_t>(source) {}
00046 
00048     PeriodicBspline(size_t spline_order, size_t n_coefficients)
00049     { resize(spline_order, n_coefficients); }
00050 
00052     const PeriodicBspline & operator=(const PeriodicBspline & rhs)
00053     { Bspline<DATA_t>::operator=(rhs); return *this; }
00054 
00055     size_t spline_order() const { return Bspline<DATA_t>::spline_order(); }
00056     float_t knot(size_t i) const { return Bspline<DATA_t>::knot(i + Bspline<DATA_t>::spline_order() - 1); }
00057 
00058     float_t first_knot() const { return Bspline<DATA_t>::first_knot(); }
00059     float_t last_knot() const { return Bspline<DATA_t>::last_knot(); }
00060 
00061     void set_knot(size_t i, float_t value)
00062     {
00063       Bspline<DATA_t>::set_knot(i + Bspline<DATA_t>::spline_order() - 1, value);
00064 
00065       for(size_t j = n_knots(); j < n_knots() + Bspline<DATA_t>::spline_order() - 1; ++j)
00066         Bspline<DATA_t>::set_knot(j + Bspline<DATA_t>::spline_order() - 1, Bspline<DATA_t>::knot(j - 1 + Bspline<DATA_t>::spline_order() - 1) +
00067                                         ( knot(j - n_knots() + 1) - knot(j - n_knots()) ) );
00068 
00069       for(size_t j = 1; j < Bspline<DATA_t>::spline_order(); ++j)
00070         Bspline<DATA_t>::set_knot(Bspline<DATA_t>::spline_order() - 1 - j, Bspline<DATA_t>::knot(Bspline<DATA_t>::spline_order() - 1 - j + 1) -
00071                                         ( knot(n_knots() - j) - knot(n_knots() - j - 1) ) );
00072     }
00073 
00074     void set_coefficient(size_t i, const DATA_t & value)
00075     {
00076       if( i + Bspline<DATA_t>::spline_order() > n_coefficients() )
00077         Bspline<DATA_t>::set_coefficient(i + Bspline<DATA_t>::spline_order() - 1 - n_coefficients(), value);
00078 
00079       Bspline<DATA_t>::set_coefficient(i + Bspline<DATA_t>::spline_order() - 1, value);
00080     }
00081 
00082     const DATA_t & coefficient(size_t i) const { return Bspline<DATA_t>::coefficient(i + Bspline<DATA_t>::spline_order() - 1); }
00083 
00084     void resize(size_t spline_order, size_t n_coefficients)
00085     {
00086       if(n_coefficients + 1 < spline_order)
00087         throw Exception("Exception: Too little coefficients in PeriodicBspline::resize().");
00088 
00089       Bspline<DATA_t>::resize(spline_order, n_coefficients + spline_order - 1);
00090     }
00091 
00092     size_t n_coefficients() const
00093     { return Bspline<DATA_t>::n_coefficients() - Bspline<DATA_t>::spline_order() + 1; }
00094 
00096     size_t n_knots() const
00097       { return n_coefficients() + 1; }
00098 
00099     DATA_t operator()(float_t t, DATA_t & first_derivative) const
00100       { DATA_t temp; return operator()(t, first_derivative, temp); }
00101 
00102     DATA_t operator()(float_t t) const
00103       { DATA_t temp_1, temp_2; return operator()(t, temp_1, temp_2); }
00104 
00105     DATA_t operator()(float_t t, DATA_t & first_derivative, DATA_t & second_derivative) const
00106     {
00107       float_t transformed_t = transform_parameter(t);
00108 
00109       DATA_t value = Bspline<DATA_t>::operator()(transformed_t, first_derivative, second_derivative);
00110 
00111       return value;
00112     }
00113 
00114     void regular_knots(float_t x_0, float_t x_1)
00115     {
00116       float_t offset = (x_1 - x_0) / float_t(n_coefficients());
00117       float_t x = x_0;
00118       set_knot(0, x);
00119       for(size_t i = 1; i < n_knots(); ++i)
00120       {
00121         x += offset;
00122         set_knot(i, x);
00123       }
00124     }
00125     
00127     bool is_in_basis_spline_support(size_t i, float_t t) const
00128     {
00129       float_t transformed_t = transform_parameter(t);
00130       size_t looped_right_knot_index = ( i + spline_order() ) % n_knots();
00131       return t >= max(knot(i), looped_right_knot_index) && t <= knot(i + spline_order());
00132     }
00133     
00134   };
00135 }
00136 
00137 #endif

Generated on Tue Feb 10 10:01:31 2009 for imaging2 by  doxygen 1.5.5