+void BSplineImpl::spanPolesAndWeights(int theSpanIndex,
+ double* theDerivParam,
+ std::vector<GCS::DeriVector2>& thePoles,
+ std::vector<double>& theWeights) const
+{
+ thePoles.reserve(degree + 1);
+ theWeights.reserve(degree + 1);
+ for (int i = theSpanIndex; i <= theSpanIndex + degree; ++i) {
+ // optimization: weighted pole
+ int idx = i % (int)poles.size();
+ thePoles.push_back(GCS::DeriVector2(poles[idx], theDerivParam).mult(*weights[idx]));
+ theWeights.push_back(*weights[idx]);
+ }
+}
+
+void BSplineImpl::performDeBoor(double theU,
+ int theSpanIndex,
+ std::vector<GCS::DeriVector2>& thePoles,
+ std::vector<double>& theWeights,
+ GCS::DeriVector2& theValue,
+ GCS::DeriVector2& theDerivative) const
+{
+ std::vector<GCS::DeriVector2> aPDeriv(thePoles.size(), DeriVector2());
+ std::vector<double> aWDeriv(theWeights.size(), 0.0);
+ for (int i = 0; i < degree; ++i) {
+ for (int j = degree; j > i; --j) {
+ double denom = (myFlatKnots[theSpanIndex + j + degree - i] -
+ myFlatKnots[theSpanIndex + j]);
+ double a = (theU - myFlatKnots[theSpanIndex + j]) / denom;
+ aPDeriv[j] = aPDeriv[j].linCombi(a, aPDeriv[j - 1], 1.0 - a).sum(
+ thePoles[j].subtr(thePoles[j - 1]).mult(1.0 / denom));
+ aWDeriv[j] = aWDeriv[j] * a + aWDeriv[j - 1] * (1.0 - a)
+ + (theWeights[j] - theWeights[j - 1]) / denom;
+ thePoles[j] = thePoles[j].linCombi(a, thePoles[j - 1], 1.0 - a);
+ theWeights[j] = theWeights[j] * a + theWeights[j - 1] * (1.0 - a);
+ }
+ }
+ double w = 1 / theWeights[degree];
+ theValue = thePoles[degree].mult(w);
+ theDerivative = aPDeriv[degree].subtr(theValue.mult(aWDeriv[degree])).mult(w);