41 #include <visp3/core/vpColVector.h> 42 #include <visp3/me/vpNurbs.h> 50 double distancew = w1 - w2;
86 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
88 vpBasisFunction *N = NULL;
95 for (
unsigned int j = 0; j <= l_p; j++) {
96 ic = ic + N[j].value * (l_controlPoints[l_i - l_p + j]).get_i() * l_weights[l_i - l_p + j];
97 jc = jc + N[j].value * (l_controlPoints[l_i - l_p + j]).get_j() * l_weights[l_i - l_p + j];
98 wc = wc + N[j].value * l_weights[l_i - l_p + j];
121 vpBasisFunction *N = NULL;
128 for (
unsigned int j = 0; j <= p; j++) {
129 ic = ic + N[j].value * (controlPoints[N[0].i + j]).get_i() *
weights[N[0].i + j];
130 jc = jc + N[j].value * (controlPoints[N[0].i + j]).get_j() *
weights[N[0].i + j];
131 wc = wc + N[j].value *
weights[N[0].i + j];
171 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
172 std::vector<double> &l_weights)
175 vpBasisFunction **N = NULL;
178 for (
unsigned int k = 0; k <= l_der; k++) {
179 derivate[k][0] = 0.0;
180 derivate[k][1] = 0.0;
181 derivate[k][2] = 0.0;
183 for (
unsigned int j = 0; j <= l_p; j++) {
184 derivate[k][0] = derivate[k][0] + N[k][j].value * (l_controlPoints[l_i - l_p + j]).get_i();
185 derivate[k][1] = derivate[k][1] + N[k][j].value * (l_controlPoints[l_i - l_p + j]).get_j();
186 derivate[k][2] = derivate[k][2] + N[k][j].value * (l_weights[l_i - l_p + j]);
191 for (
unsigned int i = 0; i <= l_der; i++)
223 vpBasisFunction **N = NULL;
226 for (
unsigned int k = 0; k <= der; k++) {
227 derivate[k][0] = 0.0;
228 derivate[k][1] = 0.0;
229 derivate[k][2] = 0.0;
230 for (
unsigned int j = 0; j <= p; j++) {
231 derivate[k][0] = derivate[k][0] + N[k][j].value * (controlPoints[N[0][0].i - p + j]).get_i();
232 derivate[k][1] = derivate[k][1] + N[k][j].value * (controlPoints[N[0][0].i - p + j]).get_j();
233 derivate[k][2] = derivate[k][2] + N[k][j].value * (
weights[N[0][0].i - p + j]);
261 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
262 std::vector<double> &l_weights)
264 std::vector<vpImagePoint> A;
266 for (
unsigned int j = 0; j < l_controlPoints.size(); j++) {
267 pt = l_controlPoints[j];
277 for (
unsigned int k = 0; k <= l_der; k++) {
278 double ic = Awders[k][0];
279 double jc = Awders[k][1];
280 for (
unsigned int j = 1; j <= k; j++) {
281 double tmpComb =
static_cast<double>(
vpMath::comb(k, j));
282 ic = ic - tmpComb * Awders[k][2] * (CK[k - j].
get_i());
283 jc = jc - tmpComb * Awders[j][2] * (CK[k - j].
get_j());
285 CK[k].
set_ij(ic / Awders[0][2], jc / Awders[0][2]);
326 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
327 std::vector<double> &l_weights)
330 std::vector<vpImagePoint>::iterator it1;
331 std::vector<double>::iterator it2;
335 for (
unsigned int j = 0; j <= l_p - l_s; j++) {
336 Rw[j][0] = (l_controlPoints[l_k - l_p + j]).get_i() * l_weights[l_k - l_p + j];
337 Rw[j][1] = (l_controlPoints[l_k - l_p + j]).get_j() * l_weights[l_k - l_p + j];
338 Rw[j][2] = l_weights[l_k - l_p + j];
341 it1 = l_controlPoints.begin();
342 l_controlPoints.
insert(it1 + (
int)l_k - (
int)l_s, l_r, pt);
343 it2 = l_weights.begin();
344 l_weights.insert(it2 + (
int)l_k - (
int)l_s, l_r, w);
348 for (
unsigned int j = 1; j <= l_r; j++) {
351 for (
unsigned int i = 0; i <= l_p - j - l_s; i++) {
352 alpha = (l_u - l_knots[L + i]) / (l_knots[i + l_k + 1] - l_knots[L + i]);
353 Rw[i][0] = alpha * Rw[i + 1][0] + (1.0 - alpha) * Rw[i][0];
354 Rw[i][1] = alpha * Rw[i + 1][1] + (1.0 - alpha) * Rw[i][1];
355 Rw[i][2] = alpha * Rw[i + 1][2] + (1.0 - alpha) * Rw[i][2];
358 pt.
set_ij(Rw[0][0] / Rw[0][2], Rw[0][1] / Rw[0][2]);
359 l_controlPoints[L] = pt;
360 l_weights[L] = Rw[0][2];
362 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]);
363 l_controlPoints[l_k + l_r - j - l_s] = pt;
364 l_weights[l_k + l_r - j - l_s] = Rw[l_p - j - l_s][2];
367 for (
unsigned int j = L + 1; j < l_k - l_s; j++) {
368 pt.
set_ij(Rw[j - L][0] / Rw[j - L][2], Rw[j - L][1] / Rw[j - L][2]);
369 l_controlPoints[j] = pt;
370 l_weights[j] = Rw[j - L][2];
373 it2 = l_knots.begin();
374 l_knots.
insert(it2 + (
int)l_k, l_r, l_u);
408 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
410 unsigned int a =
findSpan(l_x[0], l_p, l_knots);
411 unsigned int b =
findSpan(l_x[l_r], l_p, l_knots);
414 unsigned int n = (
unsigned int)l_controlPoints.size();
415 unsigned int m = (
unsigned int)l_knots.size();
417 for (
unsigned int j = 0; j < n; j++) {
418 l_controlPoints[j].set_ij(l_controlPoints[j].get_i() * l_weights[j], l_controlPoints[j].get_j() * l_weights[j]);
421 std::vector<double> l_knots_tmp(l_knots);
422 std::vector<vpImagePoint> l_controlPoints_tmp(l_controlPoints);
423 std::vector<double> l_weights_tmp(l_weights);
428 for (
unsigned int j = 0; j <= l_r; j++) {
429 l_controlPoints.push_back(pt);
430 l_weights.push_back(w);
431 l_knots.push_back(w);
434 for (
unsigned int j = b + l_p; j <= m - 1; j++)
435 l_knots[j + l_r + 1] = l_knots_tmp[j];
437 for (
unsigned int j = b - 1; j <= n - 1; j++) {
438 l_controlPoints[j + l_r + 1] = l_controlPoints_tmp[j];
439 l_weights[j + l_r + 1] = l_weights_tmp[j];
442 unsigned int i = b + l_p - 1;
443 unsigned int k = b + l_p + l_r;
446 unsigned int j = l_r + 1;
449 while (l_x[j] <= l_knots[i] && i > a) {
450 l_controlPoints[k - l_p - 1] = l_controlPoints_tmp[i - l_p - 1];
451 l_weights[k - l_p - 1] = l_weights_tmp[i - l_p - 1];
452 l_knots[k] = l_knots_tmp[i];
457 l_controlPoints[k - l_p - 1] = l_controlPoints[k - l_p];
458 l_weights[k - l_p - 1] = l_weights[k - l_p];
460 for (
unsigned int l = 1; l <= l_p; l++) {
461 unsigned int ind = k - l_p + l;
462 double alpha = l_knots[k + l] - l_x[j];
464 if (std::fabs(alpha) <= std::numeric_limits<double>::epsilon()) {
465 l_controlPoints[ind - 1] = l_controlPoints[ind];
466 l_weights[ind - 1] = l_weights[ind];
468 alpha = alpha / (l_knots[k + l] - l_knots_tmp[i - l_p + l]);
469 l_controlPoints[ind - 1].
set_i(alpha * l_controlPoints[ind - 1].get_i() +
470 (1.0 - alpha) * l_controlPoints[ind].get_i());
471 l_controlPoints[ind - 1].set_j(alpha * l_controlPoints[ind - 1].get_j() +
472 (1.0 - alpha) * l_controlPoints[ind].get_j());
473 l_weights[ind - 1] = alpha * l_weights[ind - 1] + (1.0 - alpha) * l_weights[ind];
481 for (
unsigned int j = 0; j < n; j++) {
482 l_controlPoints[j].set_ij(l_controlPoints[j].get_i() / l_weights[j], l_controlPoints[j].get_j() / l_weights[j]);
527 unsigned int l_p, std::vector<double> &l_knots,
528 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
530 unsigned int n = (
unsigned int)l_controlPoints.size();
531 unsigned int m = n + l_p + 1;
533 for (
unsigned int j = 0; j < n; j++) {
534 l_controlPoints[j].set_ij(l_controlPoints[j].get_i() * l_weights[j], l_controlPoints[j].get_j() * l_weights[j]);
537 unsigned int ord = l_p + 1;
538 double fout = (2 * l_r - l_s - l_p) / 2.;
539 unsigned int last = l_r - l_s;
540 unsigned int first = l_r - l_p;
541 unsigned int tblSize = 2 * l_p + 1;
543 double *tempW =
new double[tblSize];
550 for (t = 0; t < l_num; t++) {
551 unsigned int off = first - 1;
552 tempP[0] = l_controlPoints[off];
553 tempW[0] = l_weights[off];
554 tempP[last + 1 - off] = l_controlPoints[last + 1];
555 tempW[last + 1 - off] = l_weights[last + 1];
559 unsigned int jj = last - off;
562 alfi = (l_u - l_knots[i]) / (l_knots[i + ord + t] - l_knots[i]);
563 alfj = (l_u - l_knots[j - t]) / (l_knots[j + ord] - l_knots[j - t]);
564 pt.
set_i((l_controlPoints[i].get_i() - (1.0 - alfi) * tempP[ii - 1].get_i()) / alfi);
565 tempP[ii].
set_i((l_controlPoints[i].get_i() - (1.0 - alfi) * tempP[ii - 1].get_i()) / alfi);
566 tempP[ii].
set_j((l_controlPoints[i].get_j() - (1.0 - alfi) * tempP[ii - 1].get_j()) / alfi);
567 tempW[ii] = ((l_weights[i] - (1.0 - alfi) * tempW[ii - 1]) / alfi);
568 tempP[jj].
set_i((l_controlPoints[j].get_i() - alfj * tempP[jj + 1].get_i()) / (1.0 - alfj));
569 tempP[jj].
set_j((l_controlPoints[j].get_j() - alfj * tempP[jj + 1].get_j()) / (1.0 - alfj));
570 tempW[jj] = ((l_weights[j] - alfj * tempW[jj + 1]) / (1.0 - alfj));
578 double distancei = tempP[ii - 1].
get_i() - tempP[jj + 1].
get_i();
579 double distancej = tempP[ii - 1].
get_j() - tempP[jj + 1].
get_j();
580 double distancew = tempW[ii - 1] - tempW[jj + 1];
582 if (distance <= l_TOL)
585 alfi = (l_u - l_knots[i]) / (l_knots[i + ord + t] - l_knots[i]);
587 l_controlPoints[i].get_i() - (alfi * tempP[ii + t + 1].
get_i() + (1.0 - alfi) * tempP[ii - 1].get_i());
589 l_controlPoints[i].get_j() - (alfi * tempP[ii + t + 1].
get_j() + (1.0 - alfi) * tempP[ii - 1].get_j());
590 double distancew = l_weights[i] - (alfi * tempW[ii + t + 1] + (1.0 - alfi) * tempW[ii - 1]);
592 if (distance <= l_TOL)
601 l_controlPoints[i].set_i(tempP[i - off].get_i());
602 l_controlPoints[i].set_j(tempP[i - off].get_j());
603 l_weights[i] = tempW[i - off];
604 l_controlPoints[j].set_i(tempP[j - off].get_i());
605 l_controlPoints[j].set_j(tempP[j - off].get_j());
606 l_weights[j] = tempW[j - off];
619 for (
unsigned int k = l_r + 1; k <= m; k++)
620 l_knots[k - t] = l_knots[k];
621 j = (
unsigned int)fout;
623 for (
unsigned int k = 1; k < t; k++) {
629 for (
unsigned int k = i + 1; k <= n; k++) {
630 l_controlPoints[j].
set_i(l_controlPoints[k].get_i());
631 l_controlPoints[j].set_j(l_controlPoints[k].get_j());
632 l_weights[j] = l_weights[k];
635 for (
unsigned int k = 0; k < t; k++) {
636 l_knots.erase(l_knots.end() - 1);
637 l_controlPoints.erase(l_controlPoints.end() - 1);
640 for (
unsigned int k = 0; k < l_controlPoints.size(); k++)
641 l_controlPoints[k].set_ij(l_controlPoints[k].get_i() / l_weights[k], l_controlPoints[k].get_j() / l_weights[k]);
686 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
687 std::vector<double> &l_weights)
695 l_controlPoints.clear();
697 unsigned int n = (
unsigned int)l_crossingPoints.size() - 1;
698 unsigned int m = n + l_p + 1;
701 for (
unsigned int k = 1; k <= n; k++)
702 d = d + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1);
705 std::vector<double> ubar;
707 for (
unsigned int k = 1; k < n; k++) {
708 ubar.push_back(ubar[k - 1] + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1) / d);
713 for (
unsigned int k = 0; k <= l_p; k++)
714 l_knots.push_back(0.0);
717 for (
unsigned int k = 1; k <= l_p; k++)
721 for (
unsigned int k = 1; k <= n - l_p; k++) {
722 l_knots.push_back(sum / l_p);
723 sum = sum - ubar[k - 1] + ubar[l_p + k - 1];
726 for (
unsigned int k = m - l_p; k <= m; k++)
727 l_knots.push_back(1.0);
732 for (
unsigned int i = 0; i <= n; i++) {
733 unsigned int span =
findSpan(ubar[i], l_p, l_knots);
735 for (
unsigned int k = 0; k <= l_p; k++)
736 A[i][span - l_p + k] = N[k].value;
745 for (
unsigned int k = 0; k <= n; k++) {
746 Qi[k] = l_crossingPoints[k].get_i();
747 Qj[k] = l_crossingPoints[k].get_j();
755 for (
unsigned int k = 0; k <= n; k++) {
757 l_controlPoints.push_back(pt);
758 l_weights.push_back(Pw[k]);
774 std::vector<vpImagePoint> v_crossingPoints;
775 l_crossingPoints.
front();
779 v_crossingPoints.push_back(pt);
780 l_crossingPoints.
next();
781 while (!l_crossingPoints.
outside()) {
782 s = l_crossingPoints.
value();
785 v_crossingPoints.push_back(pt);
788 l_crossingPoints.
next();
805 std::vector<vpImagePoint> v_crossingPoints;
806 for (std::list<vpImagePoint>::const_iterator it = l_crossingPoints.begin(); it != l_crossingPoints.end(); ++it) {
807 v_crossingPoints.push_back(*it);
824 std::vector<vpImagePoint> v_crossingPoints;
825 vpMeSite s = l_crossingPoints.front();
828 v_crossingPoints.push_back(pt);
829 std::list<vpMeSite>::const_iterator it = l_crossingPoints.begin();
831 for (; it != l_crossingPoints.end(); ++it) {
834 v_crossingPoints.push_back(pt_tmp);
867 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints,
868 std::vector<double> &l_weights)
871 l_controlPoints.clear();
873 unsigned int m = (
unsigned int)l_crossingPoints.size() - 1;
876 for (
unsigned int k = 1; k <= m; k++)
877 d = d + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1);
880 std::vector<double> ubar;
882 for (
unsigned int k = 1; k < m; k++)
883 ubar.push_back(ubar[k - 1] + distance(l_crossingPoints[k], 1, l_crossingPoints[k - 1], 1) / d);
887 for (
unsigned int k = 0; k <= l_p; k++)
888 l_knots.push_back(0.0);
890 d = (double)(m + 1) / (double)(l_n - l_p + 1);
892 for (
unsigned int j = 1; j <= l_n - l_p; j++) {
893 double i = floor(j * d);
894 double alpha = j * d - i;
895 l_knots.push_back((1.0 - alpha) * ubar[(
unsigned int)i - 1] + alpha * ubar[(
unsigned int)i]);
898 for (
unsigned int k = 0; k <= l_p; k++)
899 l_knots.push_back(1.0);
902 std::vector<vpImagePoint> Rk;
904 for (
unsigned int k = 1; k <= m - 1; k++) {
905 unsigned int span =
findSpan(ubar[k], l_p, l_knots);
906 if (span == l_p && span == l_n) {
908 vpImagePoint pt(l_crossingPoints[k].get_i() - N[0].value * l_crossingPoints[0].get_i() -
909 N[l_p].value * l_crossingPoints[m].get_i(),
910 l_crossingPoints[k].get_j() - N[0].value * l_crossingPoints[0].get_j() -
911 N[l_p].value * l_crossingPoints[m].get_j());
914 }
else if (span == l_p) {
916 vpImagePoint pt(l_crossingPoints[k].get_i() - N[0].value * l_crossingPoints[0].get_i(),
917 l_crossingPoints[k].get_j() - N[0].value * l_crossingPoints[0].get_j());
920 }
else if (span == l_n) {
922 vpImagePoint pt(l_crossingPoints[k].get_i() - N[l_p].value * l_crossingPoints[m].get_i(),
923 l_crossingPoints[k].get_j() - N[l_p].value * l_crossingPoints[m].get_j());
927 Rk.push_back(l_crossingPoints[k]);
933 for (
unsigned int i = 1; i <= m - 1; i++) {
934 unsigned int span =
findSpan(ubar[i], l_p, l_knots);
936 for (
unsigned int k = 0; k <= l_p; k++) {
937 if (N[k].i > 0 && N[k].i < l_n)
938 A[i - 1][N[k].i - 1] = N[k].value;
946 for (
unsigned int i = 0; i < l_n - 1; i++) {
948 for (
unsigned int k = 0; k < m - 1; k++)
949 sum = sum + A[k][i] * Rk[k].get_i();
952 for (
unsigned int k = 0; k < m - 1; k++)
953 sum = sum + A[k][i] * Rk[k].get_j();
956 for (
unsigned int k = 0; k < m - 1; k++)
970 l_controlPoints.push_back(l_crossingPoints[0]);
971 l_weights.push_back(1.0);
972 for (
unsigned int k = 0; k < l_n - 1; k++) {
974 l_controlPoints.push_back(pt);
975 l_weights.push_back(Pw[k]);
977 l_controlPoints.push_back(l_crossingPoints[m]);
978 l_weights.push_back(1.0);
999 std::vector<vpImagePoint> v_crossingPoints;
1000 l_crossingPoints.
front();
1001 while (!l_crossingPoints.
outside()) {
1004 v_crossingPoints.push_back(pt);
1005 l_crossingPoints.
next();
1025 std::vector<vpImagePoint> v_crossingPoints;
1026 for (std::list<vpImagePoint>::const_iterator it = l_crossingPoints.begin(); it != l_crossingPoints.end(); ++it) {
1027 v_crossingPoints.push_back(*it);
1050 std::vector<vpImagePoint> v_crossingPoints;
1051 for (std::list<vpMeSite>::const_iterator it = l_crossingPoints.begin(); it != l_crossingPoints.end(); ++it) {
1053 v_crossingPoints.push_back(pt);
Used to indicate that a value is not in the allowed range.
Implementation of a matrix and operations on matrices.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
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)
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)
Provide simple list management.
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
error that can be emited by ViSP classes.
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)
void next(void)
position the current element on the next one
static vpBasisFunction ** computeDersBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, std::vector< double > &l_knots)
static unsigned int findSpan(double l_u, unsigned int l_p, std::vector< double > &l_knots)
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)
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
static double sqr(double x)
void front(void)
Position the current element on the first element of the list.
static vpBasisFunction * computeBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, std::vector< double > &l_knots)
type & value(void)
return the value of the current element
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 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 long double comb(unsigned int n, unsigned int p)
void set_ij(double ii, double jj)
Implementation of column vector and the associated operations.
Class that provides tools to compute and manipulate a B-Spline curve.
std::vector< double > weights
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void insert(const vpMatrix &A, unsigned int r, unsigned int c)
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
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)