Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_SPLINE_SPLINE_COMPUTE_BASIS_H
00002 #define OPENTISSUE_CORE_SPLINE_SPLINE_COMPUTE_BASIS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_value_traits.h>
00013
00014 #include <stdexcept>
00015
00016 namespace OpenTissue
00017 {
00018 namespace spline
00019 {
00020 namespace detail
00021 {
00038 template<typename knot_container>
00039 inline typename knot_container::value_type compute_basis(
00040 int const & i
00041 , int const & k
00042 , typename knot_container::value_type const & u
00043 , knot_container const & U
00044 )
00045 {
00046 using std::fabs;
00047
00048 typedef typename knot_container::value_type T;
00049 typedef OpenTissue::math::ValueTraits<T> value_traits;
00050
00051 if(k<1)
00052 throw std::invalid_argument("order must be greater than zero");
00053
00054 if(i<0)
00055 throw std::invalid_argument("basis function index must be non-negative");
00056
00057 if( 0 >= (i + k - U.size()) )
00058 throw std::invalid_argument("No such basis function can exist");
00059
00060 if(k==1)
00061 {
00062 int const m = U.size() - 1;
00063 int const n = m - k;
00064
00065
00066 if(u==U[i+1] && U[i+1]==U[n+k])
00067 return value_traits::one();
00068
00069 if((U[i] <= u) && (u < U[i+1]))
00070 {
00071 return value_traits::one();
00072 }
00073 else
00074 {
00075 return value_traits::zero();
00076 }
00077 }
00078 else
00079 {
00080 T a = U[i+k-1] - U[i];
00081 if( fabs(a) > value_traits::zero() )
00082 {
00083 T tmp = compute_basis(i, k-1, u, U);
00084
00085 a = ((u-U[i])*tmp)/a;
00086 }
00087
00088 T b = U[i+k]-U[i+1];
00089 if( fabs(b) > value_traits::zero() )
00090 {
00091 T tmp = compute_basis(i+1,k-1,u, U);
00092
00093 b = ((U[i+k]-u)*tmp)/b;
00094 }
00095
00096 return a + b;
00097 }
00098 }
00099
00100 }
00101 }
00102 }
00103
00104
00105 #endif