/* * split the curve at the midpoint, returning an array with the two parts * Temporary storage is minimized by using part of the storage for the result * to hold an intermediate value until it is no longer needed. */ void split(vector<Point> const &p, double t, vector<Point> &left, vector<Point> &right) { const unsigned sz = p.size(); //Geom::Point Vtemp[sz][sz]; vector<vector<Point> > Vtemp(sz); for ( size_t i = 0; i < sz; ++i ) Vtemp[i].reserve(sz); /* Copy control points */ std::copy(p.begin(), p.end(), Vtemp[0].begin()); /* Triangle computation */ for (unsigned i = 1; i < sz; i++) { for (unsigned j = 0; j < sz - i; j++) { Vtemp[i][j] = lerp(t, Vtemp[i-1][j], Vtemp[i-1][j+1]); } } left.resize(sz); right.resize(sz); for (unsigned j = 0; j < sz; j++) left[j] = Vtemp[j][0]; for (unsigned j = 0; j < sz; j++) right[j] = Vtemp[sz-1-j][j]; }
/* * Bezier : * Evaluate a Bezier curve at a particular parameter value * Fill in control points for resulting sub-curves. * */ static Geom::Point Bezier(Geom::Point const *V, /* Control pts */ unsigned degree, /* Degree of bezier curve */ double t, /* Parameter value */ Geom::Point *Left, /* RETURN left half ctl pts */ Geom::Point *Right) /* RETURN right half ctl pts */ { //Geom::Point Vtemp[degree+1][degree+1]; std::vector<std::vector<Geom::Point> > Vtemp(degree+1); for ( size_t i = 0; i < degree + 1; ++i ) Vtemp.reserve(degree+1); /* Copy control points */ std::copy(V, V+degree+1, Vtemp[0].begin()); /* Triangle computation */ for (unsigned i = 1; i <= degree; i++) { for (unsigned j = 0; j <= degree - i; j++) { Vtemp[i][j] = lerp(t, Vtemp[i-1][j], Vtemp[i-1][j+1]); } } for (unsigned j = 0; j <= degree; j++) Left[j] = Vtemp[j][0]; for (unsigned j = 0; j <= degree; j++) Right[j] = Vtemp[degree-j][j]; return (Vtemp[degree][0]); }
QPointF evaluate(qreal t, BezierSegment *left, BezierSegment *right) const { int deg = degree(); if (! deg) return QPointF(); QVector<QVector<QPointF> > Vtemp(deg + 1); for (int i = 0; i <= deg; ++i) Vtemp[i].resize(deg + 1); /* Copy control points */ for (int j = 0; j <= deg; j++) { Vtemp[0][j] = points[j]; } /* Triangle computation */ for (int i = 1; i <= deg; i++) { for (int j =0 ; j <= deg - i; j++) { Vtemp[i][j].rx() = (1.0 - t) * Vtemp[i-1][j].x() + t * Vtemp[i-1][j+1].x(); Vtemp[i][j].ry() = (1.0 - t) * Vtemp[i-1][j].y() + t * Vtemp[i-1][j+1].y(); } } if (left) { left->setDegree(deg); for (int j = 0; j <= deg; j++) { left->setPoint(j, Vtemp[j][0]); } } if (right) { right->setDegree(deg); for (int j = 0; j <= deg; j++) { right->setPoint(j, Vtemp[deg-j][j]); } } return (Vtemp[deg][0]); }