From 6e10127665388a4723d8bfde28a407b02113bd59 Mon Sep 17 00:00:00 2001 From: joncruz Date: Wed, 14 Oct 2009 07:18:26 +0000 Subject: [PATCH] Applying second patch for bug #425557. --- src/2geom/bezier.h | 33 +++++++++++++++++++++------------ src/2geom/d2.h | 8 ++++---- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/2geom/bezier.h b/src/2geom/bezier.h index 1fe846935..9e68d93ae 100644 --- a/src/2geom/bezier.h +++ b/src/2geom/bezier.h @@ -46,7 +46,7 @@ namespace Geom { inline Coord subdivideArr(Coord t, Coord const *v, Coord *left, Coord *right, unsigned order) { /* * Bernstein : - * Evaluate a Bernstein function at a particular parameter value + * Evaluate a Bernstein function at a particular parameter value * Fill in control points for resulting sub-curves. * */ @@ -236,25 +236,34 @@ public: //inline Coord const &operator[](unsigned ix) const { return c_[ix]; } inline void setPoint(unsigned ix, double val) { c_[ix] = val; } - /* This is inelegant, as it uses several extra stores. I think there might be a way to - * evaluate roughly in situ. */ - + /** + * The size of the returned vector equals n_derivs+1. + */ std::vector valueAndDerivatives(Coord t, unsigned n_derivs) const { - std::vector val_n_der; + /* This is inelegant, as it uses several extra stores. I think there might be a way to + * evaluate roughly in situ. */ + + // initialize return vector with zeroes, such that we only need to replace the non-zero derivs + std::vector val_n_der(n_derivs + 1, Coord(0.0)); + + // initialize temp storage variables std::valarray d_(order()+1); - unsigned nn = n_derivs + 1; // the size of the result vector equals n_derivs+1 ... - if(nn > order()) - nn = order()+1; // .. but with a maximum of order() + 1! - for(unsigned i = 0; i < size(); i++) + for (unsigned i = 0; i < size(); i++) { d_[i] = c_[i]; - val_n_der.resize(nn); - for(unsigned di = 0; di < nn; di++) { + } + + unsigned nn = n_derivs + 1; + if(n_derivs > order()) { + nn = order()+1; // only calculate the non zero derivs + } + for (unsigned di = 0; di < nn; di++) { //val_n_der[di] = (subdivideArr(t, &d_[0], NULL, NULL, order() - di)); val_n_der[di] = bernsteinValueAt(t, &d_[0], order() - di); - for(unsigned i = 0; i < order() - di; i++) { + for (unsigned i = 0; i < order() - di; i++) { d_[i] = (order()-di)*(d_[i+1] - d_[i]); } } + return val_n_der; } diff --git a/src/2geom/d2.h b/src/2geom/d2.h index afa00b40d..547d8c658 100644 --- a/src/2geom/d2.h +++ b/src/2geom/d2.h @@ -97,10 +97,10 @@ class D2{ } std::vector valueAndDerivatives(double t, unsigned n) const { std::vector x = f[X].valueAndDerivatives(t, n), - y = f[Y].valueAndDerivatives(t, n); - std::vector res; - for(unsigned i = 0; i <= n; i++) { - res.push_back(Point(x[i], y[i])); + y = f[Y].valueAndDerivatives(t, n); // always returns a vector of size n+1 + std::vector res(n+1); + for (unsigned i = 0; i <= n; i++) { + res[i] = Point(x[i], y[i]); } return res; } -- 2.30.2