diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-11-23 23:36:49 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-11-23 23:36:49 +0000 |
| commit | 0969085ddf607a7a98cf7fd6d9b10da5fbebe62d (patch) | |
| tree | 59b2bc9ed3412ab2de4c703ef30342dfe2401704 /src/2geom | |
| parent | refactor from lastApplied (diff) | |
| parent | Fixed a bug pointed by suv running from comand line, also removed another des... (diff) | |
| download | inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.tar.gz inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.zip | |
fixing to trunk
(bzr r12588.1.34)
Diffstat (limited to 'src/2geom')
| -rw-r--r-- | src/2geom/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/2geom/crossing.cpp | 20 | ||||
| -rw-r--r-- | src/2geom/crossing.h | 1 | ||||
| -rw-r--r-- | src/2geom/ellipse.cpp | 7 | ||||
| -rw-r--r-- | src/2geom/math-utils.h | 4 | ||||
| -rw-r--r-- | src/2geom/numeric/symmetric-matrix-fs-operation.h | 2 | ||||
| -rw-r--r-- | src/2geom/numeric/symmetric-matrix-fs-trace.h | 2 | ||||
| -rw-r--r-- | src/2geom/path-intersection.cpp | 33 | ||||
| -rw-r--r-- | src/2geom/path.cpp | 6 | ||||
| -rw-r--r-- | src/2geom/svg-path-parser.cpp | 37 | ||||
| -rw-r--r-- | src/2geom/toposweep.cpp | 1 |
11 files changed, 68 insertions, 49 deletions
diff --git a/src/2geom/CMakeLists.txt b/src/2geom/CMakeLists.txt index b1c30f678..eeaecaa39 100644 --- a/src/2geom/CMakeLists.txt +++ b/src/2geom/CMakeLists.txt @@ -21,6 +21,7 @@ set(2geom_SRC nearest-point.cpp numeric/matrix.cpp path-intersection.cpp + path-sink.cpp path.cpp pathvector.cpp piecewise.cpp @@ -43,7 +44,6 @@ set(2geom_SRC solve-bezier-parametric.cpp svg-elliptical-arc.cpp svg-path-parser.cpp - svg-path.cpp sweep.cpp toposweep.cpp transforms.cpp @@ -94,6 +94,7 @@ set(2geom_SRC nearest-point.h ord.h path-intersection.h + path-sink.h path.h pathvector.h piecewise.h @@ -115,7 +116,6 @@ set(2geom_SRC solver.h svg-elliptical-arc.h svg-path-parser.h - svg-path.h sweep.h toposweep.h transforms.h diff --git a/src/2geom/crossing.cpp b/src/2geom/crossing.cpp index 13affa8e9..513327271 100644 --- a/src/2geom/crossing.cpp +++ b/src/2geom/crossing.cpp @@ -154,7 +154,6 @@ Crossings reverse_tb(Crossings const &cr, unsigned split, std::vector<double> ma Crossings ret; for(Crossings::const_iterator i = cr.begin(); i != cr.end(); ++i) { double mx = max[i->b - split]; - std::cout << i->b << "\n"; ret.push_back(Crossing(i->ta, i->tb > mx+0.01 ? (1 - (i->tb - mx) + mx) : mx - i->tb, !i->dir)); } @@ -181,6 +180,25 @@ CrossingSet reverse_tb(CrossingSet const &cr, unsigned split, std::vector<double return ret; } +// Delete any duplicates in a vector of crossings +// A crossing is considered to be a duplicate when it has both t_a and t_b near to another crossing's t_a and t_b +// For example, duplicates will be found when calculating the intersections of a linesegment with a polygon, if the +// endpoint of that line coincides with a cusp node of the polygon. In that case, an intersection will be found of +// the linesegment with each of the polygon's linesegments extending from the cusp node (i.e. two intersections) +void delete_duplicates(Crossings &crs) { + Crossings::reverse_iterator rit = crs.rbegin(); + + for (rit = crs.rbegin(); rit!= crs.rend(); ++rit) { + Crossings::reverse_iterator rit2 = rit; + while (++rit2 != crs.rend()) { + if (Geom::are_near((*rit).ta, (*rit2).ta) && Geom::are_near((*rit).tb, (*rit2).tb)) { + crs.erase((rit + 1).base()); // This +1 and .base() construction is needed to convert to a regular iterator + break; // out of while loop, and continue with next iteration of for loop + } + } + } +} + void clean(Crossings &/*cr_a*/, Crossings &/*cr_b*/) { /* if(cr_a.empty()) return; diff --git a/src/2geom/crossing.h b/src/2geom/crossing.h index 75c75fc24..d5012ae2b 100644 --- a/src/2geom/crossing.h +++ b/src/2geom/crossing.h @@ -183,6 +183,7 @@ CrossingSet reverse_ta(CrossingSet const &cr, unsigned split, std::vector<double CrossingSet reverse_tb(CrossingSet const &cr, unsigned split, std::vector<double> max); void clean(Crossings &cr_a, Crossings &cr_b); +void delete_duplicates(Crossings &crs); } diff --git a/src/2geom/ellipse.cpp b/src/2geom/ellipse.cpp index bea99e5dd..2686844b2 100644 --- a/src/2geom/ellipse.cpp +++ b/src/2geom/ellipse.cpp @@ -36,6 +36,7 @@ #include <2geom/numeric/fitting-tool.h> #include <2geom/numeric/fitting-model.h> +using std::swap; namespace Geom { @@ -102,7 +103,7 @@ void Ellipse::set(double A, double B, double C, double D, double E, double F) // the solution is not unique so we choose always the ellipse // with a rotation angle between 0 and PI/2 - if ( swap_axes ) std::swap(rx, ry); + if ( swap_axes ) swap(rx, ry); if ( are_near(rot, M_PI/2) || are_near(rot, -M_PI/2) || are_near(rx, ry) ) @@ -233,7 +234,7 @@ Ellipse Ellipse::transformed(Affine const& m) const Point new_center = center() * m; Affine M = m.withoutTranslation(); Affine AM = A * M; - if ( are_near(AM.det(), 0) ) + if ( are_near(std::sqrt(fabs(AM.det())), 0) ) { double angle; if (AM[0] != 0) @@ -262,7 +263,7 @@ Ellipse Ellipse::transformed(Affine const& m) const Affine invm = M.inverse(); Q = invm * Q ; - std::swap( invm[1], invm[2] ); + swap( invm[1], invm[2] ); Q *= invm; Ellipse e(Q[0], 2*Q[1], Q[3], 0, 0, -1); e.m_centre = new_center; diff --git a/src/2geom/math-utils.h b/src/2geom/math-utils.h index 83c7b4f5e..0d5d3667b 100644 --- a/src/2geom/math-utils.h +++ b/src/2geom/math-utils.h @@ -111,7 +111,7 @@ inline void sincos(double angle, double &sin_, double &cos_) { # define IS_NAN(_a) (_isnan(_a)) /* Win32 definition */ #elif defined(isnan) || defined(__FreeBSD__) || defined(__osf__) # define IS_NAN(_a) (isnan(_a)) /* GNU definition */ -#elif defined (SOLARIS_2_8) && __GNUC__ == 3 && __GNUC_MINOR__ == 2 +#elif defined (SOLARIS) # define IS_NAN(_a) (isnan(_a)) /* GNU definition */ #else # define IS_NAN(_a) (boost::math::isnan(_a)) @@ -129,7 +129,7 @@ inline void sincos(double angle, double &sin_, double &cos_) { # define IS_FINITE(_a) (isfinite(_a)) #elif defined(__osf__) # define IS_FINITE(_a) (finite(_a) && !IS_NAN(_a)) -#elif defined (SOLARIS_2_8) && __GNUC__ == 3 && __GNUC_MINOR__ == 2 +#elif defined (SOLARIS) #include <ieeefp.h> #define IS_FINITE(_a) (finite(_a) && !IS_NAN(_a)) #else diff --git a/src/2geom/numeric/symmetric-matrix-fs-operation.h b/src/2geom/numeric/symmetric-matrix-fs-operation.h index 5222d2734..37ece56ae 100644 --- a/src/2geom/numeric/symmetric-matrix-fs-operation.h +++ b/src/2geom/numeric/symmetric-matrix-fs-operation.h @@ -44,7 +44,7 @@ namespace Geom { namespace NL { template <size_t N> inline -SymmetricMatrix<N> adj(const ConstBaseSymmetricMatrix<N> & S) +SymmetricMatrix<N> adj(const ConstBaseSymmetricMatrix<N> & /*S*/) { THROW_NOTIMPLEMENTED(); return SymmetricMatrix<N>(); diff --git a/src/2geom/numeric/symmetric-matrix-fs-trace.h b/src/2geom/numeric/symmetric-matrix-fs-trace.h index 099c834a8..dbabecf6e 100644 --- a/src/2geom/numeric/symmetric-matrix-fs-trace.h +++ b/src/2geom/numeric/symmetric-matrix-fs-trace.h @@ -74,7 +74,7 @@ template <size_t K, size_t N> struct trace { static - double evaluate (const ConstBaseSymmetricMatrix<N> & S) + double evaluate (const ConstBaseSymmetricMatrix<N> & /*S*/) { THROW_NOTIMPLEMENTED(); return K; diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index ff24b92eb..63a29423d 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -164,20 +164,35 @@ void append(T &a, T const &b) { bool linear_intersect(Point A0, Point A1, Point B0, Point B1, double &tA, double &tB, double &det) { - // kramers rule as cross products + bool both_lines_non_zero = (!are_near(A0, A1)) && (!are_near(B0, B1)); + + // Cramer's rule as cross products Point Ad = A1 - A0, Bd = B1 - B0, d = B0 - A0; det = cross(Ad, Bd); - if( 1.0 + det == 1.0 ) - return false; - else - { - double detinv = 1.0 / det; - tA = cross(d, Bd) * detinv; - tB = cross(d, Ad) * detinv; - return tA >= 0. && tA <= 1. && tB >= 0. && tB <= 1.; + + double det_rel = det; // Calculate the determinant of the normalized vectors + if (both_lines_non_zero) { + det_rel /= Ad.length(); + det_rel /= Bd.length(); } + + if( fabs(det_rel) < 1e-12 ) { // If the cross product is NEARLY zero, + // Then one of the linesegments might have length zero + if (both_lines_non_zero) { + // If that's not the case, then we must have either: + // - parallel lines, with no intersections, or + // - coincident lines, with an infinite number of intersections + // Either is quite useless, so we'll just bail out + return false; + } // Else, one of the linesegments is zero, and we might still be able to calculate a single intersection point + } // Else we haven't bailed out, and we'll try to calculate the intersections + + double detinv = 1.0 / det; + tA = cross(d, Bd) * detinv; + tB = cross(d, Ad) * detinv; + return (tA >= 0.) && (tA <= 1.) && (tB >= 0.) && (tB <= 1.); } diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp index 5797f475c..3558af3b3 100644 --- a/src/2geom/path.cpp +++ b/src/2geom/path.cpp @@ -104,12 +104,14 @@ Path &Path::operator*=(Affine const &m) { } Path &Path::operator*=(Translate const &m) { +/* Somehow there is something wrong here, LPE Construct grid fails with this code unshare(); Sequence::iterator last = get_curves().end() - 1; Sequence::iterator it; Point prev; for (it = get_curves().begin() ; it != last ; ++it) { - *(const_cast<Curve*>(&**it)) *= m; + // *(const_cast<Curve*>(&**it)) *= m; + const_cast<Curve*>(it->get())->operator*=(m); if ( it != get_curves().begin() && (*it)->initialPoint() != prev ) { THROW_CONTINUITYERROR(); } @@ -124,6 +126,8 @@ Path &Path::operator*=(Translate const &m) { } } return *this; +*/ + return this->operator*=(static_cast<Affine>(m)); } std::vector<double> diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index ccc383920..932f95829 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -1,5 +1,3 @@ - -#line 1 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" /** * \file * \brief parse SVG path specifications @@ -130,6 +128,9 @@ private: void _arcTo(double rx, double ry, double angle, bool large_arc, bool sweep, Point p) { + if (are_near(_current, p)) { + return; + } _quad_tangent = _cubic_tangent = _current = p; _sink.arcTo(rx, ry, angle, large_arc, sweep, p); } @@ -141,7 +142,6 @@ private: }; -#line 145 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" static const char _svg_path_actions[] = { 0, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 15, 1, @@ -1147,9 +1147,6 @@ static const int svg_path_first_final = 270; //static const int svg_path_en_main = 1; -#line 144 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" - - void Parser::parse(char const *str) throw(SVGPathParseError) { @@ -1159,13 +1156,11 @@ throw(SVGPathParseError) _reset(); - -#line 1164 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" { cs = svg_path_start; } -#line 1169 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" + { int _klen; unsigned int _trans; @@ -1238,13 +1233,12 @@ _match: switch ( *_acts++ ) { case 0: -#line 156 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { start = p; } break; case 1: -#line 160 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { char const *end=p; std::string buf(start, end); @@ -1253,55 +1247,49 @@ _match: } break; case 2: -#line 167 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { _push(1.0); } break; case 3: -#line 171 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { _push(0.0); } break; case 4: -#line 175 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { _absolute = true; } break; case 5: -#line 179 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _absolute = false; } break; case 6: -#line 183 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _moveTo(_pop_point()); } break; case 7: -#line 187 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _lineTo(_pop_point()); } break; case 8: -#line 191 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _hlineTo(Point(_pop_coord(X), _current[Y])); } break; case 9: -#line 195 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _vlineTo(Point(_current[X], _pop_coord(Y))); } break; case 10: -#line 199 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1310,7 +1298,6 @@ _match: } break; case 11: -#line 206 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1318,7 +1305,6 @@ _match: } break; case 12: -#line 212 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c = _pop_point(); @@ -1326,14 +1312,12 @@ _match: } break; case 13: -#line 218 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); _quadTo(_quad_tangent, p); } break; case 14: -#line 223 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point point = _pop_point(); bool sweep = _pop_flag(); @@ -1346,16 +1330,13 @@ _match: } break; case 15: -#line 234 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _closePath(); } break; case 16: -#line 370 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" {{p++; goto _out; }} break; -#line 1359 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" } } @@ -1367,8 +1348,6 @@ _again: _out: {} } -#line 380 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" - if ( cs < svg_path_first_final ) { throw SVGPathParseError(); diff --git a/src/2geom/toposweep.cpp b/src/2geom/toposweep.cpp index cfb91857c..4da3f6922 100644 --- a/src/2geom/toposweep.cpp +++ b/src/2geom/toposweep.cpp @@ -53,6 +53,7 @@ TopoGraph::Edge TopoGraph::remove_edge(unsigned ix, unsigned jx) { } } assert(0); + return v[0]; // if assert is disabled, return first Edge. } void TopoGraph::cannonize() { |
