Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_SPLINE_SPLINE_INSERT_KNOT
00002 #define OPENTISSUE_CORE_SPLINE_SPLINE_INSERT_KNOT
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/spline/spline_compute_knot_span.h>
00013
00014 namespace OpenTissue
00015 {
00016 namespace spline
00017 {
00018 namespace detail
00019 {
00041 template<typename knot_container, typename point_container>
00042 inline void insert_knot(
00043 typename knot_container::value_type const & u
00044 , int k
00045 , knot_container & U
00046 , point_container & P
00047 )
00048 {
00049 typedef typename point_container::value_type V;
00050 typedef typename knot_container::value_type T;
00051
00052 if(k<=0)
00053 throw std::invalid_argument("the spline order must be one or more");
00054
00055 int i;
00056 int const m = U.size()-1;
00057 int const n = m-k;
00058 int const dim = P[0].size();
00059
00060 knot_container U_new(n+k+2);
00061 point_container P_new(n+2);
00062
00063 for(i = 0; i <(n+2); ++i )
00064 {
00065 P_new[i].resize(dim);
00066 }
00067
00068
00069
00070 int r = detail::compute_knot_span(u, k, U);
00071
00072
00073 for(i=0; i<(n+k+2); ++i)
00074 {
00075 if(i<=r)
00076 U_new[i] = U[i];
00077 else if(i>(r+1))
00078 U_new[i] = U[i-1];
00079 else
00080 U_new[r+1] = u;
00081 }
00082
00083
00084 V tmpA(dim);
00085 V tmpB(dim);
00086
00087 for(i=0;i<(n+2);++i)
00088 {
00089
00090 P_new[i].clear();
00091
00092 if(i<=(r-k+1))
00093 {
00094 P_new[i] = P[i];
00095 }
00096 else if(i>r){
00097 P_new[i] = P[i-1];
00098 }
00099 else
00100 {
00101
00102
00103
00104 T ai = (u - U[i])/(U[i+k-1]-U[i]);
00105
00106 tmpA = P[i-1]*(1-ai);
00107 tmpB = P[i] * ai;
00108 P_new[i] = tmpA;
00109 P_new[i] += tmpB;
00110 }
00111 }
00112
00113 U = U_new;
00114 P = P_new;
00115 }
00116
00117 }
00118
00119
00130 template<typename spline_type>
00131 inline void insert_knot( typename spline_type::knot_container::value_type const & u, spline_type & spline )
00132 {
00133 detail::insert_knot( u, spline.get_order(), spline.get_knot_container(), spline.get_control_container() );
00134 }
00135
00136
00137 }
00138 }
00139
00140
00141 #endif