Code

update 2geom
authorjohanengelen <johanengelen@users.sourceforge.net>
Tue, 17 Jun 2008 21:03:42 +0000 (21:03 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Tue, 17 Jun 2008 21:03:42 +0000 (21:03 +0000)
src/2geom/bezier.h
src/2geom/concepts.h
src/2geom/curve.h
src/2geom/d2.h
src/2geom/elliptical-arc.cpp
src/2geom/hvlinesegment.h
src/2geom/path.h
src/2geom/piecewise.h
src/2geom/sbasis-roots.cpp
src/2geom/sbasis.cpp

index 289a6772953e69337ccf4df040ce3934c8216061..bc9d6032e63fe0c8befdacdb2ce28e0f7764be28 100644 (file)
@@ -171,7 +171,7 @@ public:
     std::vector<Coord> valueAndDerivatives(Coord t, unsigned n_derivs) const {
         std::vector<Coord> val_n_der;
         Coord d_[order()+1];
-        unsigned nn = n_derivs;
+        unsigned nn = n_derivs + 1; // the size of the result vector equals n_derivs+1
         if(nn > order())
             //nn = order();
             nn = order()+1;
index ba45222746088391815530fb9d1f1d71263113d6..3b6fd3577bd800d877c1ed6b38ae2dca33b5fa71 100644 (file)
@@ -78,7 +78,7 @@ struct FragmentConcept {
         o = t.at1();
         o = t.valueAt(d);
         o = t(d);
-        v = t.valueAndDerivatives(d, u);
+        v = t.valueAndDerivatives(d, u-1);
                //Is a pure derivative (ignoring others) accessor ever much faster?
                //u = number of values returned. first val is value.
         sb = t.toSBasis();
index d201d5d5e0e1d1aecd8419652117e37e96355ee3..7f138dabf92653c5f6a838435ad69f8ecd8d4b44 100644 (file)
@@ -103,10 +103,14 @@ public:
 
   virtual Curve *transformed(Matrix const &m) const = 0;
 
-  virtual Point pointAt(Coord t) const { return pointAndDerivatives(t, 1).front(); }
+  virtual Point pointAt(Coord t) const { return pointAndDerivatives(t, 0).front(); }
   virtual Coord valueAt(Coord t, Dim2 d) const { return pointAt(t)[d]; }
   virtual Point operator() (double t)  const { return pointAt(t); }
+  
+  /* pointAndDerivatives returns a vector that looks like the following:
+   *  [ point at t, 1st derivative at t, 2nd derivative at t, ... , n'th derivative at t] */
   virtual std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const = 0;
+
   virtual D2<SBasis> toSBasis() const = 0;
 };
 
index 3becc813d3c983c1398deb6fcb0261c35d46d74c..db8cf68c4e503ca012a0f6c0c00edc30ca311e74 100644 (file)
@@ -88,11 +88,11 @@ class D2{
         boost::function_requires<FragmentConcept<T> >();
         return (*this)(t);
     }
-    std::vector<Point > valueAndDerivatives(double t, unsigned count) const {
-        std::vector<Coord> x = f[X].valueAndDerivatives(t, count),
-                           y = f[Y].valueAndDerivatives(t, count);
+    std::vector<Point > valueAndDerivatives(double t, unsigned n) const {
+        std::vector<Coord> x = f[X].valueAndDerivatives(t, n),
+                           y = f[Y].valueAndDerivatives(t, n);
         std::vector<Point> res;
-        for(unsigned i = 0; i < count; i++) {
+        for(unsigned i = 0; i <= n; i++) {
             res.push_back(Point(x[i], y[i]));
         }
         return res;
index a433ca370f0fa257b1f2cc1791f4ad50da427766..b30dfde5d11d85da06163951a6984962d6f3a8a5 100644 (file)
@@ -326,31 +326,32 @@ Curve* EllipticalArc::derivative() const
 std::vector<Point> 
 EllipticalArc::pointAndDerivatives(Coord t, unsigned int n) const
 {
+    unsigned int nn = n+1; // nn represents the size of the result vector.
        std::vector<Point> result;
-       result.reserve(n);
+       result.reserve(nn);
        double angle = map_unit_interval_on_circular_arc(t, start_angle(), 
                                                                 end_angle(), sweep_flag());
        EllipticalArc ea(*this);
        ea.m_center = Point(0,0);
-       unsigned int m = std::min(n, 4u);
+       unsigned int m = std::min(nn, 4u);
        for ( unsigned int i = 0; i < m; ++i )
        {
                result.push_back( ea.pointAtAngle(angle) );
                angle += M_PI/2;
                if ( !(angle < 2*M_PI) ) angle -= 2*M_PI;
        }
-       m = n / 4;
+       m = nn / 4;
        for ( unsigned int i = 1; i < m; ++i )
        {
                for ( unsigned int j = 0; j < 4; ++j )
                        result.push_back( result[j] );
        }
-       m = n - 4 * m;
+       m = nn - 4 * m;
        for ( unsigned int i = 0; i < m; ++i )
        {
                result.push_back( result[i] );
        }
-       if ( !result.empty() ) // n != 0
+       if ( !result.empty() ) // nn != 0
                result[0] = pointAtAngle(angle);
        return result;
 }
index b3c20037897aece708fcd63014d61d7d20251ef2..732c299387efdac185bed092da9df3de9284d7b2 100644 (file)
@@ -243,20 +243,25 @@ class HLineSegment : public Curve
                
                return initialPoint()[X] + t * (finalPoint()[X] - initialPoint()[X]);
        }
-       
-       std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
-       {
-               std::vector<Point> result;
-               if ( n > 0)
-                       result.push_back(pointAt(t));
-               if (n > 1)
-               {
-                       double x = finalPoint()[X] - initialPoint()[X];
-                       result.push_back( Point(x, 0) );
-               }
-               return result;
-       }
-       
+
+    std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
+    {
+        std::vector<Point> result;
+        result.push_back(pointAt(t));
+        if (n > 0)
+        {
+            double x = finalPoint()[X] - initialPoint()[X];
+            result.push_back( Point(x, 0) );
+        }
+        if (n > 1)
+        {
+            /* higher order derivatives are zero,
+             * so the other n-1 vector elements are (0,0) */
+            result.insert( result.end(), n-1, Point(0, 0) );
+        }
+        return result;
+    }
+
        D2<SBasis> toSBasis() const
        {
                return m_line_seg.toSBasis();
@@ -473,20 +478,25 @@ class VLineSegment : public Curve
                
                return initialPoint()[Y] + t * (finalPoint()[Y] - initialPoint()[Y]);
        }
-       
-       std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
-       {
-               std::vector<Point> result;
-               if ( n > 0)
-                       result.push_back(pointAt(t));
-               if (n > 1)
-               {
-                       double y = finalPoint()[Y] - initialPoint()[Y];
-                       result.push_back( Point(0, y) );
-               }
-               return result;
-       }
-       
+
+    std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
+    {
+        std::vector<Point> result;
+        result.push_back(pointAt(t));
+        if (n > 0)
+        {
+            double y = finalPoint()[Y] - initialPoint()[Y];
+            result.push_back( Point(0, y) );
+        }
+        if (n > 1)
+        {
+            /* higher order derivatives are zero,
+             * so the other n-1 vector elements are (0,0) */
+            result.insert( result.end(), n-1, Point(0, 0) );
+        }
+        return result;
+    }
+
        D2<SBasis> toSBasis() const
        {
                return m_line_seg.toSBasis();
index 8f51c46c20b7ac26e58655706171326a1fd81e06..719a66478f4105e4b83742bc2427b2221472fc3a 100644 (file)
@@ -126,6 +126,21 @@ private:
   Iterator impl_;
 };
 
+/*
+ * Open and closed paths: all paths, whether open or closed, store a final
+ * segment which connects the initial and final endpoints of the "real"
+ * path data.  While similar to the "z" in an SVG path, it exists for
+ * both open and closed paths, and is not considered part of the "normal"
+ * path data, which is always covered by the range [begin(), end_open()).
+ * Conversely, the range [begin(), end_closed()) always contains the "extra"
+ * closing segment.
+ *
+ * The only difference between a closed and an open path is whether end()
+ * returns end_closed() or end_open().  The idea behind this is to let
+ * any path be stroked using [begin(), end()), and filled using
+ * [begin(), end_closed()), without requiring a separate "filled" version
+ * of the path to use for filling.
+ */
 class Path {
 private:
   typedef std::vector<Curve *> Sequence;
@@ -598,7 +613,7 @@ class PathPortion : public Curve {
 
   virtual Curve *transformed(Matrix const &m) const = 0;
 
-  virtual Point pointAt(Coord t) const { return pointAndDerivatives(t, 1).front(); }
+  virtual Point pointAt(Coord t) const { return pointAndDerivatives(t, 0).front(); }
   virtual Coord valueAt(Coord t, Dim2 d) const { return pointAt(t)[d]; }
   virtual std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const = 0;
   virtual D2<SBasis> toSBasis() const = 0;
index 3f13d15b01ef9215ba7b16262d6bbce8c70bf863..8992c0097d3987f6d740fc8568c770506a9dc107 100644 (file)
@@ -79,9 +79,9 @@ class Piecewise {
     inline output_type lastValue() const {
         return valueAt(cuts.back());
     }
-    std::vector<output_type> valueAndDerivatives(double t, unsigned cnt) const {
+    std::vector<output_type> valueAndDerivatives(double t, unsigned n_derivs) const {
         unsigned n = segN(t);
-        std::vector<output_type> ret, val = segs[n].valueAndDerivatives(segT(t, n), cnt);
+        std::vector<output_type> ret, val = segs[n].valueAndDerivatives(segT(t, n), n_derivs);
         double mult = 1;
         for(unsigned i = 0; i < val.size(); i++) {
             ret.push_back(val[i] * mult);
index 52d3ef6a9dcc960526d5fba87a88b4e488f28bc8..51a4ec97d998949813c19ee3766318f627c48d69 100644 (file)
@@ -330,10 +330,26 @@ void subdiv_sbasis(SBasis const & s,
 
 // It is faster to use the bernstein root finder for small degree polynomials (<100?.
 
+std::vector<double> roots1(SBasis const & s) {
+    std::vector<double> res;
+    double d = s[0][0] - s[0][1];
+    if(d != 0) {
+        double r = s[0][0] / d;
+        if(0 <= r and r <= 1)
+            res.push_back(r);
+    }
+    return res;
+}
+
 std::vector<double> roots(SBasis const & s) {
-    if(s.size() == 0) return std::vector<double>();
-    
-    return sbasis_to_bezier(s).roots();
+    switch(s.size()) {
+    case 0:
+        return std::vector<double>();
+    case 1:
+        return roots1(s);
+    default:
+        return sbasis_to_bezier(s).roots();
+    }
 }
 
 };
index 920fd37fe7ed29b66c58d5cfa904b18a806c1326..d7a3972e1709662586bdf1b792ad73307081368b 100644 (file)
@@ -69,15 +69,12 @@ bool SBasis::isFinite() const {
 }
 
 std::vector<double> SBasis::valueAndDerivatives(double t, unsigned n) const {
-    std::vector<double> ret(n);
-    if(n==1) {
-        ret.push_back(valueAt(t));
-        return ret;
-    }
+    std::vector<double> ret(n+1);
+    ret.push_back(valueAt(t));
     SBasis tmp = *this;
     for(unsigned i = 0; i < n; i++) {
-        ret[i] = tmp.valueAt(t);
         tmp.derive();
+        ret[i] = tmp.valueAt(t);
     }
     return ret;
 }