SBasis dotp(Point const& p, D2<SBasis> const& c) { SBasis d; d.resize(c[X].size()); for ( unsigned int i = 0; i < c[0].size(); ++i ) { for( unsigned int j = 0; j < 2; ++j ) d[i][j] = p[X] * c[X][i][j] + p[Y] * c[Y][i][j]; } return d; }
SBasis integral(SBasis const &c) { SBasis a; a.resize(c.size() + 1, Linear(0,0)); a[0] = Linear(0,0); for(unsigned k = 1; k < c.size() + 1; k++) { double ahat = -c[k-1].tri()/(2*k); a[k][0] = a[k][1] = ahat; } double aTri = 0; for(int k = c.size()-1; k >= 0; k--) { aTri = (c[k].hat() + (k+1)*aTri/2)/(2*k+1); a[k][0] -= aTri/2; a[k][1] += aTri/2; } a.normalize(); return a; }
//-Sqrt---------------------------------------------------------- static Piecewise<SBasis> sqrt_internal(SBasis const &f, double tol, int order){ SBasis sqrtf; if(f.isZero() || order == 0){ return Piecewise<SBasis>(sqrtf); } if (f.at0()<-tol*tol && f.at1()<-tol*tol){ return sqrt_internal(-f,tol,order); }else if (f.at0()>tol*tol && f.at1()>tol*tol){ sqrtf.resize(order+1, Linear(0,0)); sqrtf[0] = Linear(std::sqrt(f[0][0]), std::sqrt(f[0][1])); SBasis r = f - multiply(sqrtf, sqrtf); // remainder for(unsigned i = 1; int(i) <= order && i<r.size(); i++) { Linear ci(r[i][0]/(2*sqrtf[0][0]), r[i][1]/(2*sqrtf[0][1])); SBasis cisi = shift(ci, i); r -= multiply(shift((sqrtf*2 + cisi), i), SBasis(ci)); r.truncate(order+1); sqrtf[i] = ci; if(r.tailError(i) == 0) // if exact break; } }else{ sqrtf = Linear(std::sqrt(fabs(f.at0())), std::sqrt(fabs(f.at1()))); } double err = (f - multiply(sqrtf, sqrtf)).tailError(0); if (err<tol){ return Piecewise<SBasis>(sqrtf); } Piecewise<SBasis> sqrtf0,sqrtf1; sqrtf0 = sqrt_internal(compose(f,Linear(0.,.5)),tol,order); sqrtf1 = sqrt_internal(compose(f,Linear(.5,1.)),tol,order); sqrtf0.setDomain(Interval(0.,.5)); sqrtf1.setDomain(Interval(.5,1.)); sqrtf0.concat(sqrtf1); return sqrtf0; }
/** Changes the basis of p to be sbasis. \param p the Bernstein basis polynomial \returns the Symmetric basis polynomial if the degree is even q is the order in the symmetrical power basis, if the degree is odd q is the order + 1 n is always the polynomial degree, i. e. the Bezier order */ void bezier_to_sbasis (SBasis & sb, Bezier const& bz) { size_t n = bz.order(); size_t q = (n+1) / 2; size_t even = (n & 1u) ? 0 : 1; sb.clear(); sb.resize(q + even, Linear(0, 0)); double Tjk; for (size_t k = 0; k < q; ++k) { for (size_t j = k; j < q; ++j) { Tjk = sgn(j, k) * binomial(n-j-k, j-k) * binomial(n, k); sb[j][0] += (Tjk * bz[k]); sb[j][1] += (Tjk * bz[n-k]); // n-j <-> [j][1] } for (size_t j = k+1; j < q; ++j) { Tjk = sgn(j, k) * binomial(n-j-k-1, j-k-1) * binomial(n, k); sb[j][0] += (Tjk * bz[n-k]); sb[j][1] += (Tjk * bz[k]); // n-j <-> [j][1] } } if (even) { for (size_t k = 0; k < q; ++k) { Tjk = sgn(q,k) * binomial(n, k); sb[q][0] += (Tjk * (bz[k] + bz[n-k])); } sb[q][0] += (binomial(n, q) * bz[q]); sb[q][1] = sb[q][0]; } sb[0][0] = bz[0]; sb[0][1] = bz[n]; }