Code

update to 2geom rev.1773
authorjohanengelen <johanengelen@users.sourceforge.net>
Wed, 7 Jan 2009 22:00:50 +0000 (22:00 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Wed, 7 Jan 2009 22:00:50 +0000 (22:00 +0000)
mostly bugfixes

src/2geom/bezier-utils.cpp
src/2geom/piecewise.h
src/2geom/poly.cpp
src/2geom/rect.h
src/2geom/sbasis.cpp
src/2geom/sbasis.h
src/2geom/transforms.h

index 83767af985008bead21fa00bd5f9c50a4ad6db09..4aa720127502d294b288190bc234ef322b287b12 100644 (file)
@@ -48,7 +48,7 @@
 #define noBEZIER_DEBUG
 
 #ifdef HAVE_IEEEFP_H
-# include <ieefp.h>
+# include <ieeefp.h>
 #endif
 
 #include <2geom/bezier-utils.h>
@@ -171,6 +171,7 @@ copy_without_nans_or_adjacent_duplicates(Point const src[], unsigned src_len, Po
             ++si;
             break;
         }
+        si++;
     }
     unsigned di = 0;
     for (; si < src_len; ++si) {
index 31bf6872af447aa4d321b2c7511142ea7da6e9ca..144d7a9b22d098b2c14e76cb6194dd9c8b1eeb5b 100644 (file)
@@ -90,6 +90,8 @@ class Piecewise {
         push_cut(1.);
     }
 
+    inline void reserve(unsigned i) { segs.reserve(i); cuts.reserve(i + 1); }
+
     inline T operator[](unsigned i) const { return segs[i]; }
     inline T &operator[](unsigned i) { return segs[i]; }
     inline output_type operator()(double t) const { return valueAt(t); }
@@ -225,6 +227,7 @@ class Piecewise {
 
         segs.insert(segs.end(), other.segs.begin(), other.segs.end());
         double t = cuts.back() - other.cuts.front();
+        cuts.reserve(cuts.size() + other.size());
         for(unsigned i = 0; i < other.size(); i++)
             push_cut(other.cuts[i + 1] + t);
     }
@@ -234,15 +237,11 @@ class Piecewise {
         boost::function_requires<AddableConcept<typename T::output_type> >();
         if(other.empty()) return;
 
-        if(empty()) {
-            for(unsigned i = 0; i < other.size(); i++)
-                push_seg(other[i]);
-            cuts = other.cuts;
-            return;
-        }
+        if(empty()) { segs = other.segs; cuts = other.cuts; return; }
 
         typename T::output_type y = segs.back().at1() - other.segs.front().at0();
         double t = cuts.back() - other.cuts.front();
+        reserve(size() + other.size());
         for(unsigned i = 0; i < other.size(); i++)
             push(other[i] + y, other.cuts[i + 1] + t);
     }
@@ -327,8 +326,7 @@ Piecewise<T> partition(const Piecewise<T> &pw, std::vector<double> const &c) {
     if(c.empty()) return Piecewise<T>(pw);
 
     Piecewise<T> ret = Piecewise<T>();
-    ret.cuts.reserve(c.size() + pw.cuts.size());
-    ret.segs.reserve(c.size() + pw.cuts.size() - 1);
+    ret.reserve(c.size() + pw.cuts.size() - 1);
 
     if(pw.empty()) {
         ret.cuts = c;
@@ -408,6 +406,7 @@ Piecewise<T> portion(const Piecewise<T> &pw, double from, double to) {
     ret.push_seg(portion( pw[i], pw.segT(from, i), 1.0 ));
     i++;
     unsigned fi = pw.segN(to, i);
+    ret.reserve(fi - i + 1);
     if (to == pw.cuts[fi]) fi-=1;
 
     ret.segs.insert(ret.segs.end(), pw.segs.begin() + i, pw.segs.begin() + fi);  //copy segs
@@ -419,10 +418,12 @@ Piecewise<T> portion(const Piecewise<T> &pw, double from, double to) {
     return ret;
 }
 
+//TODO: seems like these should be mutating
 template<typename T>
 Piecewise<T> remove_short_cuts(Piecewise<T> const &f, double tol) {
     if(f.empty()) return f;
     Piecewise<T> ret;
+    ret.reserve(f.size());
     ret.push_cut(f.cuts[0]);
     for(unsigned i=0; i<f.size(); i++){
         if (f.cuts[i+1]-f.cuts[i] >= tol || i==f.size()-1) {
@@ -432,10 +433,12 @@ Piecewise<T> remove_short_cuts(Piecewise<T> const &f, double tol) {
     return ret;
 }
 
+//TODO: seems like these should be mutating
 template<typename T>
 Piecewise<T> remove_short_cuts_extending(Piecewise<T> const &f, double tol) {
     if(f.empty()) return f;
     Piecewise<T> ret;
+    ret.reserve(f.size());
     ret.push_cut(f.cuts[0]);
     double last = f.cuts[0]; // last cut included
     for(unsigned i=0; i<f.size(); i++){
@@ -463,7 +466,8 @@ template<typename T>
 Piecewise<T> operator+(Piecewise<T> const &a, typename T::output_type b) {
     boost::function_requires<OffsetableConcept<T> >();
 //TODO:empty
-    Piecewise<T> ret = Piecewise<T>();
+    Piecewise<T> ret;
+    ret.segs.reserve(a.size());
     ret.cuts = a.cuts;
     for(unsigned i = 0; i < a.size();i++)
         ret.push_seg(a[i] + b);
@@ -473,14 +477,15 @@ template<typename T>
 Piecewise<T> operator-(Piecewise<T> const &a, typename T::output_type b) {
     boost::function_requires<OffsetableConcept<T> >();
 //TODO: empty
-    Piecewise<T> ret = Piecewise<T>();
+    Piecewise<T> ret;
+    ret.segs.reserve(a.size());
     ret.cuts = a.cuts;
     for(unsigned i = 0; i < a.size();i++)
         ret.push_seg(a[i] - b);
     return ret;
 }
 template<typename T>
-Piecewise<T> operator+=(Piecewise<T>& a, typename T::output_type b) {
+Piecewise<T>& operator+=(Piecewise<T>& a, typename T::output_type b) {
     boost::function_requires<OffsetableConcept<T> >();
 
     if(a.empty()) { a.push_cut(0.); a.push(T(b), 1.); return a; }
@@ -490,10 +495,10 @@ Piecewise<T> operator+=(Piecewise<T>& a, typename T::output_type b) {
     return a;
 }
 template<typename T>
-Piecewise<T> operator-=(Piecewise<T>& a, typename T::output_type b) {
+Piecewise<T>& operator-=(Piecewise<T>& a, typename T::output_type b) {
     boost::function_requires<OffsetableConcept<T> >();
 
-    if(a.empty()) { a.push_cut(0.); a.push(T(b), 1.); return a; }
+    if(a.empty()) { a.push_cut(0.); a.push(T(-b), 1.); return a; }
 
     for(unsigned i = 0;i < a.size();i++)
         a[i] -= b;
@@ -506,6 +511,7 @@ Piecewise<T> operator-(Piecewise<T> const &a) {
     boost::function_requires<ScalableConcept<T> >();
 
     Piecewise<T> ret;
+    ret.segs.reserve(a.size());
     ret.cuts = a.cuts;
     for(unsigned i = 0; i < a.size();i++)
         ret.push_seg(- a[i]);
@@ -518,6 +524,7 @@ Piecewise<T> operator*(Piecewise<T> const &a, double b) {
     if(a.empty()) return Piecewise<T>();
 
     Piecewise<T> ret;
+    ret.segs.reserve(a.size());
     ret.cuts = a.cuts;
     for(unsigned i = 0; i < a.size();i++)
         ret.push_seg(a[i] * b);
@@ -531,27 +538,25 @@ Piecewise<T> operator/(Piecewise<T> const &a, double b) {
     if(a.empty()) return Piecewise<T>();
 
     Piecewise<T> ret;
+    ret.segs.reserve(a.size());
     ret.cuts = a.cuts;
     for(unsigned i = 0; i < a.size();i++)
         ret.push_seg(a[i] / b);
     return ret;
 }
 template<typename T>
-Piecewise<T> operator*=(Piecewise<T>& a, double b) {
+Piecewise<T>& operator*=(Piecewise<T>& a, double b) {
     boost::function_requires<ScalableConcept<T> >();
 
-    if(a.empty()) return Piecewise<T>();
-
     for(unsigned i = 0; i < a.size();i++)
         a[i] *= b;
     return a;
 }
 template<typename T>
-Piecewise<T> operator/=(Piecewise<T>& a, double b) {
+Piecewise<T>& operator/=(Piecewise<T>& a, double b) {
     boost::function_requires<ScalableConcept<T> >();
 
     //FIXME: b == 0?
-    if(a.empty()) return Piecewise<T>();
 
     for(unsigned i = 0; i < a.size();i++)
         a[i] /= b;
@@ -564,8 +569,9 @@ Piecewise<T> operator+(Piecewise<T> const &a, Piecewise<T> const &b) {
     boost::function_requires<AddableConcept<T> >();
 
     Piecewise<T> pa = partition(a, b.cuts), pb = partition(b, a.cuts);
-    Piecewise<T> ret = Piecewise<T>();
+    Piecewise<T> ret;
     assert(pa.size() == pb.size());
+    ret.segs.reserve(pa.size());
     ret.cuts = pa.cuts;
     for (unsigned i = 0; i < pa.size(); i++)
         ret.push_seg(pa[i] + pb[i]);
@@ -578,18 +584,19 @@ Piecewise<T> operator-(Piecewise<T> const &a, Piecewise<T> const &b) {
     Piecewise<T> pa = partition(a, b.cuts), pb = partition(b, a.cuts);
     Piecewise<T> ret = Piecewise<T>();
     assert(pa.size() == pb.size());
+    ret.segs.reserve(pa.size());
     ret.cuts = pa.cuts;
     for (unsigned i = 0; i < pa.size(); i++)
         ret.push_seg(pa[i] - pb[i]);
     return ret;
 }
 template<typename T>
-inline Piecewise<T> operator+=(Piecewise<T> &a, Piecewise<T> const &b) {
+inline Piecewise<T>& operator+=(Piecewise<T> &a, Piecewise<T> const &b) {
     a = a+b;
     return a;
 }
 template<typename T>
-inline Piecewise<T> operator-=(Piecewise<T> &a, Piecewise<T> const &b) {
+inline Piecewise<T>& operator-=(Piecewise<T> &a, Piecewise<T> const &b) {
     a = a-b;
     return a;
 }
@@ -603,6 +610,7 @@ Piecewise<T2> operator*(Piecewise<T1> const &a, Piecewise<T2> const &b) {
     Piecewise<T2> pb = partition(b, a.cuts);
     Piecewise<T2> ret = Piecewise<T2>();
     assert(pa.size() == pb.size());
+    ret.segs.reserve(pa.size());
     ret.cuts = pa.cuts;
     for (unsigned i = 0; i < pa.size(); i++)
         ret.push_seg(pa[i] * pb[i]);
@@ -610,7 +618,7 @@ Piecewise<T2> operator*(Piecewise<T1> const &a, Piecewise<T2> const &b) {
 }
 
 template<typename T>
-inline Piecewise<T> operator*=(Piecewise<T> &a, Piecewise<T> const &b) {
+inline Piecewise<T>& operator*=(Piecewise<T> &a, Piecewise<T> const &b) {
     a = a * b;
     return a;
 }
@@ -740,8 +748,7 @@ std::vector<std::vector<double> >multi_roots(Piecewise<SBasis> const &f, std::ve
 template<typename T>
 Piecewise<T> reverse(Piecewise<T> const &f) {
     Piecewise<T> ret = Piecewise<T>();
-    ret.cuts.resize(f.cuts.size());
-    ret.segs.resize(f.segs.size());
+    ret.reserve(f.size());
     double start = f.cuts[0];
     double end = f.cuts.back();
     for (unsigned i = 0; i < f.cuts.size(); i++) {
@@ -759,7 +766,7 @@ Piecewise<T> reverse(Piecewise<T> const &f) {
  *  \return a if t = 0, b if t = 1, or an interpolation between a and b for t in [0,1]
  */
 template<typename T>
-Piecewise<T> lerp(Piecewise<T> const &a, Piecewise<T> b, double t) {
+Piecewise<T> lerp(double t, Piecewise<T> const &a, Piecewise<T> b) {
     // Make sure both paths have the same number of segments and cuts at the same locations
     b.setDomain(a.domain());
     Piecewise<T> pA = partition(a, b.cuts);
index d8b379557f154b812dd151dd62d3a50df3ac73e3..9dbfc0967d5ffedce1ffe1c2028f6f52e6b8c770 100644 (file)
@@ -1,6 +1,5 @@
 #include <2geom/poly.h>
 
-#define HAVE_GSL
 #ifdef HAVE_GSL
 #include <gsl/gsl_poly.h>
 #endif
index fb42ff92d1d39ee9593abfede5866f05105a1f0a..fe2cc297b97b424979e144e5bb88631c4c78c4e5 100644 (file)
@@ -215,7 +215,7 @@ public:
     /**
      * Check whether this OptRect is empty or not.
      */
-    inline bool isEmpty() { return (*this == false); };
+    inline bool isEmpty() const { return (*this == false); };
 
     /**
      * If \c this is empty, copy argument \c b. Otherwise, union with it (and do nothing when \c b is empty)
index bdc40c9361051b3bc81300c6da8424e9609224cc..b5c1a05a7bec28c6c6dfeb8f052466d154a65745 100644 (file)
@@ -70,7 +70,7 @@ std::vector<double> SBasis::valueAndDerivatives(double t, unsigned n) const {
     SBasis tmp = *this;
     for(unsigned i = 1; i < n+1; i++) {
         tmp.derive();
-        ret[i+1] = tmp.valueAt(t);
+        ret[i] = tmp.valueAt(t);
     }
     return ret;
 }
index 3038c17762458994547b5f22f56467a79b081f7e..ae045b2229aad25f051630459940fd8cc4a0f25a 100644 (file)
@@ -69,9 +69,9 @@ class SBasis{
     void push_back(Linear const&l) { d.push_back(l); }
 
 public:
+    // As part of our migration away from SBasis isa vector we provide this minimal set of vector interface methods.
     size_t size() const {return d.size();}
     Linear operator[](unsigned i) const {
-        assert(i < size());
         return d[i];
     }
     Linear& operator[](unsigned i) { return d.at(i); }
@@ -91,6 +91,8 @@ public:
     //void insert(Linear* aa, Linear* bb, Linear* cc} { d.insert(aa, bb, cc);}
     Linear& at(unsigned i) { return d.at(i);}
     //void insert(Linear* before, int& n, Linear const &l) { d.insert(std::vector<Linear>::iterator(before), n, l);}
+    bool operator==(SBasis const&B) { return d == B.d;}
+    operator std::vector<Linear>() { return d;}
 
     
     SBasis() {}
index ac5a775c492975b485335f9a5284a175553c7d69..29aab11aa20b28e0e12aa7ea3c8cbf55d157b532 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * \file
- * \brief  \todo brief description
+ * \brief  Transforms should be applied left to right. scale * translate means: first scale, then translate.
  *
  * Authors:
  *      ? <?@?.?>