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