summaryrefslogtreecommitdiffstats
path: root/src/2geom
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2015-07-15 18:18:11 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2015-07-15 18:18:11 +0000
commit8d9336326e52ee6a181c658d57c7c3a3b776fcf8 (patch)
tree85d94032dfad14f71790fd276795781d4561456e /src/2geom
parentAdd a script that simplifies syncing 2Geom changes (diff)
downloadinkscape-8d9336326e52ee6a181c658d57c7c3a3b776fcf8.tar.gz
inkscape-8d9336326e52ee6a181c658d57c7c3a3b776fcf8.zip
Sync 2Geom to revision 2420.
Should fix build failure on llvm-gcc 4.2 and an issue with powerstroke. (bzr r14247)
Diffstat (limited to 'src/2geom')
-rw-r--r--src/2geom/ellipse.cpp52
-rw-r--r--src/2geom/path.cpp3
2 files changed, 40 insertions, 15 deletions
diff --git a/src/2geom/ellipse.cpp b/src/2geom/ellipse.cpp
index fed3bf86f..4b5ad9762 100644
--- a/src/2geom/ellipse.cpp
+++ b/src/2geom/ellipse.cpp
@@ -205,22 +205,50 @@ Ellipse::arc(Point const &ip, Point const &inner, Point const &fp)
bool sweep_flag = false;
// Determination of large arc flag:
- // The arc is larger than half of the ellipse if the inner point
- // is on the same side of the line going from the initial
- // to the final point as the center of the ellipse
- Point versor = fp - ip;
- double sdist_c = cross(versor, _center - ip);
- double sdist_inner = cross(versor, inner - ip);
-
- // if we have exactly half of an arc, do not set the large flag.
- if (sdist_c != 0 && sgn(sdist_c) == sgn(sdist_inner)) {
+ // large_arc is false when the inner point is on the same side
+ // of the center---initial point line as the final point, AND
+ // is on the same side of the center---final point line as the
+ // initial point.
+ // Additionally, large_arc is always false when we have exactly
+ // 1/2 of an arc, i.e. the cross product of the center -> initial point
+ // and center -> final point vectors is zero.
+ // Negating the above leads to the condition for large_arc being true.
+ Point fv = fp - _center;
+ Point iv = ip - _center;
+ Point innerv = inner - _center;
+ double ifcp = cross(fv, iv);
+
+ if (ifcp != 0 && (sgn(cross(fv, innerv)) != sgn(ifcp) ||
+ sgn(cross(iv, innerv)) != sgn(-ifcp)))
+ {
large_arc_flag = true;
}
+ //cross(-iv, fv) && large_arc_flag
+
+
// Determination of sweep flag:
- // If the inner point is on the left side of the ip-fp line,
- // we go in clockwise direction.
- if (sdist_inner < 0) {
+ // For clarity, let's assume that Y grows up. Then the cross product
+ // is positive for points on the left side of a vector and negative
+ // on the right side of a vector.
+ //
+ // cross(?, v) > 0
+ // o------------------->
+ // cross(?, v) < 0
+ //
+ // If the arc is small (large_arc_flag is false) and the final point
+ // is on the right side of the vector initial point -> center,
+ // we have to go in the direction of increasing angles
+ // (counter-clockwise) and the sweep flag is true.
+ // If the arc is large, the opposite is true, since we have to reach
+ // the final point going the long way - in the other direction.
+ // We can express this observation as:
+ // cross(_center - ip, fp - _center) < 0 xor large_arc flag
+ // This is equal to:
+ // cross(-iv, fv) < 0 xor large_arc flag
+ // But cross(-iv, fv) is equal to cross(fv, iv) due to antisymmetry
+ // of the cross product, so we end up with the condition below.
+ if ((ifcp < 0) ^ large_arc_flag) {
sweep_flag = true;
}
diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp
index 836e65013..871441751 100644
--- a/src/2geom/path.cpp
+++ b/src/2geom/path.cpp
@@ -441,7 +441,6 @@ std::vector<PathTime> Path::roots(Coord v, Dim2 d) const
// The class below implements sweepline optimization for curve intersection in paths.
// Instead of O(N^2), this takes O(N + X), where X is the number of overlaps
// between the bounding boxes of curves.
-namespace {
struct CurveSweepTraits {
struct Bound {
@@ -512,8 +511,6 @@ private:
Coord _precision;
};
-} // end anonymous namespace
-
std::vector<PathIntersection> Path::intersect(Path const &other, Coord precision) const
{
std::vector<PathIntersection> result;