34#include <visp3/core/vpBSpline.h>
35#include <visp3/core/vpDebug.h>
44 : controlPoints(),
knots(),
p(3),
65 unsigned int m =
static_cast<unsigned int>(l_knots.size()) - 1;
67 if (l_u > l_knots.back()) {
70 return (
static_cast<unsigned int>(m - l_p - 1));
74 if (std::fabs(l_u - l_knots.back()) <=
75 std::fabs(
vpMath::maximum(l_u, l_knots.back())) * std::numeric_limits<double>::epsilon())
76 return (
static_cast<unsigned int>(m - l_p - 1));
79 double high = m - l_p;
80 double middle = (low + high) / 2.0;
82 while (l_u < l_knots[
static_cast<unsigned int>(middle)] || l_u >= l_knots[
static_cast<unsigned int>(middle) + 1]) {
83 if (l_u < l_knots[
static_cast<unsigned int>(
vpMath::round(middle))])
87 middle = (low + high) / 2.0;
90 return static_cast<unsigned int>(middle);
125 const std::vector<double> &l_knots)
127 vpBasisFunction *N =
new vpBasisFunction[l_p + 1];
131 double *left =
new double[l_p + 1];
132 double *right =
new double[l_p + 1];
135 for (
unsigned int j = 1; j <= l_p; j++) {
136 left[j] = l_u - l_knots[l_i + 1 - j];
137 right[j] = l_knots[l_i + j] - l_u;
140 for (
unsigned int r = 0; r < j; r++) {
141 temp = N[r].value / (right[r + 1] + left[j - r]);
142 N[r].value = saved + right[r + 1] * temp;
143 saved = left[j - r] * temp;
147 for (
unsigned int j = 0; j < l_p + 1; j++) {
148 N[j].i = l_i - l_p + j;
212 const std::vector<double> &l_knots)
215 N =
new vpBasisFunction *[l_der + 1];
216 for (
unsigned int j = 0; j <= l_der; j++)
217 N[j] =
new vpBasisFunction[l_p + 1];
223 double *left =
new double[l_p + 1];
224 double *right =
new double[l_p + 1];
227 for (
unsigned int j = 1; j <= l_p; j++) {
228 left[j] = l_u - l_knots[l_i + 1 - j];
229 right[j] = l_knots[l_i + j] - l_u;
232 for (
unsigned int r = 0; r < j; r++) {
233 ndu[j][r] = right[r + 1] + left[j - r];
234 temp = ndu[r][j - 1] / ndu[j][r];
235 ndu[r][j] = saved + right[r + 1] * temp;
236 saved = left[j - r] * temp;
241 for (
unsigned int j = 0; j <= l_p; j++) {
242 N[0][j].value = ndu[j][l_p];
243 N[0][j].i = l_i - l_p + j;
250 vpTRACE(
"l_der must be under or equal to l_p");
259 for (
unsigned int r = 0; r <= l_p; r++) {
263 for (
unsigned int k = 1; k <= l_der; k++) {
265 rk =
static_cast<int>(r - k);
268 a[s2][0] = a[s1][0] / ndu[pk + 1][rk];
269 d = a[s2][0] * ndu[
static_cast<unsigned int>(rk)][pk];
275 j1 =
static_cast<unsigned int>(-rk);
282 for (
unsigned int j = j1; j <= j2; j++) {
283 a[s2][j] = (a[s1][j] - a[s1][j - 1]) / ndu[pk + 1][
static_cast<unsigned int>(rk) + j];
284 d += a[s2][j] * ndu[
static_cast<unsigned int>(rk) + j][pk];
288 a[s2][k] = -a[s1][k - 1] / ndu[pk + 1][r];
289 d += a[s2][k] * ndu[r][pk];
292 N[k][r].i = l_i - l_p + r;
303 for (
unsigned int k = 1; k <= l_der; k++) {
304 for (
unsigned int j = 0; j <= l_p; j++)
360 const std::vector<vpImagePoint> &l_controlPoints)
367 for (
unsigned int j = 0; j <= l_p; j++) {
368 ic = ic + N[j].value * (l_controlPoints[l_i - l_p + j]).get_i();
369 jc = jc + N[j].value * (l_controlPoints[l_i - l_p + j]).get_j();
395 for (
unsigned int j = 0; j <=
p; j++) {
396 ic = ic + N[j].value * (controlPoints[N[0].i + j]).get_i();
397 jc = jc + N[j].value * (controlPoints[N[0].i + j]).get_j();
429 const std::vector<double> &l_knots,
const std::vector<vpImagePoint> &l_controlPoints)
437 vpTRACE(
"l_der must be under or equal to l_p");
443 for (
unsigned int k = 0; k <= du; k++) {
444 derivate[k].
set_ij(0.0, 0.0);
445 for (
unsigned int j = 0; j <= l_p; j++) {
446 derivate[k].
set_i(derivate[k].get_i() + N[k][j].value * (l_controlPoints[l_i - l_p + j]).get_i());
447 derivate[k].
set_j(derivate[k].get_j() + N[k][j].value * (l_controlPoints[l_i - l_p + j]).get_j());
451 for (
unsigned int j = 0; j <= l_der; j++)
482 vpTRACE(
"der must be under or equal to p");
488 for (
unsigned int k = 0; k <= du; k++) {
489 derivate[k].
set_ij(0.0, 0.0);
490 for (
unsigned int j = 0; j <=
p; j++) {
491 derivate[k].
set_i(derivate[k].get_i() + N[k][j].value * (controlPoints[N[0][0].i -
p + j]).get_i());
492 derivate[k].
set_j(derivate[k].get_j() + N[k][j].value * (controlPoints[N[0][0].i -
p + j]).get_j());
496 for (
unsigned int j = 0; j <= der; j++)
static vpImagePoint computeCurvePoint(double l_u, unsigned int l_i, unsigned int l_p, const std::vector< double > &l_knots, const std::vector< vpImagePoint > &l_controlPoints)
static unsigned int findSpan(double l_u, unsigned int l_p, const std::vector< double > &l_knots)
unsigned int p
Degree of the B-Spline basis functions.
static vpBasisFunction ** computeDersBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, const std::vector< double > &l_knots)
std::vector< vpImagePoint > crossingPoints
Vector which contains the points used during the interpolation method.
std::vector< double > knots
Vector which contain the knots .
static vpImagePoint * computeCurveDers(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, const std::vector< double > &l_knots, const std::vector< vpImagePoint > &l_controlPoints)
static vpBasisFunction * computeBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, const std::vector< double > &l_knots)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_ij(double ii, double jj)
static Type maximum(const Type &a, const Type &b)
static int round(double x)
Implementation of a matrix and operations on matrices.