10#ifndef MATH_BSPLINE_HEADER
11#define MATH_BSPLINE_HEADER
35template <
class V,
class T =
float>
46 bool empty (
void)
const;
49 void set_degree (
int degree);
51 int get_degree (
void)
const;
54 void reserve (std::size_t n_points);
57 void add_point (V
const& p);
59 void add_knot (T
const& t);
61 void uniform_knots (T
const& min, T
const& max);
63 void scale_knots (T
const& min, T
const& max);
71 V evaluate (T
const& t)
const;
78 T deboor (
int i,
int k, T
const& x)
const;
92template <
class V,
class T>
99template <
class V,
class T>
103 return this->points.empty();
106template <
class V,
class T>
113template <
class V,
class T>
120template <
class V,
class T>
124 this->points.reserve(n_points);
125 this->knots.reserve(n_points + n + 1);
128template <
class V,
class T>
132 this->points.push_back(p);
135template <
class V,
class T>
139 this->knots.push_back(t);
142template <
class V,
class T>
147 int n_knots = this->points.size() + this->n + 1;
148 int segments = this->points.size() - this->n;
150 this->knots.reserve(n_knots);
152 for (
int i = 0; i < this->n; ++i)
153 this->knots.push_back(
min);
154 for (
int i = 0; i < segments + 1; ++i)
155 this->knots.push_back(
min + T(i) * width / T(segments));
156 for (
int i = 0; i < this->n - 1; ++i)
157 this->knots.push_back(
max);
159 this->knots.push_back(
max + T(1));
162 std::cout <<
"Made knots: ";
163 for (std::size_t i = 0; i < this->knots.size(); ++i)
164 std::cout << this->knots[i] <<
" ";
165 std::cout << std::endl;
170template <
class V,
class T>
174 T
first = this->knots[this->n];
175 T
const& last = this->knots[this->knots.size() - this->n - 1];
177 for (std::size_t i = 0; i < this->knots.size(); ++i)
178 this->knots[i] = (this->knots[i] -
first) * scale;
181template <
class V,
class T>
188template <
class V,
class T>
195template <
class V,
class T>
200 V p = this->points[0] * this->deboor(0, this->n, t);
201 for (std::size_t i = 1; i < this->points.size(); ++i)
202 p += this->points[i] * this->deboor(i, this->n, t);
206template <
class V,
class T>
213 return (x >= this->knots[i] && x < this->knots[i+1]) ? T(1) : T(0);
216 float d1 = this->knots[i+k] - this->knots[i];
217 float d2 = this->knots[i+k+1] - this->knots[i+1];
218 T v1 = d1 > T(0) ? (x - this->knots[i]) / d1 : T(0);
219 T v2 = d2 > T(0) ? (this->knots[i+k+1] - x) / d2 : T(0);
220 return v1 * deboor(i, k-1, x) + v2 * deboor(i+1, k-1, x);
223template <
class V,
class T>
227 for (std::size_t i = 0; i < points.size(); ++i)
228 points[i] = transf.
mult(points[i], 1.0f);
Implementation of non-uniform B-Spline curves according to.
void scale_knots(T const &min, T const &max)
Scales the knots such that evaluation is valid in [min, max].
void set_degree(int degree)
Sets the degree of spline segments.
void transform(math::Matrix4f const &transf)
Transforms the B-Spline.
void add_point(V const &p)
Adds a point to the control point vector.
std::vector< T > KnotVector
void reserve(std::size_t n_points)
Reserves space for points and the knot vector.
bool empty(void) const
Returns whether there are no points in this spline.
void uniform_knots(T const &min, T const &max)
Initializes the knot vector to be uniform.
PointVector const & get_points(void) const
Returns the point vector.
V evaluate(T const &t) const
Evalutes the B-Spline.
std::vector< V > PointVector
void add_knot(T const &t)
Adds a knot to the knot vector.
KnotVector const & get_knots(void) const
Returns the knot vector.
int get_degree(void) const
Returns the degree of the spline segments.
Matrix class for arbitrary dimensions and types.
Matrix< T, N, U > mult(Matrix< T, M, U > const &rhs) const
Matrix with matrix multiplication.
#define MATH_NAMESPACE_BEGIN
#define MATH_NAMESPACE_END
T const & max(T const &a, T const &b, T const &c)
Returns the maximum value of three arguments.
T const & min(T const &a, T const &b, T const &c)
Returns the minimum value of three arguments.