From: jfbarraud Date: Sat, 3 Jan 2009 22:16:55 +0000 (+0000) Subject: update of sbasis-geometric.cpp (unitVector() was broken, which affects some lpe's) X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=57d645121d3dc83796c5fa418a2047b329f74f29;p=inkscape.git update of sbasis-geometric.cpp (unitVector() was broken, which affects some lpe's) --- diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp index d27255749..28e9fc964 100644 --- a/src/2geom/sbasis-geometric.cpp +++ b/src/2geom/sbasis-geometric.cpp @@ -50,8 +50,12 @@ vect_intersect(vector const &a, vector const &b, double tol=0.){ return inter; } +//------------------------------------------------------------------------------ static SBasis divide_by_sk(SBasis const &a, int k) { - assert( k<(int)a.size()); + if ( k>=(int)a.size()){ + //make sure a is 0? + return SBasis(); + } if(k < 0) return shift(a,-k); SBasis c; c.insert(c.begin(), a.begin()+k, a.end()); @@ -77,24 +81,41 @@ static SBasis divide_by_t0k(SBasis const &a, int k) { } static SBasis divide_by_t1k(SBasis const &a, int k) { - return divide_by_t0k(a, -k); + if(k < 0) { + SBasis c = Linear(1,0); + for (int i=2; i<=-k; i++){ + c*=c; + } + c*=a; + return(c); + }else{ + SBasis c = Linear(0,1); + for (int i=2; i<=k; i++){ + c*=c; + } + c*=a; + return(divide_by_sk(c,k)); + } } static D2 RescaleForNonVanishingEnds(D2 const &MM, double ZERO=1.e-4){ D2 M = MM; //TODO: divide by all the s at once!!! - while (fabs(M[0].at0())0||M[1].size()>0) && + fabs(M[0].at0())0||M[1].size()>0) && + fabs(M[0].at0())0||M[1].size()>0) && + fabs(M[0].at1()) > const &M, double ZERO){ Piecewise Geom::atan2(Piecewise > const &vect, double tol, unsigned order){ Piecewise result; - Piecewise > v = cutAtRoots(vect); + Piecewise > v = cutAtRoots(vect,tol); result.cuts.push_back(v.cuts.front()); for (unsigned i=0; i > Geom::unitVector(D2 const &V_in, double tol, unsigned order){ + //TODO: Handle vanishing vectors... + // -This approach is numerically bad. Find a stable way to rescale V_in to have non vanishing ends. + // -This done, unitVector will have jumps at zeros: fill the gaps with arcs of circles. D2 V = RescaleForNonVanishingEnds(V_in); + if (V[0].empty() && V[1].empty()) return Piecewise >(D2(Linear(1),SBasis())); SBasis x = V[0], y = V[1]; @@ -208,9 +233,9 @@ Geom::unitVector(D2 const &V_in, double tol, unsigned order){ Point v0 = unit_vector(V.at0()); Point v1 = unit_vector(V.at1()); - SBasis a(order+1, Linear()); + SBasis a = SBasis(order+1, Linear(0.)); a[0] = Linear(-v0[1],-v1[1]); - SBasis b(order+1, Linear()); + SBasis b = SBasis(order+1, Linear(0.)); b[0] = Linear( v0[0], v1[0]); r_eqn1 = -(a*x+b*y); @@ -227,13 +252,14 @@ Geom::unitVector(D2 const &V_in, double tol, unsigned order){ // a0*x(0)+b0*y(0)=r0 & 2*a0*a(0)+2*b0*b(0)=rr0 //and // a1*x(1)+b1*y(1)=r1 & 2*a1*a(1)+2*b1*b(1)=rr1 - a0 = r0/dot(v0,V(0))*v0[0]-rr0/2*v0[1]; - b0 = r0/dot(v0,V(0))*v0[1]+rr0/2*v0[0]; - a1 = r1/dot(v1,V(1))*v1[0]-rr1/2*v1[1]; - b1 = r1/dot(v1,V(1))*v1[1]+rr1/2*v1[0]; + a0 = r0/dot(v0,V.at0())*v0[0]-rr0/2*v0[1]; + b0 = r0/dot(v0,V.at0())*v0[1]+rr0/2*v0[0]; + a1 = r1/dot(v1,V.at1())*v1[0]-rr1/2*v1[1]; + b1 = r1/dot(v1,V.at1())*v1[1]+rr1/2*v1[0]; a[k] = Linear(a0,a1); b[k] = Linear(b0,b1); + //TODO: use "incremental" rather than explicit formulas. r_eqn1 = -(a*x+b*y); r_eqn2 = Linear(1)-(a*a+b*b); @@ -246,7 +272,6 @@ Geom::unitVector(D2 const &V_in, double tol, unsigned order){ //is it good? double rel_tol = std::max(1.,std::max(V_in[0].tailError(0),V_in[1].tailError(0)))*tol; - if (r_eqn1.tailError(order)>rel_tol || r_eqn2.tailError(order)>tol){ //if not: subdivide and concat results. Piecewise > unitV0, unitV1;