summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f4a94b1)
raw | patch | inline | side by side (parent: f4a94b1)
author | jfbarraud <jfbarraud@users.sourceforge.net> | |
Sat, 3 Jan 2009 22:16:55 +0000 (22:16 +0000) | ||
committer | jfbarraud <jfbarraud@users.sourceforge.net> | |
Sat, 3 Jan 2009 22:16:55 +0000 (22:16 +0000) |
src/2geom/sbasis-geometric.cpp | patch | blob | history |
index d27255749946703fcf8c616b0958b673ca0d0b0a..28e9fc964006df620bfe2c2b9353787d05f200c1 100644 (file)
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());
}
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<SBasis> RescaleForNonVanishingEnds(D2<SBasis> const &MM, double ZERO=1.e-4){
D2<SBasis> M = MM;
//TODO: divide by all the s at once!!!
- while (fabs(M[0].at0())<ZERO &&
+ while ((M[0].size()>0||M[1].size()>0) &&
+ fabs(M[0].at0())<ZERO &&
fabs(M[1].at0())<ZERO &&
fabs(M[0].at1())<ZERO &&
fabs(M[1].at1())<ZERO){
M[0] = divide_by_sk(M[0],1);
M[1] = divide_by_sk(M[1],1);
}
- while (fabs(M[0].at0())<ZERO && fabs(M[1].at0())<ZERO){
+ while ((M[0].size()>0||M[1].size()>0) &&
+ fabs(M[0].at0())<ZERO && fabs(M[1].at0())<ZERO){
M[0] = divide_by_t0k(M[0],1);
M[1] = divide_by_t0k(M[1],1);
}
- while (fabs(M[0].at1())<ZERO && fabs(M[1].at1())<ZERO){
+ while ((M[0].size()>0||M[1].size()>0) &&
+ fabs(M[0].at1())<ZERO && fabs(M[1].at1())<ZERO){
M[0] = divide_by_t1k(M[0],1);
M[1] = divide_by_t1k(M[1],1);
}
Piecewise<SBasis>
Geom::atan2(Piecewise<D2<SBasis> > const &vect, double tol, unsigned order){
Piecewise<SBasis> result;
- Piecewise<D2<SBasis> > v = cutAtRoots(vect);
+ Piecewise<D2<SBasis> > v = cutAtRoots(vect,tol);
result.cuts.push_back(v.cuts.front());
for (unsigned i=0; i<v.size(); i++){
*/
Piecewise<D2<SBasis> >
Geom::unitVector(D2<SBasis> 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<SBasis> V = RescaleForNonVanishingEnds(V_in);
+
if (V[0].empty() && V[1].empty())
return Piecewise<D2<SBasis> >(D2<SBasis>(Linear(1),SBasis()));
SBasis x = V[0], y = V[1];
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);
// 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);
//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<D2<SBasis> > unitV0, unitV1;