46
46
inline Coord subdivideArr(Coord t, Coord const *v, Coord *left, Coord *right, unsigned order) {
49
* Evaluate a Bernstein function at a particular parameter value
49
* Evaluate a Bernstein function at a particular parameter value
50
50
* Fill in control points for resulting sub-curves.
54
54
unsigned N = order+1;
55
std::valarray<Coord> vtemp(2*N);
55
std::valarray<Coord> row(N);
56
56
for (unsigned i = 0; i < N; i++)
59
59
// Triangle computation
60
60
const double omt = (1-t);
64
right[order] = vtemp[order];
65
double *prev_row = &vtemp[0];
66
double *row = &vtemp[N];
64
right[order] = row[order];
67
65
for (unsigned i = 1; i < N; i++) {
68
66
for (unsigned j = 0; j < N - i; j++) {
69
row[j] = omt*prev_row[j] + t*prev_row[j+1];
67
row[j] = omt*row[j] + t*row[j+1];
74
72
right[order-i] = row[order-i];
75
std::swap(prev_row, row);
79
76
Coord vtemp[order+1][order+1];
97
94
return (vtemp[order][0]);*/
98
inline T bernsteinValueAt(double t, T const *c_, unsigned n) {
103
for(unsigned i=1; i<n; i++){
106
tmp = (tmp + tn*bc*c_[i])*u;
108
return (tmp + tn*t*c_[n]);
225
236
//inline Coord const &operator[](unsigned ix) const { return c_[ix]; }
226
237
inline void setPoint(unsigned ix, double val) { c_[ix] = val; }
228
/* This is inelegant, as it uses several extra stores. I think there might be a way to
229
* evaluate roughly in situ. */
240
* The size of the returned vector equals n_derivs+1.
231
242
std::vector<Coord> valueAndDerivatives(Coord t, unsigned n_derivs) const {
232
std::vector<Coord> val_n_der;
243
/* This is inelegant, as it uses several extra stores. I think there might be a way to
244
* evaluate roughly in situ. */
246
// initialize return vector with zeroes, such that we only need to replace the non-zero derivs
247
std::vector<Coord> val_n_der(n_derivs + 1, Coord(0.0));
249
// initialize temp storage variables
233
250
std::valarray<Coord> d_(order()+1);
234
unsigned nn = n_derivs + 1; // the size of the result vector equals n_derivs+1 ...
236
nn = order()+1; // .. but with a maximum of order() + 1!
237
for(unsigned i = 0; i < size(); i++)
251
for (unsigned i = 0; i < size(); i++) {
239
for(unsigned di = 0; di < nn; di++) {
240
val_n_der.push_back(subdivideArr(t, &d_[0], NULL, NULL, order() - di));
241
for(unsigned i = 0; i < order() - di; i++) {
255
unsigned nn = n_derivs + 1;
256
if(n_derivs > order()) {
257
nn = order()+1; // only calculate the non zero derivs
259
for (unsigned di = 0; di < nn; di++) {
260
//val_n_der[di] = (subdivideArr(t, &d_[0], NULL, NULL, order() - di));
261
val_n_der[di] = bernsteinValueAt(t, &d_[0], order() - di);
262
for (unsigned i = 0; i < order() - di; i++) {
242
263
d_[i] = (order()-di)*(d_[i+1] - d_[i]);
245
val_n_der.resize(n_derivs);
246
267
return val_n_der;
257
278
find_bernstein_roots(&const_cast<std::valarray<Coord>&>(c_)[0], order(), solutions, 0, 0.0, 1.0);
258
279
return solutions;
281
std::vector<double> roots(Interval const ivl) const {
282
std::vector<double> solutions;
283
find_bernstein_roots(&const_cast<std::valarray<Coord>&>(c_)[0], order(), solutions, 0, ivl[0], ivl[1]);