00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _GOBSPLINE_H
00034 #define _GOBSPLINE_H
00035
00036 #include <vector>
00037 #include "Values.h"
00038 #include "Streamable.h"
00039
00040 #ifdef NDEBUG
00041 #define CHECK(object)
00042 #else
00043 #define CHECK(object) (object)->check()
00044 #endif
00045
00046 namespace Go
00047 {
00050
00051
00057 class BsplineBasis : public Streamable
00058 {
00059 public:
00061 BsplineBasis()
00062 : num_coefs_(0), order_(0), last_knot_interval_(0)
00063 {
00064 }
00065
00072 template <typename RandomIterator>
00073 BsplineBasis(int number,
00074 int order,
00075 RandomIterator knotstart)
00076 : num_coefs_(number), order_(order),
00077 knots_(knotstart, knotstart + number + order),
00078 last_knot_interval_(order - 1)
00079 {
00080 check();
00081 }
00082
00089 template <typename RandomIterator>
00090 BsplineBasis(int order,
00091 RandomIterator knotstart,
00092 RandomIterator knotend)
00093 : num_coefs_(knotend - knotstart - order), order_(order),
00094 knots_(knotstart, knotend),
00095 last_knot_interval_(order - 1)
00096 {
00097 check();
00098 }
00099
00101 virtual ~BsplineBasis();
00102
00103
00108 template <typename RandomIterator>
00109 void setData(int number, int order, RandomIterator knotstart)
00110 {
00111 num_coefs_ = number;
00112 order_ = order;
00113 knots_.clear();
00114 knots_.insert(knots_.end(), knotstart, knotstart + number + order);
00115 last_knot_interval_ = order - 1;
00116 }
00117
00120 void swap(BsplineBasis& other);
00121
00124 virtual void read(std::istream& is);
00125
00128 virtual void write(std::ostream& os) const;
00129
00132 virtual void read_bin(std::istream& is);
00133
00136 virtual void write_bin(std::ostream& os) const;
00137
00140 int knotInterval(double t) const;
00141
00151 std::vector<double> computeBasisValues(double t, int derivs=0) const;
00152
00164 void computeBasisValues(double t,
00165 double* basisvals_start,
00166 int derivs = 0,
00167 double resolution=1.0e-12) const;
00168
00194 void computeBasisValues(const double* parvals_start,
00195 const double* parvals_end,
00196 double* basisvals_start,
00197 int* knotinter_start,
00198 int derivs = 0) const;
00199
00203 std::vector<double> computeBasisValuesLeft(double tval, int derivs ) const;
00204
00212 void computeBasisValuesLeft(double tval,
00213 double* basisvals_start,
00214 int derivs,
00215 double resolution=1.0e-12) const;
00216
00220 void computeBasisValuesLeft(const double* parvals_start,
00221 const double* parvals_end,
00222 double* basisvals_start,
00223 int* knotinter_start,
00224 int derivs) const;
00225
00228 void reverseParameterDirection();
00229
00233 void rescale (double new_start, double new_end);
00234
00237 void insertKnot(double apar);
00238
00244 int knotIntervalFuzzy(double& t, double tol = DEFAULT_PARAMETER_EPSILON) const;
00245
00248 void insertKnot(const std::vector<double>& new_knots);
00249
00254 void removeKnot(double old_knot);
00255
00258 inline int lastKnotInterval() const;
00259
00264 inline double grevilleParameter(int index) const;
00265
00270 int knotMultiplicity(const double parval) const;
00271
00276 int endMultiplicity(bool atstart) const;
00277
00281 bool isKreg() const
00282 {
00283 return (endMultiplicity(true) == order_ &&
00284 endMultiplicity(false) == order_);
00285 }
00286
00292 void coefsAffectingParam(double tpar, int& first_coef, int& last_coef) const;
00293
00296 int numCoefs() const
00297 { return num_coefs_; }
00298
00301 int order() const
00302 { return order_; }
00303
00306 double startparam() const
00307 { return knots_[order_-1]; }
00308
00311 double endparam() const
00312 { return knots_[num_coefs_]; }
00313
00316 std::vector<double>::const_iterator begin() const
00317 { return knots_.begin(); }
00318
00321 std::vector<double>::const_iterator end() const
00322 { return knots_.end(); }
00323
00326 std::vector<double>::iterator begin()
00327 { return knots_.begin(); }
00330 std::vector<double>::iterator end()
00331 { return knots_.end(); }
00332
00334 void check() const;
00335
00336
00337 BsplineBasis subBasis(double tmin, double tmax, double knot_diff_tol = 1e-05) const;
00338
00339 private:
00340
00341 int num_coefs_;
00342 int order_;
00343 std::vector<double> knots_;
00344 mutable int last_knot_interval_;
00345
00346
00347 };
00348
00349
00350 inline int BsplineBasis::lastKnotInterval() const
00351 {
00352 return last_knot_interval_;
00353 }
00354
00355
00356 inline double BsplineBasis::grevilleParameter(int index) const
00357 {
00358 double greville = 0.0;
00359 for (int i = 1; i < order(); ++i)
00360 greville += knots_[index+i];
00361
00362 return greville/(order() - 1.0);
00363 }
00364
00365
00367 }
00368
00369
00370 #endif // This is what is 'ended': #ifndef _GOBspline_H
00371