36 #include <visp3/core/vpColVector.h>
37 #include <visp3/core/vpDebug.h>
38 #include <visp3/me/vpNurbs.h>
48 double distancew = w1 - w2;
57 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
59 vpBasisFunction *N =
nullptr;
66 for (
unsigned int j = 0; j <= l_p; j++) {
67 ic = ic + N[j].value * (l_controlPoints[l_i - l_p + j]).get_i() * l_weights[l_i - l_p + j];
68 jc = jc + N[j].value * (l_controlPoints[l_i - l_p + j]).get_j() * l_weights[l_i - l_p + j];
69 wc = wc + N[j].value * l_weights[l_i - l_p + j];
83 vpBasisFunction *N =
nullptr;
90 for (
unsigned int j = 0; j <= p; j++) {
91 ic = ic + N[j].value * (controlPoints[N[0].i + j]).get_i() *
weights[N[0].i + j];
92 jc = jc + N[j].value * (controlPoints[N[0].i + j]).get_j() *
weights[N[0].i + j];
93 wc = wc + N[j].value *
weights[N[0].i + j];
106 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
107 std::vector<double> &l_weights)
110 vpBasisFunction **N =
nullptr;
113 for (
unsigned int k = 0; k <= l_der; k++) {
114 derivate[k][0] = 0.0;
115 derivate[k][1] = 0.0;
116 derivate[k][2] = 0.0;
118 for (
unsigned int j = 0; j <= l_p; j++) {
119 derivate[k][0] = derivate[k][0] + N[k][j].value * (l_controlPoints[l_i - l_p + j]).get_i();
120 derivate[k][1] = derivate[k][1] + N[k][j].value * (l_controlPoints[l_i - l_p + j]).get_j();
121 derivate[k][2] = derivate[k][2] + N[k][j].value * (l_weights[l_i - l_p + j]);
126 for (
unsigned int i = 0; i <= l_der; i++)
136 vpBasisFunction **N =
nullptr;
139 for (
unsigned int k = 0; k <= der; k++) {
140 derivate[k][0] = 0.0;
141 derivate[k][1] = 0.0;
142 derivate[k][2] = 0.0;
143 for (
unsigned int j = 0; j <= p; j++) {
144 derivate[k][0] = derivate[k][0] + N[k][j].value * (controlPoints[N[0][0].i - p + j]).get_i();
145 derivate[k][1] = derivate[k][1] + N[k][j].value * (controlPoints[N[0][0].i - p + j]).get_j();
146 derivate[k][2] = derivate[k][2] + N[k][j].value * (
weights[N[0][0].i - p + j]);
157 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
158 std::vector<double> &l_weights)
160 std::vector<vpImagePoint> A;
162 for (
unsigned int j = 0; j < l_controlPoints.size(); j++) {
163 pt = l_controlPoints[j];
173 for (
unsigned int k = 0; k <= l_der; k++) {
174 double ic = Awders[k][0];
175 double jc = Awders[k][1];
176 for (
unsigned int j = 1; j <= k; j++) {
177 double tmpComb =
static_cast<double>(
vpMath::comb(k, j));
178 ic = ic - tmpComb * Awders[k][2] * (CK[k - j].
get_i());
179 jc = jc - tmpComb * Awders[j][2] * (CK[k - j].
get_j());
181 CK[k].
set_ij(ic / Awders[0][2], jc / Awders[0][2]);
195 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
196 std::vector<double> &l_weights)
199 std::vector<vpImagePoint>::iterator it1;
200 std::vector<double>::iterator it2;
204 for (
unsigned int j = 0; j <= l_p - l_s; j++) {
205 Rw[j][0] = (l_controlPoints[l_k - l_p + j]).get_i() * l_weights[l_k - l_p + j];
206 Rw[j][1] = (l_controlPoints[l_k - l_p + j]).get_j() * l_weights[l_k - l_p + j];
207 Rw[j][2] = l_weights[l_k - l_p + j];
210 it1 = l_controlPoints.begin();
211 l_controlPoints.
insert(it1 + (
int)l_k - (int)l_s, l_r, pt);
212 it2 = l_weights.begin();
213 l_weights.insert(it2 + (
int)l_k - (int)l_s, l_r, w);
217 for (
unsigned int j = 1; j <= l_r; j++) {
220 for (
unsigned int i = 0; i <= l_p - j - l_s; i++) {
221 alpha = (l_u - l_knots[L + i]) / (l_knots[i + l_k + 1] - l_knots[L + i]);
222 Rw[i][0] = alpha * Rw[i + 1][0] + (1.0 - alpha) * Rw[i][0];
223 Rw[i][1] = alpha * Rw[i + 1][1] + (1.0 - alpha) * Rw[i][1];
224 Rw[i][2] = alpha * Rw[i + 1][2] + (1.0 - alpha) * Rw[i][2];
227 pt.
set_ij(Rw[0][0] / Rw[0][2], Rw[0][1] / Rw[0][2]);
228 l_controlPoints[L] = pt;
229 l_weights[L] = Rw[0][2];
231 pt.
set_ij(Rw[l_p - j - l_s][0] / Rw[l_p - j - l_s][2], Rw[l_p - j - l_s][1] / Rw[l_p - j - l_s][2]);
232 l_controlPoints[l_k + l_r - j - l_s] = pt;
233 l_weights[l_k + l_r - j - l_s] = Rw[l_p - j - l_s][2];
236 for (
unsigned int j = L + 1; j < l_k - l_s; j++) {
237 pt.
set_ij(Rw[j - L][0] / Rw[j - L][2], Rw[j - L][1] / Rw[j - L][2]);
238 l_controlPoints[j] = pt;
239 l_weights[j] = Rw[j - L][2];
242 it2 = l_knots.begin();
243 l_knots.
insert(it2 + (
int)l_k, l_r, l_u);
254 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
256 unsigned int a =
findSpan(l_x[0], l_p, l_knots);
257 unsigned int b =
findSpan(l_x[l_r], l_p, l_knots);
260 unsigned int n = (
unsigned int)l_controlPoints.size();
261 unsigned int m = (
unsigned int)l_knots.size();
263 for (
unsigned int j = 0; j < n; j++) {
264 l_controlPoints[j].set_ij(l_controlPoints[j].get_i() * l_weights[j], l_controlPoints[j].get_j() * l_weights[j]);
267 std::vector<double> l_knots_tmp(l_knots);
268 std::vector<vpImagePoint> l_controlPoints_tmp(l_controlPoints);
269 std::vector<double> l_weights_tmp(l_weights);
274 for (
unsigned int j = 0; j <= l_r; j++) {
275 l_controlPoints.push_back(pt);
276 l_weights.push_back(w);
277 l_knots.push_back(w);
280 for (
unsigned int j = b + l_p; j <= m - 1; j++)
281 l_knots[j + l_r + 1] = l_knots_tmp[j];
283 for (
unsigned int j = b - 1; j <= n - 1; j++) {
284 l_controlPoints[j + l_r + 1] = l_controlPoints_tmp[j];
285 l_weights[j + l_r + 1] = l_weights_tmp[j];
288 unsigned int i = b + l_p - 1;
289 unsigned int k = b + l_p + l_r;
292 unsigned int j = l_r + 1;
295 while (l_x[j] <= l_knots[i] && i > a) {
296 l_controlPoints[k - l_p - 1] = l_controlPoints_tmp[i - l_p - 1];
297 l_weights[k - l_p - 1] = l_weights_tmp[i - l_p - 1];
298 l_knots[k] = l_knots_tmp[i];
303 l_controlPoints[k - l_p - 1] = l_controlPoints[k - l_p];
304 l_weights[k - l_p - 1] = l_weights[k - l_p];
306 for (
unsigned int l = 1; l <= l_p; l++) {
307 unsigned int ind = k - l_p + l;
308 double alpha = l_knots[k + l] - l_x[j];
310 if (std::fabs(alpha) <= std::numeric_limits<double>::epsilon()) {
311 l_controlPoints[ind - 1] = l_controlPoints[ind];
312 l_weights[ind - 1] = l_weights[ind];
315 alpha = alpha / (l_knots[k + l] - l_knots_tmp[i - l_p + l]);
316 l_controlPoints[ind - 1].
set_i(alpha * l_controlPoints[ind - 1].get_i() +
317 (1.0 - alpha) * l_controlPoints[ind].get_i());
318 l_controlPoints[ind - 1].set_j(alpha * l_controlPoints[ind - 1].get_j() +
319 (1.0 - alpha) * l_controlPoints[ind].get_j());
320 l_weights[ind - 1] = alpha * l_weights[ind - 1] + (1.0 - alpha) * l_weights[ind];
328 for (
unsigned int j = 0; j < n; j++) {
329 l_controlPoints[j].set_ij(l_controlPoints[j].get_i() / l_weights[j], l_controlPoints[j].get_j() / l_weights[j]);
339 unsigned int l_p, std::vector<double> &l_knots,
340 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
342 unsigned int n = (
unsigned int)l_controlPoints.size();
343 unsigned int m = n + l_p + 1;
345 for (
unsigned int j = 0; j < n; j++) {
346 l_controlPoints[j].set_ij(l_controlPoints[j].get_i() * l_weights[j], l_controlPoints[j].get_j() * l_weights[j]);
349 unsigned int ord = l_p + 1;
350 double fout = (2 * l_r - l_s - l_p) / 2.;
351 unsigned int last = l_r - l_s;
352 unsigned int first = l_r - l_p;
353 unsigned int tblSize = 2 * l_p + 1;
355 double *tempW =
new double[tblSize];
362 for (t = 0; t < l_num; t++) {
363 unsigned int off = first - 1;
364 tempP[0] = l_controlPoints[off];
365 tempW[0] = l_weights[off];
366 tempP[last + 1 - off] = l_controlPoints[last + 1];
367 tempW[last + 1 - off] = l_weights[last + 1];
371 unsigned int jj = last - off;
374 alfi = (l_u - l_knots[i]) / (l_knots[i + ord + t] - l_knots[i]);
375 alfj = (l_u - l_knots[j - t]) / (l_knots[j + ord] - l_knots[j - t]);
376 pt.
set_i((l_controlPoints[i].get_i() - (1.0 - alfi) * tempP[ii - 1].get_i()) / alfi);
377 tempP[ii].
set_i((l_controlPoints[i].get_i() - (1.0 - alfi) * tempP[ii - 1].get_i()) / alfi);
378 tempP[ii].
set_j((l_controlPoints[i].get_j() - (1.0 - alfi) * tempP[ii - 1].get_j()) / alfi);
379 tempW[ii] = ((l_weights[i] - (1.0 - alfi) * tempW[ii - 1]) / alfi);
380 tempP[jj].
set_i((l_controlPoints[j].get_i() - alfj * tempP[jj + 1].
get_i()) / (1.0 - alfj));
381 tempP[jj].
set_j((l_controlPoints[j].get_j() - alfj * tempP[jj + 1].
get_j()) / (1.0 - alfj));
382 tempW[jj] = ((l_weights[j] - alfj * tempW[jj + 1]) / (1.0 - alfj));
390 double distancei = tempP[ii - 1].
get_i() - tempP[jj + 1].
get_i();
391 double distancej = tempP[ii - 1].
get_j() - tempP[jj + 1].
get_j();
392 double distancew = tempW[ii - 1] - tempW[jj + 1];
394 if (distance <= l_TOL)
398 alfi = (l_u - l_knots[i]) / (l_knots[i + ord + t] - l_knots[i]);
400 l_controlPoints[i].get_i() - (alfi * tempP[ii + t + 1].
get_i() + (1.0 - alfi) * tempP[ii - 1].get_i());
402 l_controlPoints[i].get_j() - (alfi * tempP[ii + t + 1].
get_j() + (1.0 - alfi) * tempP[ii - 1].get_j());
403 double distancew = l_weights[i] - (alfi * tempW[ii + t + 1] + (1.0 - alfi) * tempW[ii - 1]);
405 if (distance <= l_TOL)
414 l_controlPoints[i].set_i(tempP[i - off].get_i());
415 l_controlPoints[i].set_j(tempP[i - off].get_j());
416 l_weights[i] = tempW[i - off];
417 l_controlPoints[j].set_i(tempP[j - off].get_i());
418 l_controlPoints[j].set_j(tempP[j - off].get_j());
419 l_weights[j] = tempW[j - off];
432 for (
unsigned int k = l_r + 1; k <= m; k++)
433 l_knots[k - t] = l_knots[k];
434 j = (
unsigned int)fout;
436 for (
unsigned int k = 1; k < t; k++) {
442 for (
unsigned int k = i + 1; k <= n; k++) {
443 l_controlPoints[j].
set_i(l_controlPoints[k].get_i());
444 l_controlPoints[j].set_j(l_controlPoints[k].get_j());
445 l_weights[j] = l_weights[k];
448 for (
unsigned int k = 0; k < t; k++) {
449 l_knots.erase(l_knots.end() - 1);
450 l_controlPoints.erase(l_controlPoints.end() - 1);
453 for (
unsigned int k = 0; k < l_controlPoints.size(); k++)
454 l_controlPoints[k].set_ij(l_controlPoints[k].get_i() / l_weights[k], l_controlPoints[k].get_j() / l_weights[k]);
467 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
468 std::vector<double> &l_weights)
476 l_controlPoints.clear();
478 unsigned int n = (
unsigned int)l_crossingPoints.size() - 1;
479 unsigned int m = n + l_p + 1;
482 for (
unsigned int k = 1; k <= n; k++)
483 d = d + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1);
486 std::vector<double> ubar;
488 for (
unsigned int k = 1; k < n; k++) {
489 ubar.push_back(ubar[k - 1] + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1) / d);
494 for (
unsigned int k = 0; k <= l_p; k++)
495 l_knots.push_back(0.0);
498 for (
unsigned int k = 1; k <= l_p; k++)
502 for (
unsigned int k = 1; k <= n - l_p; k++) {
503 l_knots.push_back(sum / l_p);
504 sum = sum - ubar[k - 1] + ubar[l_p + k - 1];
507 for (
unsigned int k = m - l_p; k <= m; k++)
508 l_knots.push_back(1.0);
513 for (
unsigned int i = 0; i <= n; i++) {
514 unsigned int span =
findSpan(ubar[i], l_p, l_knots);
516 for (
unsigned int k = 0; k <= l_p; k++)
517 A[i][span - l_p + k] = N[k].value;
526 for (
unsigned int k = 0; k <= n; k++) {
527 Qi[k] = l_crossingPoints[k].get_i();
528 Qj[k] = l_crossingPoints[k].get_j();
536 for (
unsigned int k = 0; k <= n; k++) {
538 l_controlPoints.push_back(pt);
539 l_weights.push_back(Pw[k]);
545 std::vector<vpImagePoint> v_crossingPoints;
546 l_crossingPoints.
front();
550 v_crossingPoints.push_back(pt);
551 l_crossingPoints.
next();
552 while (!l_crossingPoints.
outside()) {
553 s = l_crossingPoints.
value();
556 v_crossingPoints.push_back(pt);
559 l_crossingPoints.
next();
566 std::vector<vpImagePoint> v_crossingPoints;
567 for (std::list<vpImagePoint>::const_iterator it = l_crossingPoints.begin(); it != l_crossingPoints.end(); ++it) {
568 v_crossingPoints.push_back(*it);
576 std::vector<vpImagePoint> v_crossingPoints;
577 vpMeSite s = l_crossingPoints.front();
580 v_crossingPoints.push_back(pt);
581 std::list<vpMeSite>::const_iterator it = l_crossingPoints.begin();
583 for (; it != l_crossingPoints.end(); ++it) {
584 vpImagePoint pt_tmp(it->get_ifloat(), it->get_jfloat());
586 v_crossingPoints.push_back(pt_tmp);
596 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
597 std::vector<double> &l_weights)
600 l_controlPoints.clear();
602 unsigned int m = (
unsigned int)l_crossingPoints.size() - 1;
605 for (
unsigned int k = 1; k <= m; k++)
606 d = d + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1);
609 std::vector<double> ubar;
611 for (
unsigned int k = 1; k < m; k++)
612 ubar.push_back(ubar[k - 1] + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1) / d);
616 for (
unsigned int k = 0; k <= l_p; k++)
617 l_knots.push_back(0.0);
619 d = (double)(m + 1) / (double)(l_n - l_p + 1);
621 for (
unsigned int j = 1; j <= l_n - l_p; j++) {
622 double i = floor(j * d);
623 double alpha = j * d - i;
624 l_knots.push_back((1.0 - alpha) * ubar[(
unsigned int)i - 1] + alpha * ubar[(
unsigned int)i]);
627 for (
unsigned int k = 0; k <= l_p; k++)
628 l_knots.push_back(1.0);
631 std::vector<vpImagePoint> Rk;
633 for (
unsigned int k = 1; k <= m - 1; k++) {
634 unsigned int span =
findSpan(ubar[k], l_p, l_knots);
635 if (span == l_p && span == l_n) {
637 vpImagePoint pt(l_crossingPoints[k].get_i() - N[0].value * l_crossingPoints[0].get_i() -
638 N[l_p].value * l_crossingPoints[m].get_i(),
639 l_crossingPoints[k].get_j() - N[0].value * l_crossingPoints[0].get_j() -
640 N[l_p].value * l_crossingPoints[m].get_j());
644 else if (span == l_p) {
646 vpImagePoint pt(l_crossingPoints[k].get_i() - N[0].value * l_crossingPoints[0].get_i(),
647 l_crossingPoints[k].get_j() - N[0].value * l_crossingPoints[0].get_j());
651 else if (span == l_n) {
653 vpImagePoint pt(l_crossingPoints[k].get_i() - N[l_p].value * l_crossingPoints[m].get_i(),
654 l_crossingPoints[k].get_j() - N[l_p].value * l_crossingPoints[m].get_j());
659 Rk.push_back(l_crossingPoints[k]);
665 for (
unsigned int i = 1; i <= m - 1; i++) {
666 unsigned int span =
findSpan(ubar[i], l_p, l_knots);
668 for (
unsigned int k = 0; k <= l_p; k++) {
669 if (N[k].i > 0 && N[k].i < l_n)
670 A[i - 1][N[k].i - 1] = N[k].value;
678 for (
unsigned int i = 0; i < l_n - 1; i++) {
680 for (
unsigned int k = 0; k < m - 1; k++)
681 sum = sum + A[k][i] * Rk[k].get_i();
684 for (
unsigned int k = 0; k < m - 1; k++)
685 sum = sum + A[k][i] * Rk[k].get_j();
688 for (
unsigned int k = 0; k < m - 1; k++)
702 l_controlPoints.push_back(l_crossingPoints[0]);
703 l_weights.push_back(1.0);
704 for (
unsigned int k = 0; k < l_n - 1; k++) {
706 l_controlPoints.push_back(pt);
707 l_weights.push_back(Pw[k]);
709 l_controlPoints.push_back(l_crossingPoints[m]);
710 l_weights.push_back(1.0);
716 std::vector<vpImagePoint> v_crossingPoints;
717 l_crossingPoints.
front();
718 while (!l_crossingPoints.
outside()) {
721 v_crossingPoints.push_back(pt);
722 l_crossingPoints.
next();
730 std::vector<vpImagePoint> v_crossingPoints;
731 for (std::list<vpImagePoint>::const_iterator it = l_crossingPoints.begin(); it != l_crossingPoints.end(); ++it) {
732 v_crossingPoints.push_back(*it);
739 std::vector<vpImagePoint> v_crossingPoints;
740 for (std::list<vpMeSite>::const_iterator it = l_crossingPoints.begin(); it != l_crossingPoints.end(); ++it) {
742 v_crossingPoints.push_back(pt);
Class that provides tools to compute and manipulate a B-Spline curve.
static unsigned int findSpan(double l_u, unsigned int l_p, const std::vector< double > &l_knots)
static vpBasisFunction ** computeDersBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, const std::vector< double > &l_knots)
static vpBasisFunction * computeBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, const std::vector< double > &l_knots)
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_ij(double ii, double jj)
Provide simple list management.
void next(void)
position the current element on the next one
void front(void)
Position the current element on the first element of the list.
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
type & value(void)
return the value of the current element
static double sqr(double x)
static long double comb(unsigned int n, unsigned int p)
Implementation of a matrix and operations on matrices.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
void insert(const vpMatrix &A, unsigned int r, unsigned int c)
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
double get_ifloat() const
double get_jfloat() const
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve.
static void refineKnotVectCurve(double *l_x, unsigned int l_r, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
std::vector< double > weights
Vector which contains the weights associated to each control Points.
static vpImagePoint computeCurvePoint(double l_u, unsigned int l_i, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static void curveKnotIns(double l_u, unsigned int l_k, unsigned int l_s, unsigned int l_r, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static vpMatrix computeCurveDers(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static vpImagePoint * computeCurveDersPoint(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static void globalCurveApprox(std::vector< vpImagePoint > &l_crossingPoints, unsigned int l_p, unsigned int l_n, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static unsigned int removeCurveKnot(double l_u, unsigned int l_r, unsigned int l_num, double l_TOL, unsigned int l_s, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)