summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 405bfcd)
raw | patch | inline | side by side (parent: 405bfcd)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Tue, 17 Jun 2008 21:03:42 +0000 (21:03 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Tue, 17 Jun 2008 21:03:42 +0000 (21:03 +0000) |
diff --git a/src/2geom/bezier.h b/src/2geom/bezier.h
index 289a6772953e69337ccf4df040ce3934c8216061..bc9d6032e63fe0c8befdacdb2ce28e0f7764be28 100644 (file)
--- a/src/2geom/bezier.h
+++ b/src/2geom/bezier.h
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;
diff --git a/src/2geom/concepts.h b/src/2geom/concepts.h
index ba45222746088391815530fb9d1f1d71263113d6..3b6fd3577bd800d877c1ed6b38ae2dca33b5fa71 100644 (file)
--- a/src/2geom/concepts.h
+++ b/src/2geom/concepts.h
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();
diff --git a/src/2geom/curve.h b/src/2geom/curve.h
index d201d5d5e0e1d1aecd8419652117e37e96355ee3..7f138dabf92653c5f6a838435ad69f8ecd8d4b44 100644 (file)
--- a/src/2geom/curve.h
+++ b/src/2geom/curve.h
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;
};
diff --git a/src/2geom/d2.h b/src/2geom/d2.h
index 3becc813d3c983c1398deb6fcb0261c35d46d74c..db8cf68c4e503ca012a0f6c0c00edc30ca311e74 100644 (file)
--- a/src/2geom/d2.h
+++ b/src/2geom/d2.h
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)
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)
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();
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();
diff --git a/src/2geom/path.h b/src/2geom/path.h
index 8f51c46c20b7ac26e58655706171326a1fd81e06..719a66478f4105e4b83742bc2427b2221472fc3a 100644 (file)
--- a/src/2geom/path.h
+++ b/src/2geom/path.h
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;
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;
diff --git a/src/2geom/piecewise.h b/src/2geom/piecewise.h
index 3f13d15b01ef9215ba7b16262d6bbce8c70bf863..8992c0097d3987f6d740fc8568c770506a9dc107 100644 (file)
--- a/src/2geom/piecewise.h
+++ b/src/2geom/piecewise.h
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)
// 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();
+ }
}
};
diff --git a/src/2geom/sbasis.cpp b/src/2geom/sbasis.cpp
index 920fd37fe7ed29b66c58d5cfa904b18a806c1326..d7a3972e1709662586bdf1b792ad73307081368b 100644 (file)
--- a/src/2geom/sbasis.cpp
+++ b/src/2geom/sbasis.cpp
}
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;
}