void snlKnotVector::truncate ( knot param, bool keepLast )
{
    // Truncate knot vector.
    // ---------------------
    // param:    Parameter to truncate at.
    // keepLast: Keep last section of knot vector, discard first part.
    //
    // Notes:    Truncates at last of knots valued at param.
    //           Assumes degree knots are present at param.
    
    unsigned start, end;    
    
    if ( keepLast )
    {
        start = findSpan ( param );
        start = getPreviousSpan ( start ) + 1;  // Go to start of knots if more than one at param.
        end = vectorSize - 1;        
    }
    else
    {
        start = 0;
        end = findSpan ( param );        
    }
    
    // Generate new knot vector and populate.
    
    unsigned newSize = end - start + 2;  // Add one point for correct clamping.
    
    knot* newKnots = new knot [ newSize ];
    
    unsigned copyFrom = start;
    
    if ( keepLast )
    {
        for ( unsigned index = 1; index < newSize; index ++, copyFrom ++ )
            newKnots [ index ] = knots [ copyFrom ];
            
        newKnots [ 0 ] = param;
    }
    else
    {
        for ( unsigned index = 0; index < newSize - 1; index ++, copyFrom ++ )
            newKnots [ index ] = knots [ copyFrom ];
        
        newKnots [ newSize - 1 ] = param;
    }    
        
    delete[] knots;
    
    knots = newKnots;
    
    vectorSize = newSize;    
}
void snlKnotVector::insertKnot ( knot param, int numTimes )
{
    // Insert new knot into vector.
    // ----------------------------
    // param:       knot to insert.
    // numTimes:    Number of times to insert knot into vector.

    unsigned        index;

    if ( ! knots ) return;

    unsigned span = findSpan ( param );

    knot* newKnots = new knot [ vectorSize + numTimes ];

    // Copy up to insertion point.
    for ( index = 0; index <= span; index ++ )
        newKnots [ index ] = knots [ index ];

    // Add in new knot.
    for ( int count = 0; count < numTimes; count ++ )
        newKnots [ span + count + 1 ] = param;

    // Copy rest of old knots to new vector.
    for ( index = span + numTimes + 1; index < vectorSize + numTimes; index ++ )
        newKnots [ index ] = knots [ index - numTimes ];

    delete[] knots;

    knots = newKnots;

    vectorSize += numTimes;
}
static Vertex InterpolateNurbs(Curve *Curve, double u, int derivee)
{
  double Nb[1000];
  int span = findSpan(u, Curve->degre, List_Nbr(Curve->Control_Points), Curve->k);
  basisFuns(u, span, Curve->degre, Curve->k, Nb);
  Vertex p;
  p.Pos.X = p.Pos.Y = p.Pos.Z = p.w = p.lc = 0.0;
  for(int i = Curve->degre; i >= 0; --i) {
    Vertex *v;
    List_Read(Curve->Control_Points, span - Curve->degre + i, &v);
    p.Pos.X += Nb[i] * v->Pos.X;
    p.Pos.Y += Nb[i] * v->Pos.Y;
    p.Pos.Z += Nb[i] * v->Pos.Z;
    p.w += Nb[i] * v->w;
    p.lc += Nb[i] * v->lc;
  }
  return p;
}
int snlKnotVector::findMultiplicity ( knot param ) const
{
    // Find the knot multiplicity at a particular knot value.
    // ------------------------------------------------------
    // param:       Parameter to evaluate.
    //
    // Returns:     Number of knots found.
    
    // Find span parameter belongs to.
    unsigned span = findSpan ( param );
    
    // Find value of knot associated with span.
    knot spanKnotVal = val ( span );
    
    // Return multiplicity.
    if ( param == spanKnotVal )    
        return findMultiplicity ( span );
    
    return 0;        
}
Beispiel #5
0
/*!
  Compute the nonvanishing basis functions at \f$ u \f$. All the basis functions are stored in an array such as :
  
  N = \f$ N_{i,0}(u) \f$, \f$ N_{i-1,1}(u) \f$, \f$ N_{i,1}(u) \f$, ... , \f$ N_{i-k,k}(u) \f$, ..., \f$ N_{i,k}(u) \f$, ... , \f$ N_{i-p,p}(u) \f$, ... , \f$ N_{i,p}(u) \f$
  
  where i the number of the knot interval in which \f$ u \f$ lies.
  
  \param u : A real number which is between the extrimities of the knot vector
  
  \return An array containing the nonvanishing basis functions at \f$ u \f$. The size of the array is \f$ p +1 \f$.
*/
vpBasisFunction* vpBSpline::computeBasisFuns(double u)
{
  unsigned int i = findSpan(u);
  return computeBasisFuns(u, i, p ,knots);
}
Beispiel #6
0
/*!
  Find the knot interval in which the parameter \f$ u \f$ lies. Indeed \f$ u \in [u_i, u_{i+1}[ \f$ 
  
   Example : The knot vector is the following \f$ U = \{0,  0 , 1 , 2 ,3 , 3\} \f$ with \f$ p \f$ is equal to 1. 
    - For \f$ u \f$ equal to 0.5 the method will retun 1.
    - For \f$ u \f$ equal to 2.5 the method will retun 3. 
    - For \f$ u \f$ equal to 3 the method will retun 3.
	
  \param u : The knot whose knot interval is seeked.
  
  \return the number of the knot interval in which \f$ u \f$ lies.
*/
unsigned int 
vpBSpline::findSpan(double u)
{
  return findSpan( u, p, knots);
}
basis* snlKnotVector::evalBasisDeriv ( knot param, int deriv )
{
    // Evaluate basis functions and their derivatives.
    // -----------------------------------------------
    //
    // param:       Parameter to process at.
    // deriv:       Which derivative to process to.
    //
    // Returns:     Two dimensional array of basis and basis derivative values.
    //
    // Notes:       The calling function is responsible for deleting the returned array
    //              using delete[]. The size of the array is [ deriv + 1 ] [ deg + 1 ].    

    basis*      right = new basis [ deg + 1 ];
    basis*      left = new basis [ deg + 1 ];
    basis       saved, temp;
    basis*      derivSaved = new basis [ deriv ];
    unsigned    index, level;
    int         count;
    
    basis* bVals = new basis [ ( deriv + 1 ) * ( deg + 1 ) ];
    
    unsigned spanIndex = findSpan ( param );

    unsigned         overFlow;  // Just in case deriv is bigger than degree.

    if ( deriv > deg )
    {
        overFlow = deriv - deg;
        deriv = deg;
    }
    else
        overFlow = 0;

    bVals [ 0 ] = 1.0;

    for ( level = 1; level <= (unsigned) deg; level ++ )
    {
        left [ level ] = param - knots [ spanIndex + 1 - level ];
        right [ level ] = knots [ spanIndex + level ] - param;

        saved = 0.0;

        for ( count = 0; count < deriv; count ++ )
            derivSaved [ count ] = 0.0;

        for ( index = 0; index < level; index ++ )
        {
            temp = bVals [ index ] / ( right [ index + 1 ] + left [ level - index ] );
            bVals [ index ]  = saved + right [ index + 1 ] * temp;
            saved = left [ level - index ] * temp;

            // Process first order derivatives as needed.
            if ( level > (unsigned) ( deg - deriv ) )
            {
                bVals [ index + ( ( deg - level + 1 ) * ( deg + 1 ) ) ] = level * ( derivSaved [ 0 ] - temp );
                derivSaved [ 0 ] = temp;
            }

            // Process other order derivatives.
            for ( count = deg - level + 2; count <= deriv; count ++ )
            {
                temp = bVals [ index + ( count * ( deg + 1 ) ) ] /
                               ( right [ index + 1 ] + left [ level - index ] );

                bVals [ index + ( count * ( deg + 1 ) ) ] = level * ( derivSaved [ count - 1 ] - temp );

                derivSaved [ count - 1 ] = temp;
            }
        }

        bVals [ level ] = saved;

        // Add last first order derivative at this level.
        if ( level > (unsigned) ( deg - deriv ) )
            bVals [ level + ( ( deg - level + 1 ) * ( deg + 1 ) ) ] = level * derivSaved [ 0 ];

        // Add last other order derivatives at this level.
        for ( count = deg - level + 2; count <= deriv; count ++ )
            bVals [ index + ( count * ( deg + 1 ) ) ] = level * derivSaved [ count - 1 ];
    }

    if ( overFlow )
    {
        for ( index = ( deriv + 1 ) * ( deg + 1 ); index < ( deriv + overFlow + 1 ) * ( deg + 1 ); index ++ )
            bVals [ index ] = 0.0;
    }

    delete[] left;
    delete[] right;
    delete[] derivSaved;
    
    return bVals;
}
basis* snlKnotVector::evalBasis ( knot param )
{

    // Evaluate Basis Functions
    // ------------------------
    // param:       Paramater value to process at.
    //
    // Returns:     Array of basis function values, evaluated at param.
    //
    // Notes:       The calling function owns the returned array and is responsible for
    //              deleting it using delete[]. The size of the array is always deg + 1.
    
    basis* bVals = new basis [ deg + 1 ];

    if ( param == knots [ 0 ] && kvType == open )
    {
        // First basis function value is 1 the rest are zero.

        bVals [ 0 ] = 1.0;

        for ( int index = 1; index < deg + 1; index ++ )
            bVals [ index ] = 0.0;

        return bVals;
    }

    if ( param == knots [ vectorSize - 1 ] && kvType == open )
    {
        // Last basis function value is 1 the rest are zero.

        bVals [ deg ] = 1.0;

        for ( int index = 0; index < deg; index ++ )
            bVals [ index ] = 0.0;

        return bVals;
    }
    
    unsigned spanIndex = findSpan ( param );

    basis*      right = new basis [ deg + 1 ];
    basis*      left = new basis  [ deg + 1 ];
    basis       saved, temp;
    unsigned    index, level;

    bVals [ 0 ] = 1.0;

    for ( level = 1; level <= (unsigned) deg; level ++ )
    {
        left [ level ] = param - knots [ spanIndex + 1 - level ];
        right [ level ] = knots [ spanIndex + level ] - param;

        saved = 0.0;

        for ( index = 0; index < level; index ++ )
        {
            temp = bVals [ index ] / ( right [ index + 1 ] + left [ level - index ] );
            bVals [ index ] = saved + right [ index + 1 ] * temp;
            saved = left [ level - index ] * temp;
        }

        bVals [ level ] = saved;
    }

    delete[] right;
    delete[] left;

    return bVals;
}
Beispiel #9
0
void NURBSCurve<Real>::refine(Array1D_Real & insknts, Array1D_Vector3 & Qw, Array1D_Real & Ubar )
{
    // Input
    Array1D_Real X		= insknts;
    Array1D_Vector3 Pw	= this->mCtrlPoint;
    Array1D_Real U		= GetKnotVector();

    int s = insknts.size();
    int order = this->GetDegree() + 1;
    int p = order - 1;
    int n = Pw.size() - 1;
    int r = X.size() - 1;
    int m = n+p+1;

    // Output
    Qw.resize	( n+s+1, Vector3(0,0,0) );
    Ubar.resize	( m+s+1, 0 );

    int a = findSpan(n,p,X[0],U);
    int b = findSpan(n,p,X[r],U) + 1;

    int j = 0;
    for(j=0	 ; j<=a-p; j++)  Qw[j]		 = Pw[j];
    for(j=b-1; j<=n	 ; j++)  Qw[j+r+1]	 = Pw[j];
    for(j=0	 ; j<=a	 ; j++)  Ubar[j]	 = U[j];
    for(j=b+p; j<=m	 ; j++)  Ubar[j+r+1] = U[j];

    int i = b+p-1;
    int k = b+p+r;

    Real alfa = 0;

    for (int j=r; j>=0; j--)
    {
        while (X[j] <= U[i] && i > a) {
            Qw[k-p-1] = Pw[i-p-1];
            Ubar[k] = U[i];
            k = k - 1;
            i = i - 1;
        }

        Qw[k-p-1] = Qw[k-p];

        for (int l=1; l<=p; l++)
        {
            int ind = k-p+l;
            alfa = Ubar[k+l] - X[j];
            if (fabs(alfa) == 0.0)
            {
                Qw[ind-1] = Qw[ind];
            }
            else
            {
                alfa = alfa / (Ubar[k+l] - U[i-p+l]);
                Qw[ind-1] = alfa * Qw[ind-1] + (1.0 - alfa) * Qw[ind];
            }
        }
        Ubar[k] = X[j];
        k = k - 1;
    }
}
Beispiel #10
0
int NURBSCurve<Real>::findSpan(Real u)
{
    return findSpan(this->mCtrlPoint.size() - 1, GetDegree(), u, GetKnotVector() );
}
Beispiel #11
0
/*!
  Method which enables to compute a NURBS curve approximating a set of data points.
  
  The data points are approximated thanks to a least square method.
  
  The result of the method is composed by a knot vector, a set of control points and a set of associated weights.
  
  \param l_crossingPoints : The list of data points which have to be interpolated.
  \param l_p : Degree of the NURBS basis functions.
  \param l_n : The desired number of control points. l_n must be under or equal to the number of data points.
  \param l_knots : The knot vector.
  \param l_controlPoints : the list of control points.
  \param l_weights : the list of weights.
*/
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)
{
  l_knots.clear();
  l_controlPoints.clear();
  l_weights.clear();
  unsigned int m = (unsigned int)l_crossingPoints.size()-1;

  double d = 0;
  for(unsigned int k=1; k<=m; k++)
    d = d + distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1);
  
  //Compute ubar
  std::vector<double> ubar;
  ubar.push_back(0.0);
  for(unsigned int k=1; k<m; k++)
    ubar.push_back(ubar[k-1]+distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1)/d);
   ubar.push_back(1.0);

  //Compute the knot vector
  for(unsigned int k = 0; k <= l_p; k++)
    l_knots.push_back(0.0);
  
  d = (double)(m+1)/(double)(l_n-l_p+1);
  
  for(unsigned int j = 1; j <= l_n-l_p; j++)
  {
    double i = floor(j*d);
    double alpha = j*d-i;
    l_knots.push_back((1.0-alpha)*ubar[(unsigned int)i-1]+alpha*ubar[(unsigned int)i]);
  }

  for(unsigned int k = 0; k <= l_p ; k++)
    l_knots.push_back(1.0);

  //Compute Rk
  std::vector<vpImagePoint> Rk;
  vpBasisFunction* N;
  for(unsigned int k = 1; k <= m-1; k++)
  {
    unsigned int span = findSpan(ubar[k], l_p, l_knots);
    if (span == l_p && span == l_n) 
    {
      N = computeBasisFuns(ubar[k], span, l_p, l_knots);
      vpImagePoint pt(l_crossingPoints[k].get_i()-N[0].value*l_crossingPoints[0].get_i()-N[l_p].value*l_crossingPoints[m].get_i(),
		      l_crossingPoints[k].get_j()-N[0].value*l_crossingPoints[0].get_j()-N[l_p].value*l_crossingPoints[m].get_j());
      Rk.push_back(pt);
      delete[] N;
    }
    else if (span == l_p) 
    {
      N = computeBasisFuns(ubar[k], span, l_p, l_knots);
      vpImagePoint pt(l_crossingPoints[k].get_i()-N[0].value*l_crossingPoints[0].get_i(),
		      l_crossingPoints[k].get_j()-N[0].value*l_crossingPoints[0].get_j());
      Rk.push_back(pt);
      delete[] N;
    }
    else if (span == l_n)
    {
      N = computeBasisFuns(ubar[k], span, l_p, l_knots);
      vpImagePoint pt(l_crossingPoints[k].get_i()-N[l_p].value*l_crossingPoints[m].get_i(),
		      l_crossingPoints[k].get_j()-N[l_p].value*l_crossingPoints[m].get_j());
      Rk.push_back(pt);
      delete[] N;
    }
    else
    {
      Rk.push_back(l_crossingPoints[k]);
    }
  }

  vpMatrix A(m-1,l_n-1);
  //Compute A
  for(unsigned int i = 1; i <= m-1; i++)
  {
    unsigned int span = findSpan(ubar[i], l_p, l_knots);
    N = computeBasisFuns(ubar[i], span, l_p, l_knots);
    for (unsigned int k = 0; k <= l_p; k++)
    {
      if (N[k].i > 0 && N[k].i < l_n)
        A[i-1][N[k].i-1] = N[k].value;
    }
    delete[] N;
  }
  
  vpColVector Ri(l_n-1);
  vpColVector Rj(l_n-1);
  vpColVector Rw(l_n-1);
  for (unsigned int i = 0; i < l_n-1; i++)
  {
    double sum =0;
    for (unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]*Rk[k].get_i();
    Ri[i] = sum;
    sum = 0;
    for (unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]*Rk[k].get_j();
    Rj[i] = sum;
    sum = 0;
    for (unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]; //The crossing points weigths are equal to 1.
    Rw[i] = sum;
  }
  
  vpMatrix AtA = A.AtA();
  vpMatrix AtAinv;
  AtA.pseudoInverse(AtAinv);
  
  vpColVector Pi = AtAinv*Ri;
  vpColVector Pj = AtAinv*Rj;
  vpColVector Pw = AtAinv*Rw;
  
  vpImagePoint pt;
  l_controlPoints.push_back(l_crossingPoints[0]);
  l_weights.push_back(1.0);
  for (unsigned int k = 0; k < l_n-1; k++)
  {
    pt.set_ij(Pi[k],Pj[k]);
    l_controlPoints.push_back(pt);
    l_weights.push_back(Pw[k]);
  }
  l_controlPoints.push_back(l_crossingPoints[m]);
  l_weights.push_back(1.0);
}
Beispiel #12
0
/*!
  Method which enables to compute a NURBS curve passing through a set of data points.
  
  The result of the method is composed by a knot vector, a set of control points and a set of associated weights.
  
  \param l_crossingPoints : The list of data points which have to be interpolated.
  \param l_p : Degree of the NURBS basis functions. This value need to be > 0.
  \param l_knots : The knot vector
  \param l_controlPoints : the list of control points.
  \param l_weights : the list of weights.
*/
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)
{
  if (l_p == 0) {
    //vpERROR_TRACE("Bad degree of the NURBS basis functions");
    throw(vpException(vpException::badValue,
                      "Bad degree of the NURBS basis functions")) ;
  }

  l_knots.clear();
  l_controlPoints.clear();
  l_weights.clear();
  unsigned int n = (unsigned int)l_crossingPoints.size()-1;
  unsigned int m = n+l_p+1;

  double d = 0;
  for(unsigned int k=1; k<=n; k++)
    d = d + distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1);
  
  //Compute ubar
  std::vector<double> ubar;
  ubar.push_back(0.0);
  for(unsigned int k=1; k<n; k++)
    ubar.push_back(ubar[k-1]+distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1)/d);
    ubar.push_back(1.0);

  //Compute the knot vector
  for(unsigned int k = 0; k <= l_p; k++)
    l_knots.push_back(0.0);

  double sum  = 0;
  for(unsigned int k = 1; k <= l_p; k++)
    sum = sum + ubar[k];

  //Centripetal method
  for(unsigned int k = 1; k <= n-l_p; k++)
  {
    l_knots.push_back(sum/l_p);
    sum = sum - ubar[k-1] + ubar[l_p+k-1];
  }

  for(unsigned int k = m-l_p; k <= m; k++)
    l_knots.push_back(1.0);
    
  vpMatrix A(n+1,n+1);
  vpBasisFunction* N;

  for(unsigned int i = 0; i <= n; i++)
  {
    unsigned int span = findSpan(ubar[i], l_p, l_knots);
    N = computeBasisFuns(ubar[i], span, l_p, l_knots);
    for (unsigned int k = 0; k <= l_p; k++) A[i][span-l_p+k] = N[k].value;
    delete[] N;
  }
  //vpMatrix Ainv = A.inverseByLU();
  vpMatrix Ainv;
  A.pseudoInverse(Ainv);
  vpColVector Qi(n+1);
  vpColVector Qj(n+1);
  vpColVector Qw(n+1);
  for (unsigned int k = 0; k <= n; k++)
  {
    Qi[k] = l_crossingPoints[k].get_i();
    Qj[k] = l_crossingPoints[k].get_j();
  }
  Qw = 1;
  vpColVector Pi = Ainv*Qi;
  vpColVector Pj = Ainv*Qj;
  vpColVector Pw = Ainv*Qw;

  vpImagePoint pt;
  for (unsigned int k = 0; k <= n; k++)
  {
    pt.set_ij(Pi[k],Pj[k]);
    l_controlPoints.push_back(pt);
    l_weights.push_back(Pw[k]);
  }
}
Beispiel #13
0
/*!
  Insert \f$ l_r \f$ knots in the knot vector.
  
  Of course the knot vector changes. But The list of control points and the list of the associated weights change too.
  
  \param l_x : Several real numbers which are between the extrimities of the knot vector and which have to be inserted.
  \param l_r : Number of knot in the array \f$ l_x \f$.
  \param l_p : Degree of the NURBS basis functions.
  \param l_knots : The knot vector
  \param l_controlPoints : the list of control points.
  \param l_weights : the list of weights.
*/
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)
{
  unsigned int a = findSpan(l_x[0], l_p, l_knots);
  unsigned int b = findSpan(l_x[l_r], l_p, l_knots);
  b++;

  unsigned int n = (unsigned int)l_controlPoints.size();
  unsigned int m = (unsigned int)l_knots.size();

  for (unsigned int j = 0; j < n; j++)
  {
    l_controlPoints[j].set_ij(l_controlPoints[j].get_i()*l_weights[j],l_controlPoints[j].get_j()*l_weights[j]);
  }

  std::vector<double> l_knots_tmp(l_knots);
  std::vector<vpImagePoint> l_controlPoints_tmp(l_controlPoints);
  std::vector<double> l_weights_tmp(l_weights);

  vpImagePoint pt;
  double w = 0;

  for (unsigned int j = 0; j <= l_r; j++)
  {
    l_controlPoints.push_back(pt);
    l_weights.push_back(w);
    l_knots.push_back(w);
  }

  for(unsigned int j = b+l_p; j <= m-1; j++) l_knots[j+l_r+1] = l_knots_tmp[j];

  for (unsigned int j = b-1; j <= n-1; j++)
  {
    l_controlPoints[j+l_r+1] = l_controlPoints_tmp[j];
    l_weights[j+l_r+1] = l_weights_tmp[j];
  } 

  unsigned int i = b+l_p-1;
  unsigned int k = b+l_p+l_r;

  {
    unsigned int j = l_r + 1;
    do{
      j--;
      while(l_x[j] <= l_knots[i] && i > a)
      {
        l_controlPoints[k-l_p-1] = l_controlPoints_tmp[i-l_p-1];
        l_weights[k-l_p-1] = l_weights_tmp[i-l_p-1];
        l_knots[k] = l_knots_tmp[i];
        k--;
        i--;
      }

      l_controlPoints[k-l_p-1] = l_controlPoints[k-l_p];
      l_weights[k-l_p-1] = l_weights[k-l_p];

      for (unsigned int l = 1; l <= l_p; l++)
      {
        unsigned int ind = k-l_p+l;
        double alpha = l_knots[k+l] - l_x[j];
        //if (vpMath::abs(alpha) == 0.0)
	if (std::fabs(alpha) <= std::numeric_limits<double>::epsilon())
	{
          l_controlPoints[ind-1] = l_controlPoints[ind];
          l_weights[ind-1] = l_weights[ind];
        }
        else
        {
          alpha = alpha/(l_knots[k+l]-l_knots_tmp[i-l_p+l]);
          l_controlPoints[ind-1].set_i( alpha * l_controlPoints[ind-1].get_i() + (1.0-alpha) * l_controlPoints[ind].get_i());
          l_controlPoints[ind-1].set_j( alpha * l_controlPoints[ind-1].get_j() + (1.0-alpha) * l_controlPoints[ind].get_j());
          l_weights[ind-1] = alpha * l_weights[ind-1] + (1.0-alpha) * l_weights[ind];
        }
      }
      l_knots[k] = l_x[j];
      k--;
    }while(j != 0);
  }

  for (unsigned int j = 0; j < n; j++)
  {
    l_controlPoints[j].set_ij(l_controlPoints[j].get_i()/l_weights[j],l_controlPoints[j].get_j()/l_weights[j]);
  }
}
Beispiel #14
0
/*!
  Insert \f$ r \f$ times a knot in the \f$ k \f$ th interval of the knot vector. The inserted knot \f$ u \f$ has multiplicity \f$ s \f$.
  
  Of course the knot vector changes. But The list of control points and the list of the associated weights change too.
  
  \param u : A real number which is between the extrimities of the knot vector and which has to be inserted.
  \param s : Multiplicity of \f$ l_u \f$
  \param r : Number of times \f$ l_u \f$ has to be inserted.
*/
void vpNurbs::curveKnotIns(double u, unsigned int s, unsigned int r)
{
  unsigned int i = findSpan(u);
  curveKnotIns(u, i, s, r, p, knots, controlPoints, weights);
}
Beispiel #15
0
/*!
  Compute the kth derivatives of \f$ C(u) \f$ for \f$ k = 0, ... , l_{der} \f$.
  
  To see how the derivatives are computed refers to the Nurbs book.
  
  \param u : A real number which is between the extrimities of the knot vector
  \param der : The last derivative to be computed.
  
  \return an array of size l_der+1 containing the coordinates \f$ C^{(k)}(u) \f$ for \f$ k = 0, ... , der \f$. The kth derivative is in the kth cell of the array.
*/
vpImagePoint* vpNurbs::computeCurveDersPoint(double u, unsigned int der)
{
  unsigned int i = findSpan(u);
  return computeCurveDersPoint(u, i, p, der, knots, controlPoints, weights);
}
Beispiel #16
0
int	pmqlso(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
	char		*mqName = (char *) a1;
	uvast		remoteEngineId = a2 != 0 ? strtouvast((char *) a2) : 0;
#else
int	main(int argc, char *argv[])
{
	char		*mqName = argc > 1 ? argv[1] : NULL;
	uvast		remoteEngineId = argc > 2 ? strtouvast(argv[2]) : 0;
#endif
	Sdr		sdr;
	LtpVspan	*vspan;
	PsmAddress	vspanElt;
	struct mq_attr	mqAttributes = { 0, PMQLSA_MAXMSG, PMQLSA_MSGSIZE, 0 };
	mqd_t		mq;
	int		running;
	int		segmentLength;
	char		*segment;

	if (remoteEngineId == 0 || mqName == NULL)
	{
		puts("Usage: pmqlso <message queue name> <remote engine ID>");
		return 0;
	}

	/*	Note that ltpadmin must be run before the first
	 *	invocation of ltplso, to initialize the LTP database
	 *	(as necessary) and dynamic database.			*/

	if (ltpInit(0) < 0)
	{
		putErrmsg("pmqlso can't initialize LTP.", NULL);
		return 1;
	}

	sdr = getIonsdr();
	CHKERR(sdr_begin_xn(sdr));	/*	Just to lock memory.	*/
	findSpan(remoteEngineId, &vspan, &vspanElt);
	if (vspanElt == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("No such engine in database.", itoa(remoteEngineId));
		return 1;
	}

	if (vspan->lsoPid > 0 && vspan->lsoPid != sm_TaskIdSelf())
	{
		sdr_exit_xn(sdr);
		putErrmsg("LSO task is already started for this span.",
				itoa(vspan->lsoPid));
		return 1;
	}

	/*	All command-line arguments are now validated.		*/

	sdr_exit_xn(sdr);
	mq = mq_open(mqName, O_RDWR | O_CREAT, 0777, &mqAttributes);
	if (mq == (mqd_t) -1)
	{
		putSysErrmsg("pmqlso can't open message queue", mqName);
		return 1;
	}

	oK(_pmqlsoSemaphore(&vspan->segSemaphore));
	isignal(SIGTERM, interruptThread);

	/*	Can now begin transmitting to remote engine.		*/

	writeMemo("[i] pmqlso is running.");
	running = 1;
	while (running && !(sm_SemEnded(_pmqlsoSemaphore(NULL))))
	{
		segmentLength = ltpDequeueOutboundSegment(vspan, &segment);
		if (segmentLength < 0)
		{
			running = 0;	/*	Terminate LSO.		*/
			continue;
		}

		if (segmentLength == 0)	/*	Interrupted.		*/
		{
			continue;
		}

		if (segmentLength > PMQLSA_MSGSIZE)
		{
			putErrmsg("Segment is too big for PMQ LSO.",
					itoa(segmentLength));
			running = 0;	/*	Terminate LSO.		*/
			continue;
		}

		if (sendSegmentByPMQ(mq, segment, segmentLength) < 0)
		{
			putSysErrmsg("pmqlso failed sending segment", mqName);
			running = 0;	/*	Terminate LSO.	*/
			continue;
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	mq_close(mq);
	writeErrmsgMemos();
	writeMemo("[i] pmqlso duct has ended.");
	ionDetach();
	return 0;
}