diff options
| author | Liam P. White <inkscapebrony@gmail.com> | 2014-08-31 18:59:47 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebrony@gmail.com> | 2014-08-31 18:59:47 +0000 |
| commit | 6a306cf8edbaebacbe679a58f6b162657caf5ad0 (patch) | |
| tree | f043ce64170b0ab7ada1712efb8e38a3fbe5681a /src/snap.cpp | |
| parent | Update to experimental r13483 (diff) | |
| parent | Header cleanup: stop using Glib types where they aren't truly needed. Eases G... (diff) | |
| download | inkscape-6a306cf8edbaebacbe679a58f6b162657caf5ad0.tar.gz inkscape-6a306cf8edbaebacbe679a58f6b162657caf5ad0.zip | |
Update to experimental r13531
(bzr r13090.1.106)
Diffstat (limited to 'src/snap.cpp')
| -rw-r--r-- | src/snap.cpp | 85 |
1 files changed, 36 insertions, 49 deletions
diff --git a/src/snap.cpp b/src/snap.cpp index e067cf8f7..fb87aae6b 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -274,7 +274,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapCandidatePoint /* See the documentation for constrainedSnap() directly above for more details. * The difference is that multipleConstrainedSnaps() will take a list of constraints instead of a single one, - * and will try to snap the SnapCandidatePoint to all of the provided constraints and see which one fits best + * and will try to snap the SnapCandidatePoint to only the closest constraint * \param p Source point to be snapped * \param constraints List of directions or lines along which snapping must occur * \param dont_snap If true then we will only apply the constraint, without snapping @@ -293,16 +293,11 @@ Inkscape::SnappedPoint SnapManager::multipleConstrainedSnaps(Inkscape::SnapCandi return no_snap; } - IntermSnapResults isr; - SnapperList const snappers = getSnappers(); - std::vector<Geom::Point> projections; - bool snapping_is_futile = !someSnapperMightSnap() || dont_snap; - - Inkscape::SnappedPoint result = no_snap; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool snap_mouse = prefs->getBool("/options/snapmousepointer/value", false); + // We haven't tried to snap yet; we will first determine which constraint is closest to where we are now, + // i.e. lets find out which of the constraints yields the closest projection of point p + // Project the mouse pointer on each of the constraints + std::vector<Geom::Point> projections; for (std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); c != constraints.end(); ++c) { // Project the mouse pointer onto the constraint; In case we don't snap then we will // return the projection onto the constraint, such that the constraint is always enforced @@ -310,55 +305,47 @@ Inkscape::SnappedPoint SnapManager::multipleConstrainedSnaps(Inkscape::SnapCandi projections.push_back(pp); } - if (snap_mouse && p.isSingleHandle() && !dont_snap) { + // Select the closest constraint + no_snap.setPoint(projections.front()); + Inkscape::Snapper::SnapConstraint cc = constraints.front(); //closest constraint + + std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); + std::vector<Geom::Point>::iterator pp = projections.begin(); + for (; pp != projections.end(); ++pp) { + if (Geom::L2(*pp - p.getPoint()) < Geom::L2(no_snap.getPoint() - p.getPoint())) { + no_snap.setPoint(*pp); // Remember the projection onto the closest constraint + cc = *c; // Remember the closest constraint itself + } + ++c; + } + + if (!someSnapperMightSnap() || dont_snap) { + return no_snap; + } + + IntermSnapResults isr; + SnapperList const snappers = getSnappers(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool snap_mouse = prefs->getBool("/options/snapmousepointer/value", false); + + Inkscape::SnappedPoint result = no_snap; + if (snap_mouse && p.isSingleHandle()) { // Snapping the mouse pointer instead of the constrained position of the knot allows // to snap to things which don't intersect with the constraint line; this is basically // then just a freesnap with the constraint applied afterwards // We'll only to this if we're dragging a single handle, and for example not when transforming an object in the selector tool result = freeSnap(p, bbox_to_snap); + // Now apply the constraint afterwards + result.setPoint(cc.projection(result.getPoint())); } else { - // Iterate over the constraints - for (std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); c != constraints.end(); ++c) { - // Try to snap to the constraint - if (!snapping_is_futile) { - for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); ++i) { - (*i)->constrainedSnap(isr, p, bbox_to_snap, *c, &_items_to_ignore,_unselected_nodes); - } - } + // Try to snap along the closest constraint + for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); ++i) { + (*i)->constrainedSnap(isr, p, bbox_to_snap, cc, &_items_to_ignore,_unselected_nodes); } result = findBestSnap(p, isr, true); } - if (result.getSnapped()) { - if (snap_mouse) { - // If "snap_mouse" then we still have to apply the constraint, because so far we only tried a freeSnap - Geom::Point result_closest; - for (std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); c != constraints.end(); ++c) { - // Project the mouse pointer onto the constraint; In case we don't snap then we will - // return the projection onto the constraint, such that the constraint is always enforced - Geom::Point result_p = (*c).projection(result.getPoint()); - if (c == constraints.begin() || (Geom::L2(result_p - p.getPoint()) < Geom::L2(result_closest - p.getPoint()))) { - result_closest = result_p; - } - } - result.setPoint(result_closest); - } - return result; - } - - // So we didn't snap, but we still need to return a point on one of the constraints - // Find out which of the constraints yielded the closest projection of point p - for (std::vector<Geom::Point>::iterator pp = projections.begin(); pp != projections.end(); ++pp) { - if (pp != projections.begin()) { - if (Geom::L2(*pp - p.getPoint()) < Geom::L2(no_snap.getPoint() - p.getPoint())) { - no_snap.setPoint(*pp); - } - } else { - no_snap.setPoint(projections.front()); - } - } - - return no_snap; + return result.getSnapped() ? result : no_snap; } Inkscape::SnappedPoint SnapManager::constrainedAngularSnap(Inkscape::SnapCandidatePoint const &p, |
