1 #ifndef VTESTBED_GEOMETRY_CUBIC_SPLINE_HH     2 #define VTESTBED_GEOMETRY_CUBIC_SPLINE_HH     6 #include <vtestbed/base/blitz.hh>     7 #include <vtestbed/geometry/curve_segments.hh>     8 #include <vtestbed/geometry/math.hh>    14         template <
class V, 
class T>
    16         difference(
const V& a, 
const V& b, T delta) {
    26         difference(
const V& a, 
const V& b) {
    35         template <
class T, 
int N=3>
    39             using value_type = Vertex<T,N>;
    40             using reference = value_type&;
    41             using const_reference = 
const value_type&;
    43             using size_type = size_t;
    55             _points(values), _segments(values) {
    56                 const auto n = values.size();
    57                 if (n <= 1) { 
return; }
    58                 const auto& p = this->_points;
    59                 auto& dt = this->_segments;
    60                 auto& m = this->_derivatives;
    62                 m.emplace_back(difference(p[1],p[0],dt[0]));
    63                 for (
size_t i=1; i<n-1; ++i) {
    64                     m.emplace_back(T{0.5}*(
    65                         difference(p[i+1],p[i],dt[i]) +
    66                         difference(p[i],p[i-1],dt[i-1])
    69                 m.emplace_back(difference(p[n-1],p[n-2],dt[n-2]));
    74             operator()(T t)
 const {
    75                 const auto& segments = this->_segments;
    76                 const auto& points = this->_points;
    77                 const auto& derivatives = this->_derivatives;
    78                 if (points.size() == 1) {
    79                     return points.front();
    82                 segments.locate(t, i0);
    83                 if (i0 == segments.size()) {
    87                 const auto& p0 = points[i0];
    88                 const auto& p1 = points[i1];
    89                 const auto& m0 = derivatives[i0];
    90                 const auto& m1 = derivatives[i1];
    94                 T h00 = (T{1} + T{2}*t)*t1;
    96                 T h01 = t2*(T{3} - T{2}*t);
    97                 T h11 = t2*(t - T{1});
    98                 return h00*p0 + h10*m0 + h01*p1 + h11*m1;
   101             inline const_reference
   102             front() 
const noexcept {
   103                 return this->_points.front();
   106             inline const_reference
   107             back() 
const noexcept {
   108                 return this->_points.back();
   113                 return this->_points.size();
   117             derivatives()
 const {
   118                 return this->_derivatives;
   123                 return this->_segments;
   128                 return this->_segments;
   132             range(T min, T max) {
   133                 this->_segments.range(min, max);
   138                 return this->_segments.length();
   142             smooth_left(value_type p_left) {
   143                 auto& m = this->_derivatives;
   144                 const auto& p = this->_points;
   145                 m[0] = T{0.5}*(difference(p[1],p[0]) + difference(p[0], p_left));
   149             smooth_right(value_type p_right) {
   150                 auto& m = this->_derivatives;
   151                 const auto& p = this->_points;
   152                 const auto n = p.size();
   153                 m[n-1] = T{0.5}*(difference(p[n-1],p[n-2]) + difference(p[n-1], p_right));
   162 #endif // vim:filetype=cpp