Horus Doc || C++ Reference || Class Overview   Pixels   Images   Detector   Geometry   Registry || Doxygen's quick Index  

HxBSplineCurve Class Reference

Class definition for BSpline curves. More...

#include <HxBSplineCurve.h>

List of all members.

Public Methods

 HxBSplineCurve ()
 Construct default curve. More...

 HxBSplineCurve (const HxBSplineBasis &basis, const HxPointSetR2 &cp)
 Construct a curve with given basis and control points. More...

 ~HxBSplineCurve ()
 Destructor. More...

int ident () const
 Get the identifier. More...

HxBSplineBasis basis () const
 Get the basis. More...

HxBSplineType curveType () const
 Get the curve type. More...

int degree () const
 Get the degree of the curve. More...

double minT () const
 Get the minimum value of T. More...

double maxT () const
 Get the maximum value of T. More...

HxBSplineInterval getInterval (double t1, double t2) const
 Get the curve interval determined by t1, t2. More...

int numP () const
 Get the number of control points. More...

HxPointR2 P (int i) const
 Get the coordinates of control point i. More...

HxPointSetR2 allP () const
 Get the coordinates of all control points. More...

HxPolyline2d controlP () const
 Get the control polygon. More...

double B (int i, double t) const
 Get the value of basis i at path position t. More...

double dB (int order, int i, double t) const
 Get derivative of basis i at path position t. More...

HxBSplineInterval pathAffectedBy (int index) const
 Get the curve interval affected by given control point. More...

vector< int > PThatAffectCAt (double t) const
 Get the indices of control points that affect the curve at path position t. More...

vector< int > PThatAffectCAt (const HxBSplineInterval &interval) const
 Get the indices of control points that affect the curve inside given interval. More...

HxPointR2 C (double t) const
 Get the curve point at path position t. More...

HxVectorR2 dC (int order, double t) const
 Get the curve derivative at path position t. More...

double kAtC (double t) const
 Get curvature at path position t. More...

double dTurnAngleAtC (double t) const
 Get derivative of turning angle at path position t. More...

double length (int n=50) const
 Get the total curve length based on distance between the given number of samples (n). More...

double length (const HxBSplineInterval &interval, int n=50) const
 Get the length of the given curve interval. More...

HxPointR2 center () const
 Get the center of control polygon. More...

HxPolyline2d sampleC (int n=50) const
 Sample the curve at n points. More...

HxBSplineCurve changeAllP (const HxPointSetR2 &p) const
 Replace the coordinates of all control points. More...

HxBSplineCurve translateAllP (const HxVectorR2 &v) const
 Translate all control points. More...

HxBSplineCurve scaleAllP (double s) const
 Scale control polygon using center as origin. More...

HxBSplineCurve translateCurve (const HxVectorR2 &v, double t) const
 Translate the given point in the curve in the given direction modifying only one control point (NURBS book p.511-513). More...

HxBSplineCurve translateCurve (const HxPointR2 &pDest, double t) const
 Translate the given point in the curve to the given position modifying only one control point (NURBS book p.511-513). More...

HxBSplineCurve translateCurve2 (const HxVectorR2 &v, double t) const
 Translate the given point in the curve to the given position modifying two control points (NURBS book p.511-513). More...

HxBSplineCurve insertKnot (double t, int n=1) const
 Insert a given number of knots in the curve with corresponding control point without changing parametrization and geometry. More...

STD_OSTREAM & dump (STD_OSTREAM &) const
 Dump the curve on the given stream. More...


Static Public Methods

HxBSplineCurve makeUniform (HxPolyline2d cp, int degree)
 Make a curve with uniform knots. More...

HxBSplineCurve makeInterpolating (HxPolyline2d cp)
 Make an interpolating curve (uniform knots). More...


Detailed Description

Class definition for BSpline curves.

Based on "Curve and Surface Fitting with Splines", by "Dierckx,P.", "Oxford", "1993", chapter "Univariate Splines", and "The NURBS book", "Piegl, L. and Tiller, W.", Springer, 1997.


Constructor & Destructor Documentation

HxBSplineCurve::HxBSplineCurve  
 

Construct default curve.

00021 {
00022     _ident = _nr++;
00023     makeDefault();
00024 }

HxBSplineCurve::HxBSplineCurve const HxBSplineBasis   basis,
const HxPointSetR2 &    vectorOfCP
 

Construct a curve with given basis and control points.

00027                                     : _basis(basis)
00028 {
00029     _ident = _nr++;
00030     if ( vectorOfCP.size() != numP() ) {
00031         message("(constructor) invalid number of control points - making default");
00032         makeDefault();
00033     }
00034     else
00035         _PVec = vectorOfCP;
00036 }

HxBSplineCurve::~HxBSplineCurve  
 

Destructor.

00064 {
00065 }


Member Function Documentation

HxBSplineCurve HxBSplineCurve::makeUniform HxPolyline2d    cp,
int    degree
[static]
 

Make a curve with uniform knots.

00040 {
00041     HxBSplineType type = (cp.getClosed())? closed : openRepeatEndPoints;
00042     HxPointSetR2 p = cp.getPoints();
00043 
00044     int nInt; 
00045     if (cp.getClosed()) 
00046         nInt = p.size();
00047     else
00048         nInt = p.size() - degree;
00049 
00050     HxBSplineBasis base(type, degree, nInt, uniformKnots, 0, 1);
00051     return HxBSplineCurve(base, p);
00052 }

HxBSplineCurve HxBSplineCurve::makeInterpolating HxPolyline2d    cp [static]
 

Make an interpolating curve (uniform knots).

00056 {
00057     HxLocalInterpol interpol(3, cp.getPoints(), cp.getClosed());
00058     HxBSplineType type = (cp.getClosed())? closed : open;
00059     HxBSplineBasis base(type, 3, interpol.allKnots());
00060     return HxBSplineCurve(base, interpol.allP());
00061 }

int HxBSplineCurve::ident   const [inline]
 

Get the identifier.

00200 {
00201     return _ident;
00202 }

HxBSplineBasis HxBSplineCurve::basis   const [inline]
 

Get the basis.

00206 {
00207     return _basis;
00208 }

HxBSplineType HxBSplineCurve::curveType   const [inline]
 

Get the curve type.

00212 {
00213     return _basis.curveType();
00214 }

int HxBSplineCurve::degree   const [inline]
 

Get the degree of the curve.

00218 {
00219     return _basis.degree();
00220 }

double HxBSplineCurve::minT   const [inline]
 

Get the minimum value of T.

00224 { 
00225     return _basis.minT();
00226 }

double HxBSplineCurve::maxT   const [inline]
 

Get the maximum value of T.

00230 { 
00231     return _basis.maxT();
00232 }

HxBSplineInterval HxBSplineCurve::getInterval double    t1,
double    t2
const [inline]
 

Get the curve interval determined by t1, t2.

00236 {
00237     return HxBSplineInterval(t1, t2,
00238         _basis.minT(), _basis.maxT(), _basis.curveType());
00239 } 

int HxBSplineCurve::numP   const [inline]
 

Get the number of control points.

00261 { 
00262     return _basis.numB();
00263 }

HxPointR2 HxBSplineCurve::P int    i const [inline]
 

Get the coordinates of control point i.

00267 {
00268     if ( i < 0 || i >= numP() ) {
00269         message("(P) invalid index - setting to 0");
00270         i = 0;
00271     }
00272     return _PVec[i];
00273 }

HxPointSetR2 HxBSplineCurve::allP   const [inline]
 

Get the coordinates of all control points.

00277 {
00278     return _PVec;
00279 }

HxPolyline2d HxBSplineCurve::controlP   const [inline]
 

Get the control polygon.

00283 {
00284     return HxPolyline2d(_PVec, (curveType() == closed));
00285 }

double HxBSplineCurve::B int    i,
double    t
const [inline]
 

Get the value of basis i at path position t.

00243 {
00244     return _basis.B(i, t);
00245 }

double HxBSplineCurve::dB int    order,
int    i,
double    t
const [inline]
 

Get derivative of basis i at path position t.

00249 {
00250     return _basis.dB(order, i, t);
00251 }

HxBSplineInterval HxBSplineCurve::pathAffectedBy int    index const [inline]
 

Get the curve interval affected by given control point.

00255 {
00256     return _basis.pathAffectedBy(index);
00257 }

vector< int > HxBSplineCurve::PThatAffectCAt double    t const
 

Get the indices of control points that affect the curve at path position t.

00073 {
00074     if ( t < minT() ) {
00075         message("(PThatAffectCAt) invalid t - setting to minT()");
00076         t = minT();
00077     }
00078     if ( t >= maxT() ) {
00079         message("(PThatAffectCAt) invalid t - setting near to maxT()");
00080         t = maxT() - EPS;
00081     }
00082 
00083     vector<int> b;
00084     int index = _basis.whichInterval(t);
00085     for ( int i=index; i <= index + degree(); i++)
00086         b.push_back(indexPVec(i));
00087 
00088     return b;
00089 }

vector< int > HxBSplineCurve::PThatAffectCAt const HxBSplineInterval   interval const
 

Get the indices of control points that affect the curve inside given interval.

00097 {
00098     int i = indexPVec(_basis.whichInterval(interval.begin()));
00099     int f = indexPVec(_basis.whichInterval(interval.end()) + degree());
00100 
00101     vector<int> b;
00102     while (i != f) {
00103         b.push_back(indexPVec(i));
00104         if ( ++i >= numP() )
00105             i = 0;      // wrap closed curve
00106     };
00107     b.push_back(indexPVec(f));
00108     return b;
00109 }

HxPointR2 HxBSplineCurve::C double    t const [inline]
 

Get the curve point at path position t.

00295 {
00296     HxVectorR2 tmp = dC( 0, t);
00297     return HxPointR2(tmp.x(), tmp.y());
00298 }

HxVectorR2 HxBSplineCurve::dC int    order,
double    t
const
 

Get the curve derivative at path position t.

00121 {
00122     if ( t < minT() ) {
00123         message("(dC) invalid t - setting to minT()");
00124         t = minT();
00125     }
00126     if ( t >= maxT() ) {
00127         message("(dC) invalid t - setting near to maxT()");
00128         t = maxT() - EPS;
00129     }
00130     if ( ! inRange(order, 0, degree()-1) ) {
00131         message("(dC) derivative not defined - fixing to 1st");
00132         order = 1;
00133     }
00134 
00135     double multterm = 1;
00136     int i;
00137     for (i = 1 ; i <= order ; i++)
00138         multterm *= (degree()+1-i);
00139 
00140     int index = _basis.whichInterval(t);
00141     double sumtermx = 0, sumtermy = 0;
00142     for (i = index+order ; i <= index + degree(); i++) {
00143         double nterm = _basis.nim(t,i,degree()+1-order);
00144         HxPointR2 cterm = civ(i,order);
00145         sumtermx += cterm.x() * nterm;
00146         sumtermy += cterm.y() * nterm;
00147     }
00148 
00149     return HxVectorR2(multterm*sumtermx, multterm*sumtermy);
00150 }

double HxBSplineCurve::kAtC double    t const
 

Get curvature at path position t.

00158 {
00159     if ( degree() <= 2 ) {
00160         message("(kAtC) can't compute curvature - returning 0");
00161         return 0;
00162     }
00163     
00164     HxVectorR2 d1 = dC(1,t);
00165     HxVectorR2 d2 = dC(2,t);
00166     double l2 = d1.squaredMagnitude();
00167     double l = sqrt(l2);
00168     return (d1.x() * d2.y() - d2.x() * d1.y()) / (l * l2);
00169 }

double HxBSplineCurve::dTurnAngleAtC double    t const
 

Get derivative of turning angle at path position t.

00177 {
00178     if ( degree() <= 2 ) {
00179         message("(dTurnAngleAtC) can't compute curvature - returning 0");
00180         return 0;
00181     }
00182 
00183     HxVectorR2 d1 = dC(1,t);
00184     HxVectorR2 d2 = dC(2,t);
00185     double l2 = d1.squaredMagnitude();
00186     return (d1.x() * d2.y() - d2.x() * d1.y()) / l2;
00187 }

double HxBSplineCurve::length int    np = 50 const
 

Get the total curve length based on distance between the given number of samples (n).

00231 {
00232     double length = 0.0;
00233     double d = (maxT()-EPS - minT() ) / np;
00234 
00235     if ( degree() > 1 ) {
00236         for ( double t = minT(); t < maxT(); t+= d)
00237             length += dC(1,t).magnitude();
00238         return length*d;
00239     } else  {
00240         HxPointR2 p1 = C(minT());
00241         for ( double t = minT(); t < maxT(); t+= d) {
00242             HxPointR2 p2 = C(t);
00243             HxVectorR2 v(p2,p1);
00244             length += v.magnitude();
00245             p1 = p2;
00246         }
00247         if ( curveType() == closed ) {
00248             HxVectorR2 v(C(minT()), p1);
00249             length += v.magnitude();
00250         }
00251         return length;
00252     }
00253 }

double HxBSplineCurve::length const HxBSplineInterval   part,
int    np = 50
const
 

Get the length of the given curve interval.

00197 {
00198     double length = 0.0;
00199     double d = part.length()/ np;
00200 
00201     if ( degree() > 1 ) {
00202         double t=part.begin();
00203         for ( int i=0; i < np; i++) {
00204             length += dC(1,t).magnitude();
00205             t=part.next(t, d);
00206         }
00207         return length*d;
00208     } else  {
00209         HxPointR2 p1 = C(part.begin());
00210         HxPointR2 p2;
00211         double t= part.next(part.begin(),d);
00212         for ( int i=0; i < np; i++) {
00213             p2 = C(t);
00214             HxVectorR2 v(p2,p1);
00215             length += v.magnitude();
00216             p1 = p2;
00217             t=part.next(t, d);
00218         }
00219         return length;
00220     }
00221 }

HxPointR2 HxBSplineCurve::center   const
 

Get the center of control polygon.

00278 {
00279     double sumX=0, sumY=0;
00280     for (int i=0; i < _PVec.size(); i++) {
00281         sumX += _PVec[i].x();
00282         sumY += _PVec[i].y();
00283     }
00284     return HxPointR2( sumX/_PVec.size(), sumY/_PVec.size());
00285 }

HxPolyline2d HxBSplineCurve::sampleC int    np = 50 const
 

Sample the curve at n points.

00261 {
00262     double d = (maxT()-EPS - minT() ) / np;
00263     HxPointSetR2 c;
00264     HxPointR2 p1 = C(minT());
00265     for (double t=minT() ; t<maxT() ; t+=d) {
00266         c.push_back(C(t));
00267     }
00268     return HxPolyline2d(c, (curveType() == closed));
00269 }

HxBSplineCurve HxBSplineCurve::changeAllP const HxPointSetR2 &    p const [inline]
 

Replace the coordinates of all control points.

00289 {
00290     return HxBSplineCurve(_basis, p);
00291 }

HxBSplineCurve HxBSplineCurve::translateAllP const HxVectorR2   v const
 

Translate all control points.

00293 {
00294     HxPointSetR2 tmp(_PVec.size());
00295     for (int i=0; i < tmp.size(); i++) {
00296         tmp[i] = _PVec[i].add(v);
00297     }
00298     return HxBSplineCurve( _basis, tmp);
00299 }

HxBSplineCurve HxBSplineCurve::scaleAllP double    s const
 

Scale control polygon using center as origin.

00309 {
00310     HxPointSetR2 tmp(_PVec.size());
00311     HxPointR2 origin(center());
00312     for (int i=0; i < tmp.size(); i++) {
00313         HxVectorR2 v(_PVec[i],origin);
00314         tmp[i] =  origin.add(v.mul(s));
00315     }
00316     return HxBSplineCurve( _basis, tmp);
00317 }

HxBSplineCurve HxBSplineCurve::translateCurve const HxVectorR2   vec,
double    t
const
 

Translate the given point in the curve in the given direction modifying only one control point (NURBS book p.511-513).

00329 {
00330     HxBSplineCurve tmp(*this);
00331     if ( absolute(basis().nearestKnot(t)-t) > EPS )
00332         tmp= insertKnot(t);
00333 
00334         // determine CP to move and vector
00335     int i = tmp._basis.maxBasis(t);
00336     double d = vec.magnitude();
00337     double alpha =  d / tmp._basis.B(i, t);
00338     HxVectorR2 V = vec.div(d).mul(alpha);
00339 
00340         // update control point
00341     int index = tmp.indexPVec(i);
00342     tmp._PVec[index] = tmp._PVec[index].add(V);
00343 
00344     return tmp;
00345 }

HxBSplineCurve HxBSplineCurve::translateCurve const HxPointR2   pDest,
double    t
const [inline]
 

Translate the given point in the curve to the given position modifying only one control point (NURBS book p.511-513).

00302 {
00303     return translateCurve( HxVectorR2(pDest, C(t)), t);
00304 }

HxBSplineCurve HxBSplineCurve::translateCurve2 const HxVectorR2   vec,
double    t
const
 

Translate the given point in the curve to the given position modifying two control points (NURBS book p.511-513).

00357 {
00358     HxBSplineCurve tmp(*this);
00359     HxBSplineBasis tmpBasis(tmp._basis);
00360 
00361         // determine two CP to move
00362     int k = tmpBasis.maxBasis(t);
00363     double kNode =  tmpBasis.node(k);
00364     while ( kNode >= t ) {
00365         k--;
00366         if ( k < 0 )
00367             k = tmpBasis.nIntervals()-1;
00368         kNode =  tmpBasis.node(k);
00369     }
00370 
00371     int k1;
00372     if ( k >= tmpBasis.nIntervals() )
00373         k1 = 0;
00374     else    k1 = k+1;
00375     double k1Node =  tmpBasis.node(k1);
00376 
00377         // determine proportion of each CP
00378     HxBSplineInterval intA( kNode, t, minT(), maxT(), curveType());
00379     HxBSplineInterval intB( kNode, k1Node, minT(), maxT(), curveType());
00380     double l = intA.length() / intB.length();
00381 
00382         // determine motion vector
00383     double d = vec.magnitude();
00384     double alpha =  d / ( (1-l)*tmpBasis.B(k, t) + l*tmpBasis.B(k1, t) );
00385     HxVectorR2 V = vec.div(d).mul(alpha);
00386 
00387         // update control points
00388     int index = tmp.indexPVec(k);
00389     tmp._PVec[index] = tmp._PVec[index].add(V.mul(1-l));
00390     index = tmp.indexPVec(k1);
00391     tmp._PVec[index] = tmp._PVec[index].add(V.mul(l));
00392 
00393     return tmp;
00394 }

HxBSplineCurve HxBSplineCurve::insertKnot double    t,
int    n = 1
const
 

Insert a given number of knots in the curve with corresponding control point without changing parametrization and geometry.

00404 {
00405     if ( t < minT() ) {
00406         message("(insertKnot) invalid knot - setting to minT()");
00407         t = minT();
00408     }
00409     if ( t >= maxT() ) {
00410         message("(insertKnot) invalid knot - setting near to maxT()");
00411         t = maxT() - EPS;
00412     }
00413     if ( n != 1 ) {
00414         message("(insertKnot) multiple knot insertion not supported - inserting 1 knot");
00415         n=1;
00416     }
00417 
00418     HxBSplineBasis newB = _basis.insertKnot(t,n);
00419     HxPointSetR2 newP = _PVec;
00420 
00421     vector<HxVectorR2> aux(degree()+1);
00422     int ii1 = _basis.whichInterval(t);
00423     int ii2 = _basis.internalBasisIndex(ii1,t);
00424     int k = ii2 + degree();
00425     int j =1;
00426     int s =0;   // multiplicity
00427 
00428     int i;
00429     for (i=0; i <= degree()-s; i++) {
00430         HxPointR2 p = newP[indexPVec(k-degree()+i)];
00431         aux[i] = HxVectorR2(p.x(), p.y());
00432     }
00433 
00434     int L = k - degree() + j;
00435 //  newP.insert(newP.begin()+indexPVec(L), n, HxPointR2(0,0));
00436     newP.insert(newP.begin()+L, n, HxPointR2(0,0));
00437     for ( i=0; i <= degree() -j-s; i++) {
00438         double a = (t - _basis._knotsVec[L+i]) / 
00439             (_basis._knotsVec[i+k+1] - _basis._knotsVec[L+i]);
00440         aux[i] = aux[i+1].mul(a).add(aux[i].mul(1.0-a));
00441     }
00442 
00443     HxBSplineCurve tmp(newB, newP);
00444     for ( i=L; i <= k-s; i++ ) {
00445         HxVectorR2 v(aux[i-L]);
00446         tmp._PVec[tmp.indexPVec(i)] = HxPointR2(v.x(), v.y());
00447     }
00448 
00449     return tmp;
00450 }

STD_OSTREAM & HxBSplineCurve::dump STD_OSTREAM &    os const
 

Dump the curve on the given stream.

00458 {
00459     _basis.dump(os);
00460 
00461     if ( _PVec.empty() ) {
00462         os << "\nNo Control Points";
00463     } else {
00464         os << "P Vector: " << _PVec.size() << " points\n";
00465         for ( int i = 0; i < _PVec.size(); i++ ) {
00466             os <<"("<< _PVec[i].x() << ","<<_PVec[i].y()<<") ";
00467         }
00468     }
00469 
00470     os << STD_ENDL;
00471     return os;
00472 }


The documentation for this class was generated from the following files:
Generated on Mon Jan 27 15:48:58 2003 for C++Reference by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001