Medusa  1.1
Coordinate Free Mehless Method implementation
cad_helpers.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_DOMAINS_CAD_HELPERS_HPP_
2 #define MEDUSA_BITS_DOMAINS_CAD_HELPERS_HPP_
3 
9 #include "cad_helpers_fwd.hpp"
11 #include <algorithm>
12 
13 namespace mm {
14 
15 namespace cad_helpers {
16 
17 template <typename scalar_t, int dim>
19  const Range<Vec<scalar_t, dim>>& control_points, const Range<scalar_t>& knots, int k) {
20  // Check for special cases.
21  if (t == *(knots.end() - 1)) {
22  return *(control_points.end() - 1);
23  } else if (t == *knots.begin()) {
24  return *control_points.begin();
25  }
26 
27  assert_msg(knots.size() >= k + p + 1 && k - p >= 0,
28  "Not enough knots or parameter not within range. Try padding the knot vector p times.");
29 
30  // De Boor's algorithm.
31  Range<Vec<scalar_t, dim>> d(control_points.begin() + (k - p), control_points.begin() + (k + 1));
32 
33  for (int r = 1; r < p + 1; r++) {
34  for (int j = p; j > r - 1; j--) {
35  scalar_t alpha = (t - knots[j + k - p]) / (knots[j + 1 + k - r] - knots[j + k - p]);
36  d[j] = (1.0 - alpha) * d[j - 1] + alpha * d[j];
37  }
38  }
39 
40  return d[p];
41 }
42 
43 template <typename scalar_t, int dim>
45  const Range<Vec<scalar_t, dim>>& control_points, const Range<scalar_t>& knots,
46  scalar_t epsilon) {
47  if (t > knots[knots.size() - 1] && abs(t - knots[knots.size() - 1]) < epsilon) {
48  t = knots[knots.size() - 1];
49  } else if (t < knots[0] && abs(t - knots[0]) < epsilon) {
50  t = knots[0];
51  }
52 
53  // Binary search for k.
54  int k = std::upper_bound(knots.begin(), knots.end(), t) - knots.begin();
55  k--;
56 
57  return evaluate_b_spline(t, p, control_points, knots, k);
58 }
59 
60 template <typename scalar_t, int dim>
61 void generate_b_spline_derivative(int p, const Range<Vec<scalar_t, dim>>& control_points,
62  const Range<scalar_t>& knots, Range<Vec<scalar_t, dim>>& der_control_points,
63  Range<scalar_t>& der_knots) {
64  generate_b_spline_derivative_control_points(p, control_points, knots, der_control_points);
65  generate_b_spline_derivative_knots(knots, der_knots);
66 }
67 
68 template <typename scalar_t, int dim>
70  const Range<Vec<scalar_t, dim>>& control_points, const Range<scalar_t>& knots,
71  Range<Vec<scalar_t, dim>>& der_control_points) {
72  // Derivative has one less control point.
73  der_control_points.resize(control_points.size() - 1);
74 
75  // Calculate control points.
76  for (int i = 0; i < control_points.size() - 1; i++) {
77  scalar_t temp = ((scalar_t)p) / (knots[i + p + 1] - knots[i + 1]);
78  for (int j =0; j < dim; j++) {
79  der_control_points[i](j) = temp * (control_points[i + 1](j) - control_points[i](j));
80  }
81  }
82 }
83 
84 template <typename scalar_t>
86  Range<scalar_t>& der_knots) {
87  // Derivative's order is one less than original order.
88  der_knots.resize(knots.size() - 2);
89 
90  // Calculate derivative knots.
91  for (int i = 0; i < der_knots.size(); i++) {
92  der_knots[i] = knots[i + 1];
93  }
94 }
95 
96 } // namespace cad_helpers
97 } // namespace mm
98 
99 #endif // MEDUSA_BITS_DOMAINS_CAD_HELPERS_HPP_
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
scalar_t
Scalar scalar_t
Type of the elements, alias of Scalar.
Definition: MatrixBaseAddons.hpp:16
mm::Vec
Eigen::Matrix< scalar_t, dim, 1, Eigen::ColMajor|Eigen::AutoAlign, dim, 1 > Vec
Fixed size vector type, representing a mathematical 1d/2d/3d vector.
Definition: Vec_fwd.hpp:31
mm::cad_helpers::generate_b_spline_derivative_control_points
void generate_b_spline_derivative_control_points(int p, const Range< Vec< scalar_t, dim >> &control_points, const Range< scalar_t > &knots, Range< Vec< scalar_t, dim >> &der_control_points)
Generate control points of a B-spline that is the first derivative of the inputed B-spline.
Definition: cad_helpers.hpp:69
dim
@ dim
Number of elements of this matrix.
Definition: MatrixBaseAddons.hpp:14
assert_msg
#define assert_msg(cond,...)
Assert with better error reporting.
Definition: assert.hpp:75
mm::cad_helpers::generate_b_spline_derivative
void generate_b_spline_derivative(int p, const Range< Vec< scalar_t, dim >> &control_points, const Range< scalar_t > &knots, Range< Vec< scalar_t, dim >> &der_control_points, Range< scalar_t > &der_knots)
Generate control points and knot vector of a B-spline that is the first derivative of the inputed B-s...
Definition: cad_helpers.hpp:61
mm::cad_helpers::generate_b_spline_derivative_knots
void generate_b_spline_derivative_knots(const Range< scalar_t > &knots, Range< scalar_t > &der_knots)
Generate knots of a B-spline that is the first derivative of the inputed B-spline.
Definition: cad_helpers.hpp:85
assert.hpp
mm::cad_helpers::evaluate_b_spline
Vec< scalar_t, dim > evaluate_b_spline(scalar_t t, int p, const Range< Vec< scalar_t, dim >> &control_points, const Range< scalar_t > &knots, int k)
Evaluate B-spline in one point using De Boor's algorithm - , where is the number of dimensions.
Definition: cad_helpers.hpp:18
mm::Range::size
int size() const
Returns number of elements.
Definition: Range_fwd.hpp:185
mm::Range
An extension of std::vector<T> to support additional useful operations.
Definition: Range_fwd.hpp:30
cad_helpers_fwd.hpp