contrib/rpl/rgrl/rgrl_spline.h
Go to the documentation of this file.
00001 #ifndef rgrl_spline_h_
00002 #define rgrl_spline_h_
00003 
00004 //: \file
00005 //  \author Lee, Ying-Lin (Bess)
00006 //  \date   Sep 2003
00007 //  \brief A class for dealing a uniform cubic B-spline up to 4D (a hypersurface in 4D).
00008 
00009 #include "rgrl_spline_sptr.h"
00010 #include "rgrl_object.h"
00011 
00012 #include <vcl_iosfwd.h>
00013 #include <vnl/vnl_matrix.h>
00014 #include <vnl/vnl_vector.h>
00015 
00016 //: A tensor-product B-spline in 4D can be written in
00017 //  \f[
00018 //      \mathbf{Q}_{ijk}(u,v,w) = \sum_{r=0}^{3} \sum_{s=0}^{3} \sum_{t=0}^{3}V_{i+r,j+s,k+t} b_r(u) b_s(v) b_t(w)
00019 //  \f]
00020 //  where
00021 // \verbatim
00022 // i=\ceil{x}-1,  i=\ceil{y}-1, i=\ceil{z}-1,
00023 // \endverbatim
00024 //  and \f$u=x-i\f$,\f$v=y-j\f$\f$w=z-k\f$ are local parameters ranging in $[0,1)$
00025 //  and
00026 //  \f[
00027 //    b_{3}(u) = \frac{1}{6}u^3
00028 //  \f]
00029 //  \f[
00030 //    b_{2}(u) = \frac{1}{6}(-3u^3+3u^2+3u+1)
00031 //  \f]
00032 //  \f[
00033 //    b_{1}(u) = \frac{1}{6}(3u^3-6u^2+4)
00034 //  \f]
00035 //  \f[
00036 //    b_{0}(u) = \frac{1}{6}(1-u)^3
00037 //  \f]
00038 //  or can be expressed in
00039 //  \f[
00040 //      \mathbf{Q}_(x,y,z)=
00041 //      \sum_{i=-1}^{m+1} \sum_{j=-1}^{n+1}  \sum_{k=-1}^{l+1}V_{ijk} B_i(x) B_j(y) B_k(z)
00042 //  \f]
00043 // The control vertex \f$V_{0,0,0}\f$ is located at \f$(0,0,0)\f$.
00044 
00045 class rgrl_spline
00046   : public rgrl_object
00047 {
00048  public:
00049   //: Constructor
00050   rgrl_spline( ) : rgrl_object() { }
00051   rgrl_spline( vnl_vector< unsigned > const& m );
00052   rgrl_spline( vnl_vector< unsigned > const& m, vnl_vector< double > const& c );
00053 
00054 //    rgrl_spline( vnl_vector<double> const& delta,
00055 //                 vnl_vector<double> const& x0,
00056 //                 vnl_vector<double> const& x1 );
00057 //    rgrl_spline( vnl_vector<int> const& m,
00058 //                    vnl_vector<double> const& delta,
00059 //                    vnl_vector<double> const& p0);
00060 //    rgrl_spline( vnl_vector<double> const& c,
00061 //                 vnl_vector<double> const& delta,
00062 //                 vnl_vector<double> const& x0,
00063 //                 vnl_vector<double> const& x1 );
00064 //    rgrl_spline( vnl_vector<double> const& c,
00065 //                    vnl_vector<int> const& m,
00066 //                    vnl_vector<double> const& delta,
00067 //                    vnl_vector<double> const& p0 );
00068 
00069   //: Destructor.
00070   ~rgrl_spline(){}
00071 
00072   //: Set controls points
00073   void set_control_points( vnl_vector<double> const& c ) ;
00074   vnl_vector< double > const& get_control_points() const { return c_; }
00075   vnl_vector< double > & get_control_points() { return c_; }
00076 
00077   //: The spline value
00078   //
00079   //  \f[ f(\overline{u},y,z) = \sum_{i=-1}^{m[0]_+1}
00080   //  \sum_{j=-1}^{m[1]_+1} \sum_{k=-1}^{m_[2]+1} V_{ijk} * B_i(x) *
00081   //  B_j(y) * B_k(z)\f]
00082   double f_x( vnl_vector<double> const& x ) const;
00083   vnl_vector< double > jacobian( vnl_vector< double > const& x ) const;
00084 
00085   //: The basis responses at \f$(x,y,z)\f$.
00086   //
00087   //  It returns a 1 by \f$(m_[0]+3)*(m_[1]+3)*(m_[2]+3)\f$ vector which contains
00088   //  [$B_{-1}(x)*B_{-1}(y)*B_{-1}(z)$,...,
00089   //  $B_{m_[0]+1}(x)B_{m_[1]+1}(y)B_{m_[2]+1}(z)$],
00090   //  in the same order as in c_
00091   void basis_response( vnl_vector<double> const& point, vnl_vector<double>& br ) const;
00092 
00093   void thin_plate_regularization( vnl_matrix<double>& regularization ) const;
00094 
00095   unsigned num_of_control_points( ) const { return c_.size(); }
00096 
00097   // for tester to access its private members
00098   friend class test_rgrl_spline;
00099 
00100   // for output
00101   friend vcl_ostream& operator<< (vcl_ostream& os, rgrl_spline const& spline );
00102 
00103   // for input
00104   friend vcl_istream& operator>> (vcl_istream& is, rgrl_spline& spline );
00105 
00106 
00107   //: Generate a refined B-spline that produces the same surface.
00108   rgrl_spline_sptr refinement( vnl_vector< unsigned > const& new_m ) const;
00109 
00110 //    //: True if the i-th control point has support on pt
00111 //    bool is_support( vnl_vector< double > const& pt, unsigned i );
00112 
00113   // Defines type-related functions
00114   rgrl_type_macro( rgrl_spline, rgrl_object );
00115 
00116  private:
00117 
00118   double element_1d_thin_plate( unsigned i, unsigned j ) const;
00119   double element_2d_thin_plate( unsigned i, unsigned j ) const;
00120   double element_3d_thin_plate( unsigned i, unsigned j ) const;
00121 
00122   typedef double (*func_type)( int i, double u );
00123   void basis_response_helper( vnl_vector<double> const& point, vnl_vector<double>& br, func_type func ) const;
00124 
00125   // The control vertices indices are from -1 to \f$m_[i]+1\f$.
00126   // The total number of control vertices in each dimension is \f$m_[i]+3\f$
00127   vnl_vector< unsigned > m_;
00128 
00129   // The control points in the order of
00130   // $c_{-1,-1,-1}$,..., $c_{m_[0]+1,-1,-1}$
00131   // $c_{-1,0, -1}$,..., $c_{m_[0]+1,0,-1}$,..., $c_{m_[0]+1,m_[1]+1,-1}$
00132   // ... $c_{m_[0]+1, m_[1]+1, m_[2]+1}$
00133   // Gehua:
00134   // In general The control point (i, j, k) is converted to
00135   // (i+1) + (m_[0]+3)(j+1) + (m_[0]+3)(m_[1]+3)(k+1)
00136   // i+1 is to shift the starting point from -1 to 0
00137   vnl_vector<double> c_;
00138 
00139 
00140 //    // to specify $\delta x$, $\delta y$, and $\delta z$ for uniform spline
00141 //    vnl_vector<double> delta_;
00142 //    vnl_vector<double> p0_;
00143 };
00144 
00145 #endif