From 5b4319e0715220ba39530755e9d971cbf7fee47f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 22 May 2010 22:06:35 +0200 Subject: [PATCH] Snapping: get rid of the false positives when calculating intersections --- src/object-snapper.cpp | 7 ++++++- src/snapped-curve.cpp | 16 +++++++++++++++- src/snapped-curve.h | 4 +++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 5c0ea419b..bced0ac44 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -441,6 +441,9 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, } } + int num_path = 0; + int num_segm = 0; + for (std::vector::const_iterator it_p = _paths_to_snap_to->begin(); it_p != _paths_to_snap_to->end(); it_p++) { bool const being_edited = node_tool_active && (*it_p).currently_being_edited; //if true then this pathvector it_pv is currently being edited in the node tool @@ -482,11 +485,13 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, if (!being_edited || (c1 && c2)) { Geom::Coord const dist = Geom::distance(sp_doc, p_doc); if (dist < getSnapperTolerance()) { - sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, p.getSourceType(), p.getSourceNum(), it_p->target_type, it_p->target_bbox)); + sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, num_path, num_segm, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, p.getSourceType(), p.getSourceNum(), it_p->target_type, it_p->target_bbox)); } } } + num_segm++; } // End of: for (Geom::PathVector::iterator ....) + num_path++; } } diff --git a/src/snapped-curve.cpp b/src/snapped-curve.cpp index e7df3cfad..77bc8280c 100644 --- a/src/snapped-curve.cpp +++ b/src/snapped-curve.cpp @@ -12,8 +12,10 @@ #include <2geom/crossing.h> #include <2geom/path-intersection.h> -Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, long source_num, SnapTargetType target, Geom::OptRect target_bbox) +Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, int num_path, int num_segm, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, long source_num, SnapTargetType target, Geom::OptRect target_bbox) { + _num_path = num_path; + _num_segm = num_segm; _distance = snapped_distance; _tolerance = std::max(snapped_tolerance, 1.0); _always_snap = always_snap; @@ -32,6 +34,8 @@ Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coo Inkscape::SnappedCurve::SnappedCurve() { + _num_path = 0; + _num_segm = 0; _distance = NR_HUGE; _tolerance = 1; _always_snap = false; @@ -68,6 +72,16 @@ Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &cur for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); i++) { Geom::Point p_ix = this->_curve->pointAt((*i).ta); Geom::Coord dist = Geom::distance(p_ix, p); + + // Test if we have two segments (curves) from the same path.. + if (this->_num_path == curve._num_path) { + // Never try to intersect a segment with itself + if (this->_num_segm == curve._num_segm) continue; + // Two subsequent segments (curves) in a path will have a common node; this node is not considered to be an intersection + if (this->_num_segm == curve._num_segm + 1 && (*i).ta == 0 && (*i).tb == 1) continue; + if (this->_num_segm + 1 == curve._num_segm && (*i).ta == 1 && (*i).tb == 0) continue; + } + if (dist < best_dist) { best_dist = dist; best_p = p_ix; diff --git a/src/snapped-curve.h b/src/snapped-curve.h index 21124c678..595f84411 100644 --- a/src/snapped-curve.h +++ b/src/snapped-curve.h @@ -24,12 +24,14 @@ class SnappedCurve : public SnappedPoint { public: SnappedCurve(); - SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, long source_num, SnapTargetType target, Geom::OptRect target_bbox); + SnappedCurve(Geom::Point const &snapped_point, int num_path, int num_segm, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, long source_num, SnapTargetType target, Geom::OptRect target_bbox); ~SnappedCurve(); Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve private: Geom::Curve const *_curve; + int _num_path; // Unique id of the path to which this segment belongs too + int _num_segm; // Sequence number of this segment in the path }; } -- 2.30.2