Guest User

Untitled

a guest
May 21st, 2018
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.78 KB | None | 0 0
  1. #pragma once
  2. #include <cgv/math/vec.h>
  3. #include <cgv/math/mat.h>
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10. template <typename T>
  11. struct bspline_curve
  12. {
  13.     //control points
  14.     cgv::math::mat<T> Q;
  15.     //degree of piecewise polynomials
  16.     unsigned g;
  17.     //knot vector
  18.     cgv::math::vec<T> U;
  19.    
  20.  
  21.     bspline_curve(unsigned degree,const cgv::math::mat<T>& control_points,
  22.         const cgv::math::mat<T>& knots)
  23.     {
  24.         Q = control_points;
  25.         U = knots;
  26.         g = degree;
  27.    
  28.     }
  29.  
  30.     ///returns the number of control points
  31.     unsigned num_control_points()
  32.     {
  33.         return Q.ncols();
  34.     }
  35.  
  36.     bspline_curve(unsigned degree,const cgv::math::mat<T>& control_points, bool interpolate_endpoints=true)
  37.     {
  38.         Q = control_points;
  39.         g = degree;
  40.        
  41.         unsigned n =num_control_points();
  42.        
  43.         U.resize(n+1+g);
  44.  
  45.         if(interpolate_endpoints)
  46.         {
  47.             //student begin
  48.             U.resize(n+1+g*2);
  49.             for(unsigned i=0; i<g+1;i++) {
  50.                 U(i) = 0;
  51.             }
  52.             for(unsigned i=g+1; i< g+1+n; i++) {
  53.                 U(i+g) = i;
  54.             }
  55.             for(unsigned i=0; i<g; i++) {
  56.                 U(i+g+1+n) = g;
  57.             }
  58.             //student end
  59.  
  60.         }
  61.         else
  62.         {
  63.             for(unsigned i =0; i < num_control_points()+g+1;i++)
  64.             {
  65.                 U(i)=i;
  66.             }
  67.            
  68.         }
  69.  
  70.        
  71.        
  72.                
  73.     }
  74.  
  75.    
  76.  
  77.  
  78.     //i... zero-based index of control point
  79.     //g... degree of spline
  80.     //t... position to evaluate
  81.     //the knot vector is stored in U
  82.     T cox_de_boor(int i, int g, const T& t)
  83.     {
  84.         //student begin
  85.         if(g == 0) {
  86.             if(U[i] <= g && g < U[i + 1] && U[i] < U[i + 1]) {
  87.                 return 1;
  88.             }
  89.             return 0;
  90.         }
  91.         return cox_de_boor(i, g - 1, t) * (t - U[i]) / (U[i + g] - U[i])
  92.             + cox_de_boor(i + 1, g - 1, t) * (U[i + 1 + g] - t)/(U[i + 1 + g] - U[i + 1]);
  93.         //student end
  94.     }
  95.  
  96.  
  97.  
  98.  
  99.     //sample basis at sample position t
  100.     cgv::math::vec<T> sample_basis(const T& t)
  101.     {
  102.         cgv::math::vec<T> v(num_control_points());
  103.         for(unsigned i = 0; i < num_control_points(); i++)
  104.             v(i) = cox_de_boor(i,g,t);
  105.        
  106.        
  107.         return v;
  108.     }
  109.  
  110.     //sample basis at multiple sample positions t
  111.     cgv::math::mat<T> sample_basis(const cgv::math::vec<T>& ts)
  112.     {
  113.         cgv::math::mat<T> vs(num_control_points(),ts.size());
  114.  
  115.         for(unsigned j = 0; j < ts.size(); j++)
  116.             vs.set_col(j,sample_basis(ts(j)));
  117.         return vs;
  118.     }
  119.  
  120.     //returns a curve point at sample position t
  121.     cgv::math::vec<T> sample_curve(const T& t)
  122.     {  
  123.         return Q*sample_basis(t);
  124.     }
  125.  
  126.     //returns multiple curve points at sample positions t
  127.     cgv::math::mat<T> sample_curve(const cgv::math::vec<T>& ts)
  128.     {
  129.         return Q*sample_basis(ts);
  130.     }
  131.  
  132.    
  133.     /// helper method to calculate the affine combination of x and y
  134.     static cgv::math::vec<T> aff(const T& t,const cgv::math::vec<T>& x,const cgv::math::vec<T>& y,
  135.         const T& a,const T& b)
  136.     {
  137.         if (a==b)
  138.             return x;
  139.        
  140.         return  ( 1.0 / (b-a) ) * ( (b-t)*x + (t-a)*y);
  141.     }
  142.  
  143.     ///r..recursion depth,
  144.     ///t..sample position,
  145.     ///i..control point index
  146.     cgv::math::vec<T> de_boor(int r,const T& t, int i)
  147.     {
  148.         //student begin
  149.         if(r==0) {
  150.             return Q.col(i);
  151.         }
  152.         T a = (t - U[i]) / (U[i+num_control_points()+1-g] - U[i]);
  153.         return (1-a)*de_boor(r-1, t, i) + a*de_boor(r-1, t, i+1);
  154.         //student end
  155.     }
  156.  
  157.     cgv::math::vec<T> sample_curve_de_boor(const T& t)
  158.     {
  159.         assert (g < num_control_points() );
  160.    
  161.         int i = 0;
  162.         while(t >= U(i+1)  && i+1 < U.size())
  163.             i++;
  164.        
  165.         return (de_boor(g,t, i-g));
  166.            
  167.        
  168.     }
  169.  
  170.    
  171.     ///ts..sample positions
  172.     cgv::math::mat<T> sample_curve_de_boor(const cgv::math::vec<T>& ts)
  173.     {
  174.         cgv::math::mat<T> S(Q.nrows(),ts.size());
  175.         for(unsigned i = 0; i < ts.size();i++)
  176.             S.set_col(i,sample_curve_de_boor(ts(i)));
  177.        
  178.         return S;
  179.     }
  180.  
  181.     //creates a vector of sample positions containing num_samples values
  182.     cgv::math::vec<T> create_samples(unsigned num_samples)
  183.     {
  184.        
  185.         T start = U(g);
  186.         T end = U(U.size()-1-g)-0.00001;
  187.         //assert(start < end);
  188.        
  189.  
  190.         return cgv::math::lin_space<double>(start, end, num_samples);
  191.     }
  192.  
  193. };
Add Comment
Please, Sign In to add comment