00001
00015 #ifndef _KNOTVECTORS_H
00016 #define _KNOTVECTORS_H
00017
00018 #include <iterator>
00019 #include <vector>
00020 #include <error.H>
00021 #include <ListAssignment.H>
00022
00023 using namespace std;
00024
00025 namespace xchen
00026 {
00027 template<int dims>
00028 class KnotVectorIterator;
00029
00031 template<int dims>
00032 class KnotVector
00033 {
00034 typedef KnotVectorIterator<dims> iterator;
00035 typedef ListAssignmentCheckSzRt<double, iterator> lst_asg_t;
00036 iterator Begin() { return KnotVectorIterator<dims>(*this); }
00037 public:
00038 void Insert(double u, int i=0);
00039 int UpperBound(double u, int& repeat, int i=0);
00040
00041 vector<double>& operator[](int i) { return kv[i]; }
00042 vector<double>const& operator[](int i) const { return kv[i]; }
00043 double& operator()(int j, int i=0) { return kv[i][j]; }
00044 void operator=(double* v) { copy(v, v+totalSz(), Begin()); }
00045 lst_asg_t operator=(double v) { kv[0].front() = v; return lst_asg_t(++Begin(), totalSz()-1); }
00046
00047 void Clear() { ForEachIofDims kv[i].clear(); }
00048
00049 friend ostream& operator<< <>(ostream&os, KnotVector const&);
00050
00051 private:
00052 vector<double> kv[dims];
00053
00054 int totalSz()
00055 {
00056 int totalsz = 0;
00057 for(int i=0; i<dims; i++)
00058 totalsz += kv[i].size();
00059 return totalsz;
00060 }
00061 };
00062
00063 template<int dims>
00064 void KnotVector<dims> :: Insert(double u, int i)
00065 {
00066 kv[i].insert( find_if( kv[i].begin(), kv[i].end(),bind2nd(greater_equal<double>(), u) ), u);
00067 }
00068 template<int dims>
00069 int KnotVector<dims> :: UpperBound(double u, int& repeat, int i)
00070 {
00071 int j = 0;
00072 while(u > kv[i][j] && j < kv[i].size()) j++;
00073 for(repeat = 0; u == kv[i][j]; j++, repeat++);
00074 return j;
00075 }
00076
00077 template<int dims>
00078 class KnotVectorIterator
00079 {
00080 KnotVector<dims>& kv;
00081 vector<double>::iterator itr;
00082 public:
00083 KnotVectorIterator(KnotVector<dims>& _kv) : kv(_kv), itr(kv[0].begin()) { }
00084 double& operator*() { return *itr; }
00085
00086 KnotVectorIterator& operator++()
00087 {
00088 for(int i=0; i<dims; i++)
00089 {
00090 if(itr == kv[i].end())
00091 {
00092 if(i==dims-1) error_exit("knotvector iterator passed the end.\n");
00093 itr = kv[i+1].begin();
00094 break;
00095 }
00096 }
00097 ++itr;
00098 return *this;
00099 }
00100 };
00101
00102
00103 template<int dims>
00104 ostream& operator<<(ostream&os, KnotVector<dims>const& kv)
00105 {
00106 for(int i=dims-1; i>=0; i--)
00107 {
00108 os << "[";
00109 copy(kv[i].begin(), kv[i].end()-1, ostream_iterator<double>(os, " "));
00110 os << kv[i].back() << "]\t";
00111 }
00112 os << endl;
00113 return os;
00114 }
00115
00116
00117 }
00118
00119
00120 #endif