#include <2geom/d2.h> /* One would think that we would include d2-sbasis.h, however, * you cannot actually include it in anything - only d2 may import it. * This is due to the trickinesses of template submatching. */ namespace Geom { SBasis L2(D2 const & a, unsigned k) { return sqrt(dot(a, a), k); } D2 multiply(Linear const & a, D2 const & b) { return D2(multiply(a, b[X]), multiply(a, b[Y])); } D2 multiply(SBasis const & a, D2 const & b) { return D2(multiply(a, b[X]), multiply(a, b[Y])); } D2 truncate(D2 const & a, unsigned terms) { return D2(truncate(a[X], terms), truncate(a[Y], terms)); } unsigned sbasis_size(D2 const & a) { return std::max((unsigned) a[0].size(), (unsigned) a[1].size()); } //TODO: Is this sensical? shouldn't it be like pythagorean or something? double tail_error(D2 const & a, unsigned tail) { return std::max(a[0].tailError(tail), a[1].tailError(tail)); } Piecewise > sectionize(D2 > const &a) { Piecewise x = partition(a[0], a[1].cuts), y = partition(a[1], a[0].cuts); assert(x.size() == y.size()); Piecewise > ret; for(unsigned i = 0; i < x.size(); i++) ret.push_seg(D2(x[i], y[i])); ret.cuts.insert(ret.cuts.end(), x.cuts.begin(), x.cuts.end()); return ret; } D2 > make_cuts_independent(Piecewise > const &a) { D2 > ret; for(unsigned d = 0; d < 2; d++) { for(unsigned i = 0; i < a.size(); i++) ret[d].push_seg(a[i][d]); ret[d].cuts.insert(ret[d].cuts.end(), a.cuts.begin(), a.cuts.end()); } return ret; } Piecewise > rot90(Piecewise > const &M){ Piecewise > result; if (M.empty()) return M; result.push_cut(M.cuts[0]); for (unsigned i=0; i dot(Piecewise > const &a, Piecewise > const &b) { Piecewise result; if (a.empty() || b.empty()) return result; Piecewise > aa = partition(a,b.cuts); Piecewise > bb = partition(b,a.cuts); result.push_cut(aa.cuts.front()); for (unsigned i=0; i dot(Piecewise > const &a, Point const &b) { Piecewise result; if (a.empty()) return result; result.push_cut(a.cuts.front()); for (unsigned i = 0; i < a.size(); ++i){ result.push(dot(a.segs[i],b), a.cuts[i+1]); } return result; } Piecewise cross(Piecewise > const &a, Piecewise > const &b){ Piecewise result; if (a.empty() || b.empty()) return result; Piecewise > aa = partition(a,b.cuts); Piecewise > bb = partition(b,a.cuts); result.push_cut(aa.cuts.front()); for (unsigned i=0; i > operator*(Piecewise > const &a, Matrix const &m) { Piecewise > result; if(a.empty()) return result; result.push_cut(a.cuts[0]); for (unsigned i = 0; i < a.size(); i++) { result.push(a[i] * m, a.cuts[i+1]); } return result; } //if tol>0, only force continuity where the jump is smaller than tol. Piecewise > force_continuity(Piecewise > const &f, double tol, bool closed) { if (f.size()==0) return f; Piecewise > result=f; unsigned cur = (closed)? 0:1; unsigned prev = (closed)? f.size()-1:0; while(cur > > split_at_discontinuities (Geom::Piecewise > const & pwsbin, double tol) { using namespace Geom; std::vector > > ret; unsigned piece_start = 0; for (unsigned i=0; i tol){ Piecewise > piece; piece.cuts.push_back(pwsbin.cuts[piece_start]); for (unsigned j = piece_start; j > &f, Point a){ if ( f.empty() ){ f.concat(Piecewise >(D2(Linear(a[X]),Linear(a[Y])))); return; } for (unsigned dim=0; dim<2; dim++){ if (f.segs.front()[dim].size() == 0){ f.segs.front()[dim] = SBasis(Linear(a[dim],0)); }else{ f.segs.front()[dim][0][0] = a[dim]; } } } static void set_last_point(Piecewise > &f, Point a){ if ( f.empty() ){ f.concat(Piecewise >(D2(Linear(a[X]),Linear(a[Y])))); return; } for (unsigned dim=0; dim<2; dim++){ if (f.segs.back()[dim].size() == 0){ f.segs.back()[dim] = SBasis(Linear(0,a[dim])); }else{ f.segs.back()[dim][0][1] = a[dim]; } } } std::vector > > fuse_nearby_ends(std::vector > > const &f, double tol){ if ( f.size()==0 ) return f; std::vector > > result; std::vector > pre_result; for (unsigned i=0; i()); pre_result.back().push_back(i); } } for (unsigned i=0; i > comp; for (unsigned j=0; j > new_comp = f.at(pre_result[i][j]); if ( j>0 ){ set_first_point( new_comp, comp.segs.back().at1() ); } comp.concat(new_comp); } if ( L2(comp.firstValue()-comp.lastValue()) < tol ){ //TODO: check sizes!!! set_last_point( comp, comp.segs.front().at0() ); } result.push_back(comp); } return result; return f; } } // namespace Geom /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :