/** Reparameterise M to have unit speed. \param M the Element. \param tol the maximum error allowed. \param order the maximum degree to use for approximation \relates Piecewise, D2 */ Piecewise<D2<SBasis> > Geom::arc_length_parametrization(D2<SBasis> const &M, unsigned order, double tol){ Piecewise<D2<SBasis> > u; u.push_cut(0); Piecewise<SBasis> s = arcLengthSb(Piecewise<D2<SBasis> >(M),tol); for (unsigned i=0; i < s.size();i++){ double t0=s.cuts[i],t1=s.cuts[i+1]; if ( are_near(s(t0),s(t1)) ) { continue; } D2<SBasis> sub_M = compose(M,Linear(t0,t1)); D2<SBasis> sub_u; for (unsigned dim=0;dim<2;dim++){ SBasis sub_s = s.segs[i]; sub_s-=sub_s.at0(); sub_s/=sub_s.at1(); sub_u[dim]=compose_inverse(sub_M[dim],sub_s, order, tol); } u.push(sub_u,s(t1)); } return u; }
void draw(cairo_t *cr, std::ostringstream *notify, int width, int height, bool save) { Geom::Point dir(1,-2); D2<Piecewise<SBasis> > B = make_cuts_independent(path_a_pw); cairo_set_source_rgba (cr, 0., 0.125, 0, 1); if(0) { D2<Piecewise<SBasis> > tB(cos(B[0]*0.1)*(brush_handle.pos[0]/100) + B[0], cos(B[1]*0.1)*(brush_handle.pos[1]/100) + B[1]); cairo_d2_pw_sb(cr, tB); } else { Piecewise<SBasis> r2 = (dot(path_a_pw - brush_handle.pos, path_a_pw - brush_handle.pos)); Piecewise<SBasis> rc; rc.push_cut(0); rc.push(SBasis(Linear(1, 1)), 2); rc.push(SBasis(Linear(1, 0)), 4); rc.push(SBasis(Linear(0, 0)), 30); rc *= 10; rc.scaleDomain(1000); Piecewise<SBasis> swr; swr.push_cut(0); swr.push(SBasis(Linear(0, 1)), 2); swr.push(SBasis(Linear(1, 0)), 4); swr.push(SBasis(Linear(0, 0)), 30); swr *= 10; swr.scaleDomain(1000); cairo_pw(cr, swr);// + (height - 100)); D2<Piecewise<SBasis> > uB = make_cuts_independent(unitVector(path_a_pw - brush_handle.pos)); D2<Piecewise<SBasis> > tB(compose(rc, (r2))*uB[0] + B[0], compose(rc, (r2))*uB[1] + B[1]); cairo_d2_pw_sb(cr, tB); //path_a_pw = sectionize(tB); } cairo_stroke(cr); *notify << path_a_pw.size(); Toy::draw(cr, notify, width, height, save); }
Piecewise<SBasis> convole(SBasisOf<double> const &f, Interval dom_f, SBasisOf<double> const &g, Interval dom_g, bool f_cst_ends = false){ if ( dom_f.extent() < dom_g.extent() ) return convole(g, dom_g, f, dom_f); Piecewise<SBasis> result; SBasisOf<SBasisOf<double> > u,v; u.push_back(LinearOf<SBasisOf<double> >(SBasisOf<double>(LinearOf<double>(0,1)))); v.push_back(LinearOf<SBasisOf<double> >(SBasisOf<double>(LinearOf<double>(0,0)), SBasisOf<double>(LinearOf<double>(1,1)))); SBasisOf<SBasisOf<double> > v_u = (v - u)*(dom_f.extent()/dom_g.extent()); v_u += SBasisOf<SBasisOf<double> >(SBasisOf<double>(-dom_g.min()/dom_g.extent())); SBasisOf<SBasisOf<double> > gg = multi_compose(g,v_u); SBasisOf<SBasisOf<double> > ff = SBasisOf<SBasisOf<double> >(f); SBasisOf<SBasisOf<double> > hh = integral(ff*gg,0); result.cuts.push_back(dom_f.min()+dom_g.min()); //Note: we know dom_f.extent() >= dom_g.extent()!! //double rho = dom_f.extent()/dom_g.extent(); double t0 = dom_g.min()/dom_f.extent(); double t1 = dom_g.max()/dom_f.extent(); double t2 = t0+1; double t3 = t1+1; SBasisOf<double> a,b,t; SBasis seg; a = SBasisOf<double>(LinearOf<double>(0,0)); b = SBasisOf<double>(LinearOf<double>(0,t1-t0)); t = SBasisOf<double>(LinearOf<double>(t0,t1)); seg = toSBasis(compose(hh,b,t)-compose(hh,a,t)); result.push(seg,dom_f.min() + dom_g.max()); if (dom_f.extent() > dom_g.extent()){ a = SBasisOf<double>(LinearOf<double>(0,t2-t1)); b = SBasisOf<double>(LinearOf<double>(t1-t0,1)); t = SBasisOf<double>(LinearOf<double>(t1,t2)); seg = toSBasis(compose(hh,b,t)-compose(hh,a,t)); result.push(seg,dom_f.max() + dom_g.min()); } a = SBasisOf<double>(LinearOf<double>(t2-t1,1.)); b = SBasisOf<double>(LinearOf<double>(1.,1.)); t = SBasisOf<double>(LinearOf<double>(t2,t3)); seg = toSBasis(compose(hh,b,t)-compose(hh,a,t)); result.push(seg,dom_f.max() + dom_g.max()); result*=dom_f.extent(); //--constant ends correction-------------- if (f_cst_ends){ SBasis ig = toSBasis(integraaal(g))*dom_g.extent(); ig -= ig.at0(); Piecewise<SBasis> cor; cor.cuts.push_back(dom_f.min()+dom_g.min()); cor.push(reverse(ig)*f.at0(),dom_f.min()+dom_g.max()); cor.push(Linear(0),dom_f.max()+dom_g.min()); cor.push(ig*f.at1(),dom_f.max()+dom_g.max()); result+=cor; } //---------------------------------------- return result; }
/** * \brief Retruns a Piecewise SBasis with prescribed values at prescribed times. * * \param times: vector of times at which the values are given. Should be sorted in increasing order. * \param values: vector of prescribed values. Should have the same size as times and be sorted accordingly. * \param smoothness: (defaults to 1) regularity class of the result: 0=piecewise linear, 1=continuous derivative, etc... */ Piecewise<SBasis> interpolate(std::vector<double> times, std::vector<double> values, unsigned smoothness){ assert ( values.size() == times.size() ); if ( values.size() == 0 ) return Piecewise<SBasis>(); if ( values.size() == 1 ) return Piecewise<SBasis>(values[0]);//what about time?? SBasis sk = shift(Linear(1.),smoothness); SBasis bump_in = integral(sk); bump_in -= bump_in.at0(); bump_in /= bump_in.at1(); SBasis bump_out = reverse( bump_in ); Piecewise<SBasis> result; result.cuts.push_back(times[0]); for (unsigned i = 0; i<values.size()-1; i++){ result.push(bump_out*values[i]+bump_in*values[i+1],times[i+1]); } return result; }