44 #include <visp/vpNurbs.h>
45 #include <visp/vpColVector.h>
55 double distancew = w1 -w2;
101 std::vector<double> &l_knots,
102 std::vector<vpImagePoint> &l_controlPoints,
103 std::vector<double> &l_weights)
105 vpBasisFunction* N = NULL;
112 for(
unsigned int j = 0; j <= l_p; j++)
114 ic = ic + N[j].value * (l_controlPoints[l_i-l_p+j]).get_i() * l_weights[l_i-l_p+j];
115 jc = jc + N[j].value * (l_controlPoints[l_i-l_p+j]).get_j() * l_weights[l_i-l_p+j];
116 wc = wc + N[j].value * l_weights[l_i-l_p+j];
122 if (N != NULL)
delete[] N;
136 vpBasisFunction* N = NULL;
143 for(
unsigned int j = 0; j <= p; j++)
145 ic = ic + N[j].value * (controlPoints[N[0].i+j]).get_i() *
weights[N[0].i+j];
146 jc = jc + N[j].value * (controlPoints[N[0].i+j]).get_j() *
weights[N[0].i+j];
147 wc = wc + N[j].value *
weights[N[0].i+j];
153 if (N != NULL)
delete[] N;
182 unsigned int l_p,
unsigned int l_der,
183 std::vector<double> &l_knots,
184 std::vector<vpImagePoint> &l_controlPoints,
185 std::vector<double> &l_weights)
188 vpBasisFunction** N = NULL;
191 for(
unsigned int k = 0; k <= l_der; k++)
193 derivate[k][0] = 0.0;
194 derivate[k][1] = 0.0;
195 derivate[k][2] = 0.0;
197 for(
unsigned int j = 0; j<= l_p; j++)
199 derivate[k][0] = derivate[k][0] + N[k][j].value*(l_controlPoints[l_i-l_p+j]).get_i();
200 derivate[k][1] = derivate[k][1] + N[k][j].value*(l_controlPoints[l_i-l_p+j]).get_j();
201 derivate[k][2] = derivate[k][2] + N[k][j].value*(l_weights[l_i-l_p+j]);
206 for(
unsigned int i = 0; i <= l_der; i++)
232 vpBasisFunction** N = NULL;
235 for(
unsigned int k = 0; k <= der; k++)
237 derivate[k][0] = 0.0;
238 derivate[k][1] = 0.0;
239 derivate[k][2] = 0.0;
240 for(
unsigned int j = 0; j<= p; j++)
242 derivate[k][0] = derivate[k][0] + N[k][j].value*(controlPoints[N[0][0].i-p+j]).get_i();
243 derivate[k][1] = derivate[k][1] + N[k][j].value*(controlPoints[N[0][0].i-p+j]).get_j();
244 derivate[k][2] = derivate[k][2] + N[k][j].value*(
weights[N[0][0].i-p+j]);
248 if (N!=NULL)
delete[] N;
271 unsigned int l_p,
unsigned int l_der,
272 std::vector<double> &l_knots,
273 std::vector<vpImagePoint> &l_controlPoints,
274 std::vector<double> &l_weights)
276 std::vector<vpImagePoint> A;
278 for(
unsigned int j = 0; j < l_controlPoints.size(); j++)
280 pt = l_controlPoints[j];
291 for(
unsigned int k = 0; k <= l_der; k++)
295 for(
unsigned int j = 1; j <= k; j++)
297 double tmpComb =
static_cast<double>(
vpMath::comb(k,j) );
298 ic = ic - tmpComb*Awders[k][2]*(CK[k-j].
get_i());
299 jc = jc - tmpComb*Awders[j][2]*(CK[k-j].
get_j());
301 CK[k].
set_ij(ic/Awders[0][2],jc/Awders[0][2]);
338 void vpNurbs::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)
341 std::vector<vpImagePoint>::iterator it1;
342 std::vector<double>::iterator it2;
346 for (
unsigned int j = 0; j <= l_p-l_s; j++)
348 Rw[j][0] = (l_controlPoints[l_k-l_p+j]).get_i() * l_weights[l_k-l_p+j];
349 Rw[j][1] = (l_controlPoints[l_k-l_p+j]).get_j() * l_weights[l_k-l_p+j];
350 Rw[j][2] = l_weights[l_k-l_p+j];
353 it1 = l_controlPoints.begin();
354 l_controlPoints.
insert(it1+(
int)l_k-(
int)l_s, l_r, pt);
355 it2 = l_weights.begin();
356 l_weights.insert(it2+(
int)l_k-(
int)l_s, l_r, w);
360 for (
unsigned int j = 1; j <= l_r; j++)
364 for (
unsigned int i = 0; i <=l_p-j-l_s; i++)
366 alpha = (l_u - l_knots[L+i])/(l_knots[i+l_k+1] - l_knots[L+i]);
367 Rw[i][0]= alpha*Rw[i+1][0]+(1.0-alpha)*Rw[i][0];
368 Rw[i][1]= alpha*Rw[i+1][1]+(1.0-alpha)*Rw[i][1];
369 Rw[i][2]= alpha*Rw[i+1][2]+(1.0-alpha)*Rw[i][2];
372 pt.
set_ij(Rw[0][0]/Rw[0][2],Rw[0][1]/Rw[0][2]);
373 l_controlPoints[L] = pt;
374 l_weights[L] = Rw[0][2];
376 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]);
377 l_controlPoints[l_k+l_r-j-l_s] = pt;
378 l_weights[l_k+l_r-j-l_s] = Rw[l_p-j-l_s][2];
381 for(
unsigned int j = L+1; j < l_k-l_s; j++)
383 pt.
set_ij(Rw[j-L][0]/Rw[j-L][2],Rw[j-L][1]/Rw[j-L][2]);
384 l_controlPoints[j] = pt;
385 l_weights[j] = Rw[j-L][2];
388 it2 = l_knots.begin();
389 l_knots.
insert(it2+(
int)l_k, l_r, l_u);
421 void vpNurbs::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)
423 unsigned int a =
findSpan(l_x[0], l_p, l_knots);
424 unsigned int b =
findSpan(l_x[l_r], l_p, l_knots);
427 unsigned int n = (
unsigned int)l_controlPoints.size();
428 unsigned int m = (
unsigned int)l_knots.size();
430 for (
unsigned int j = 0; j < n; j++)
432 l_controlPoints[j].set_ij(l_controlPoints[j].get_i()*l_weights[j],l_controlPoints[j].get_j()*l_weights[j]);
435 std::vector<double> l_knots_tmp(l_knots);
436 std::vector<vpImagePoint> l_controlPoints_tmp(l_controlPoints);
437 std::vector<double> l_weights_tmp(l_weights);
442 for (
unsigned int j = 0; j <= l_r; j++)
444 l_controlPoints.push_back(pt);
445 l_weights.push_back(w);
446 l_knots.push_back(w);
449 for(
unsigned int j = b+l_p; j <= m-1; j++) l_knots[j+l_r+1] = l_knots_tmp[j];
451 for (
unsigned int j = b-1; j <= n-1; j++)
453 l_controlPoints[j+l_r+1] = l_controlPoints_tmp[j];
454 l_weights[j+l_r+1] = l_weights_tmp[j];
457 unsigned int i = b+l_p-1;
458 unsigned int k = b+l_p+l_r;
461 unsigned int j = l_r + 1;
464 while(l_x[j] <= l_knots[i] && i > a)
466 l_controlPoints[k-l_p-1] = l_controlPoints_tmp[i-l_p-1];
467 l_weights[k-l_p-1] = l_weights_tmp[i-l_p-1];
468 l_knots[k] = l_knots_tmp[i];
473 l_controlPoints[k-l_p-1] = l_controlPoints[k-l_p];
474 l_weights[k-l_p-1] = l_weights[k-l_p];
476 for (
unsigned int l = 1; l <= l_p; l++)
478 unsigned int ind = k-l_p+l;
479 double alpha = l_knots[k+l] - l_x[j];
481 if (std::fabs(alpha) <= std::numeric_limits<double>::epsilon())
483 l_controlPoints[ind-1] = l_controlPoints[ind];
484 l_weights[ind-1] = l_weights[ind];
488 alpha = alpha/(l_knots[k+l]-l_knots_tmp[i-l_p+l]);
489 l_controlPoints[ind-1].
set_i( alpha * l_controlPoints[ind-1].get_i() + (1.0-alpha) * l_controlPoints[ind].get_i());
490 l_controlPoints[ind-1].set_j( alpha * l_controlPoints[ind-1].get_j() + (1.0-alpha) * l_controlPoints[ind].get_j());
491 l_weights[ind-1] = alpha * l_weights[ind-1] + (1.0-alpha) * l_weights[ind];
499 for (
unsigned int j = 0; j < n; j++)
501 l_controlPoints[j].set_ij(l_controlPoints[j].get_i()/l_weights[j],l_controlPoints[j].get_j()/l_weights[j]);
542 vpNurbs::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)
544 unsigned int n = (
unsigned int)l_controlPoints.size();
545 unsigned int m = n + l_p + 1;
547 for (
unsigned int j = 0; j < n; j++)
549 l_controlPoints[j].set_ij(l_controlPoints[j].get_i()*l_weights[j],l_controlPoints[j].get_j()*l_weights[j]);
552 unsigned int ord = l_p + 1;
553 double fout = (2*l_r-l_s-l_p)/2;
554 unsigned int last = l_r - l_s;
555 unsigned int first = l_r - l_p;
556 unsigned int tblSize = 2*l_p+1;
558 double *tempW =
new double[tblSize];
563 unsigned int i, j, ii, jj;
565 for(t = 0; t < l_num; t++)
567 unsigned int off = first - 1;
568 tempP[0] = l_controlPoints[off];
569 tempW[0] = l_weights[off];
570 tempP[last+1-off] = l_controlPoints[last+1];
571 tempW[last+1-off] = l_weights[last+1];
579 alfi = (l_u - l_knots[i])/(l_knots[i+ord+t]-l_knots[i]);
580 alfj = (l_u - l_knots[j-t])/(l_knots[j+ord]-l_knots[j-t]);
581 pt.
set_i((l_controlPoints[i].get_i()-(1.0-alfi)*tempP[ii-1].get_i())/alfi);
582 tempP[ii].
set_i((l_controlPoints[i].get_i()-(1.0-alfi)*tempP[ii-1].get_i())/alfi);
583 tempP[ii].
set_j((l_controlPoints[i].get_j()-(1.0-alfi)*tempP[ii-1].get_j())/alfi);
584 tempW[ii] = ((l_weights[i]-(1.0-alfi)*tempW[ii-1])/alfi);
585 tempP[jj].
set_i((l_controlPoints[j].get_i()-alfj*tempP[jj+1].get_i())/(1.0-alfj));
586 tempP[jj].
set_j((l_controlPoints[j].get_j()-alfj*tempP[jj+1].get_j())/(1.0-alfj));
587 tempW[jj] = ((l_weights[j]-alfj*tempW[jj+1])/(1.0-alfj));
596 double distancei = tempP[ii-1].
get_i() - tempP[jj+1].
get_i();
597 double distancej = tempP[ii-1].
get_j() - tempP[jj+1].
get_j();
598 double distancew = tempW[ii-1] - tempW[jj+1];
600 if(distance <= l_TOL) remflag = 1;
604 alfi = (l_u - l_knots[i])/(l_knots[i+ord+t]-l_knots[i]);
605 double distancei = l_controlPoints[i].get_i() - (alfi*tempP[ii+t+1].
get_i()+(1.0-alfi)*tempP[ii-1].get_i());
606 double distancej = l_controlPoints[i].get_j() - (alfi*tempP[ii+t+1].
get_j()+(1.0-alfi)*tempP[ii-1].get_j());
607 double distancew = l_weights[i] - (alfi*tempW[ii+t+1]+(1.0-alfi)*tempW[ii-1]);
609 if(distance <= l_TOL) remflag = 1;
611 if (remflag == 0)
break;
618 l_controlPoints[i].set_i(tempP[i-off].get_i());
619 l_controlPoints[i].set_j(tempP[i-off].get_j());
620 l_weights[i] = tempW[i-off];
621 l_controlPoints[j].set_i(tempP[j-off].get_i());
622 l_controlPoints[j].set_j(tempP[j-off].get_j());
623 l_weights[j] = tempW[j-off];
636 for(
unsigned int k = l_r+1; k <= m; k++) l_knots[k-t] = l_knots[k];
637 j = (
unsigned int)fout;
639 for(
unsigned int k = 1; k< t; k++)
644 for(
unsigned int k = i+1; k <= n; k++)
646 l_controlPoints[j].
set_i(l_controlPoints[k].get_i());
647 l_controlPoints[j].set_j(l_controlPoints[k].get_j());
648 l_weights[j] = l_weights[k];
651 for(
unsigned int k = 0; k < t; k++)
653 l_knots.erase(l_knots.end()-1);
654 l_controlPoints.erase(l_controlPoints.end()-1);
657 for(
unsigned int k = 0; k < l_controlPoints.size(); k++)
658 l_controlPoints[k].set_ij(l_controlPoints[k].get_i()/l_weights[k],l_controlPoints[k].get_j()/l_weights[k]);
700 void vpNurbs::globalCurveInterp(std::vector<vpImagePoint> &l_crossingPoints,
unsigned int l_p, std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights)
705 "Bad degree of the NURBS basis functions")) ;
709 l_controlPoints.clear();
711 unsigned int n = (
unsigned int)l_crossingPoints.size()-1;
712 unsigned int m = n+l_p+1;
715 for(
unsigned int k=1; k<=n; k++)
716 d = d + distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1);
719 std::vector<double> ubar;
721 for(
unsigned int k=1; k<n; k++)
722 ubar.push_back(ubar[k-1]+distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1)/d);
726 for(
unsigned int k = 0; k <= l_p; k++)
727 l_knots.push_back(0.0);
730 for(
unsigned int k = 1; k <= l_p; k++)
734 for(
unsigned int k = 1; k <= n-l_p; k++)
736 l_knots.push_back(sum/l_p);
737 sum = sum - ubar[k-1] + ubar[l_p+k-1];
740 for(
unsigned int k = m-l_p; k <= m; k++)
741 l_knots.push_back(1.0);
746 for(
unsigned int i = 0; i <= n; i++)
748 unsigned int span =
findSpan(ubar[i], l_p, l_knots);
750 for (
unsigned int k = 0; k <= l_p; k++) A[i][span-l_p+k] = N[k].value;
759 for (
unsigned int k = 0; k <= n; k++)
761 Qi[k] = l_crossingPoints[k].get_i();
762 Qj[k] = l_crossingPoints[k].get_j();
770 for (
unsigned int k = 0; k <= n; k++)
773 l_controlPoints.push_back(pt);
774 l_weights.push_back(Pw[k]);
787 std::vector<vpImagePoint> v_crossingPoints;
788 l_crossingPoints.
front();
792 v_crossingPoints.push_back(pt);
793 l_crossingPoints.
next();
794 while(!l_crossingPoints.
outside())
796 s = l_crossingPoints.
value();
800 v_crossingPoints.push_back(pt);
803 l_crossingPoints.
next();
817 std::vector<vpImagePoint> v_crossingPoints;
818 for(std::list<vpImagePoint>::const_iterator it=l_crossingPoints.begin(); it!=l_crossingPoints.end(); ++it){
819 v_crossingPoints.push_back(*it);
834 std::vector<vpImagePoint> v_crossingPoints;
835 vpMeSite s = l_crossingPoints.front();
838 v_crossingPoints.push_back(pt);
839 std::list<vpMeSite>::const_iterator it = l_crossingPoints.begin();
841 for(; it!=l_crossingPoints.end(); ++it){
844 v_crossingPoints.push_back(pt_tmp);
876 void vpNurbs::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)
879 l_controlPoints.clear();
881 unsigned int m = (
unsigned int)l_crossingPoints.size()-1;
884 for(
unsigned int k=1; k<=m; k++)
885 d = d + distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1);
888 std::vector<double> ubar;
890 for(
unsigned int k=1; k<m; k++)
891 ubar.push_back(ubar[k-1]+distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1)/d);
895 for(
unsigned int k = 0; k <= l_p; k++)
896 l_knots.push_back(0.0);
898 d = (double)(m+1)/(double)(l_n-l_p+1);
901 for(
unsigned int j = 1; j <= l_n-l_p; j++)
903 double i = floor(j*d);
905 l_knots.push_back((1.0-alpha)*ubar[(
unsigned int)i-1]+alpha*ubar[(
unsigned int)i]);
908 for(
unsigned int k = 0; k <= l_p ; k++)
909 l_knots.push_back(1.0);
912 std::vector<vpImagePoint> Rk;
914 for(
unsigned int k = 1; k <= m-1; k++)
916 unsigned int span =
findSpan(ubar[k], l_p, l_knots);
917 if (span == l_p && span == l_n)
920 vpImagePoint pt(l_crossingPoints[k].get_i()-N[0].value*l_crossingPoints[0].get_i()-N[l_p].value*l_crossingPoints[m].get_i(),
921 l_crossingPoints[k].get_j()-N[0].value*l_crossingPoints[0].get_j()-N[l_p].value*l_crossingPoints[m].get_j());
925 else if (span == l_p)
928 vpImagePoint pt(l_crossingPoints[k].get_i()-N[0].value*l_crossingPoints[0].get_i(),
929 l_crossingPoints[k].get_j()-N[0].value*l_crossingPoints[0].get_j());
933 else if (span == l_n)
936 vpImagePoint pt(l_crossingPoints[k].get_i()-N[l_p].value*l_crossingPoints[m].get_i(),
937 l_crossingPoints[k].get_j()-N[l_p].value*l_crossingPoints[m].get_j());
943 Rk.push_back(l_crossingPoints[k]);
949 for(
unsigned int i = 1; i <= m-1; i++)
951 unsigned int span =
findSpan(ubar[i], l_p, l_knots);
953 for (
unsigned int k = 0; k <= l_p; k++)
955 if (N[k].i > 0 && N[k].i < l_n)
956 A[i-1][N[k].i-1] = N[k].value;
965 for (
unsigned int i = 0; i < l_n-1; i++)
968 for (
unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]*Rk[k].get_i();
971 for (
unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]*Rk[k].get_j();
974 for (
unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i];
987 l_controlPoints.push_back(l_crossingPoints[0]);
988 l_weights.push_back(1.0);
989 for (
unsigned int k = 0; k < l_n-1; k++)
992 l_controlPoints.push_back(pt);
993 l_weights.push_back(Pw[k]);
995 l_controlPoints.push_back(l_crossingPoints[m]);
996 l_weights.push_back(1.0);
1017 std::vector<vpImagePoint> v_crossingPoints;
1018 l_crossingPoints.
front();
1019 while(!l_crossingPoints.
outside())
1023 v_crossingPoints.push_back(pt);
1024 l_crossingPoints.
next();
1041 std::vector<vpImagePoint> v_crossingPoints;
1042 for(std::list<vpImagePoint>::const_iterator it=l_crossingPoints.begin(); it!=l_crossingPoints.end(); ++it){
1043 v_crossingPoints.push_back(*it);
1066 std::vector<vpImagePoint> v_crossingPoints;
1067 for(std::list<vpMeSite>::const_iterator it=l_crossingPoints.begin(); it!=l_crossingPoints.end(); ++it){
1069 v_crossingPoints.push_back(pt);
1087 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1099 std::vector<vpImagePoint> v_crossingPoints;
1100 l_crossingPoints.
front();
1101 while(!l_crossingPoints.
outside())
1103 v_crossingPoints.push_back(l_crossingPoints.
value());
1104 l_crossingPoints.
next();
1123 std::vector<vpImagePoint> v_crossingPoints;
1124 l_crossingPoints.
front();
1125 while(!l_crossingPoints.
outside())
1127 v_crossingPoints.push_back(l_crossingPoints.
value());
1128 l_crossingPoints.
next();
Definition of the vpMatrix class.
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
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)
void set_i(const double ii)
void insert(const vpMatrix &A, const unsigned int r, const unsigned int c)
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)
void set_j(const double jj)
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)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Class that provides tools to compute and manipulate a B-Spline curve.
std::vector< double > weights
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_ij(const double ii, const double jj)
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)