summaryrefslogtreecommitdiffstats
path: root/src/snap.cpp
diff options
context:
space:
mode:
authorLiam P. White <inkscapebrony@gmail.com>2014-08-31 18:59:47 +0000
committerLiam P. White <inkscapebrony@gmail.com>2014-08-31 18:59:47 +0000
commit6a306cf8edbaebacbe679a58f6b162657caf5ad0 (patch)
treef043ce64170b0ab7ada1712efb8e38a3fbe5681a /src/snap.cpp
parentUpdate to experimental r13483 (diff)
parentHeader cleanup: stop using Glib types where they aren't truly needed. Eases G... (diff)
downloadinkscape-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.cpp85
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,