summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5631b9d)
raw | patch | inline | side by side (parent: 5631b9d)
author | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Fri, 20 Aug 2010 20:20:02 +0000 (22:20 +0200) | ||
committer | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Fri, 20 Aug 2010 20:20:02 +0000 (22:20 +0200) |
src/line-snapper.cpp | patch | blob | history | |
src/object-snapper.cpp | patch | blob | history | |
src/object-snapper.h | patch | blob | history |
diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp
index 0a1567a47a21454cfa6357acf50b9d9969779a26..be64438ed503d5b6282b77fed33348822f4b79b6 100644 (file)
--- a/src/line-snapper.cpp
+++ b/src/line-snapper.cpp
return;
}
+ // project the mouse pointer onto the constraint. Only the projected point will be considered for snapping
+ Geom::Point pp = c.projection(p.getPoint());
+
/* Get the lines that we will try to snap to */
- const LineList lines = _getSnapLines(p.getPoint());
+ const LineList lines = _getSnapLines(pp);
for (LineList::const_iterator i = lines.begin(); i != lines.end(); i++) {
- Geom::Point const point_on_line = c.hasPoint() ? c.getPoint() : p.getPoint();
+ Geom::Point const point_on_line = c.hasPoint() ? c.getPoint() : pp;
Geom::Line gridguide_line(i->second, i->second + Geom::rot90(i->first));
if (c.isCircular()) {
Geom::Coord radius = c.getRadius();
if (dist == radius) {
// Only one point of intersection;
- _addSnappedPoint(sc, p_proj, Geom::L2(p.getPoint() - p_proj), p.getSourceType(), p.getSourceNum(), true);
+ _addSnappedPoint(sc, p_proj, Geom::L2(pp - p_proj), p.getSourceType(), p.getSourceNum(), true);
} else if (dist < radius) {
// Two points of intersection, symmetrical with respect to the projected point
// Calculate half the length of the linesegment between the two points of intersection
Geom::Coord d = Geom::L2(gridguide_line.versor()); // length of versor, needed to normalize the versor
if (d > 0) {
Geom::Point v = l*gridguide_line.versor()/d;
- _addSnappedPoint(sc, p_proj + v, Geom::L2(p.getPoint() - (p_proj + v)), p.getSourceType(), p.getSourceNum(), true);
- _addSnappedPoint(sc, p_proj - v, Geom::L2(p.getPoint() - (p_proj - v)), p.getSourceType(), p.getSourceNum(), true);
+ _addSnappedPoint(sc, p_proj + v, Geom::L2(pp - (p_proj + v)), p.getSourceType(), p.getSourceNum(), true);
+ _addSnappedPoint(sc, p_proj - v, Geom::L2(pp - (p_proj - v)), p.getSourceType(), p.getSourceNum(), true);
}
}
} else {
if (inters) {
Geom::Point t = constraint_line.pointAt((*inters).ta);
- const Geom::Coord dist = Geom::L2(t - p.getPoint());
+ const Geom::Coord dist = Geom::L2(t - pp);
if (dist < getSnapperTolerance()) {
// When doing a constrained snap, we're already at an intersection.
// This snappoint is therefore fully constrained, so there's no need
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 1540fbabca8df437834890b8d22ed6a9162675d1..f9e21174acb3694eb4fb80f9844d4e363936a0fa 100644 (file)
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
Inkscape::SnapCandidatePoint const &p,
std::vector<SnapCandidatePoint> *unselected_nodes,
- SnapConstraint const &c) const
+ SnapConstraint const &c,
+ Geom::Point const &p_proj_on_constraint) const
{
// Iterate through all nodes, find out which one is the closest to p, and snap to it!
for (std::vector<SnapCandidatePoint>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
Geom::Point target_pt = (*k).getPoint();
+ Geom::Coord dist = NR_HUGE;
if (!c.isUndefined()) {
// We're snapping to nodes along a constraint only, so find out if this node
// is at the constraint, while allowing for a small margin
// is too large, so this point is not on the constraint. Skip it!
continue;
}
+ dist = Geom::L2(target_pt - p_proj_on_constraint);
+ } else {
+ // Free (unconstrained) snapping
+ dist = Geom::L2(target_pt - p.getPoint());
}
- Geom::Coord dist = Geom::L2(target_pt - p.getPoint());
if (dist < getSnapperTolerance() && dist < s.getSnapDistance()) {
s = SnappedPoint(target_pt, p.getSourceType(), p.getSourceNum(), (*k).getTargetType(), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, true, (*k).getTargetBBox());
success = true;
_collectNodes(SNAPSOURCE_GUIDE, true);
if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
- _collectPaths(Inkscape::SnapCandidatePoint(p, SNAPSOURCE_GUIDE), true);
+ _collectPaths(p, SNAPSOURCE_GUIDE, true);
_snapPaths(sc, Inkscape::SnapCandidatePoint(p, SNAPSOURCE_GUIDE), NULL, NULL);
}
* Returns index of first NR_END bpath in array.
*/
-void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapCandidatePoint const &p,
+void Inkscape::ObjectSnapper::_collectPaths(Geom::Point p,
+ Inkscape::SnapSourceType const source_type,
bool const &first_point) const
{
// Now, let's first collect all paths to snap to. If we have a whole bunch of points to snap,
@@ -342,8 +348,8 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapCandidatePoint const &
// Determine the type of bounding box we should snap to
SPItem::BBoxType bbox_type = SPItem::GEOMETRIC_BBOX;
- bool p_is_a_node = p.getSourceType() & Inkscape::SNAPSOURCE_NODE_CATEGORY;
- bool p_is_other = p.getSourceType() & Inkscape::SNAPSOURCE_OTHER_CATEGORY;
+ bool p_is_a_node = source_type & Inkscape::SNAPSOURCE_NODE_CATEGORY;
+ bool p_is_other = source_type & Inkscape::SNAPSOURCE_OTHER_CATEGORY;
if (_snapmanager->snapprefs.getSnapToBBoxPath()) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes,
SPPath const *selected_path) const
{
- _collectPaths(p, p.getSourceNum() == 0);
+ _collectPaths(p.getPoint(), p.getSourceType(), p.getSourceNum() == 0);
// Now we can finally do the real snapping, using the paths collected above
g_assert(_snapmanager->getDesktop() != NULL);
@@ -542,15 +548,16 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
Inkscape::SnapCandidatePoint const &p,
- SnapConstraint const &c) const
+ SnapConstraint const &c,
+ Geom::Point const &p_proj_on_constraint) const
{
- _collectPaths(p, p.getSourceNum() == 0);
+ _collectPaths(p_proj_on_constraint, p.getSourceType(), p.getSourceNum() == 0);
// Now we can finally do the real snapping, using the paths collected above
g_assert(_snapmanager->getDesktop() != NULL);
- Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p.getPoint());
+ Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p_proj_on_constraint);
Geom::Point direction_vector = c.getDirection();
if (!is_zero(direction_vector)) {
// The intersection point of the constraint line with any path, must lie within two points on the
// SnapConstraint: p_min_on_cl and p_max_on_cl. The distance between those points is twice the snapping tolerance
- Geom::Point const p_proj_on_cl = p.getPoint(); // projection has already been taken care of in constrainedSnap in the snapmanager;
- Geom::Point const p_min_on_cl = _snapmanager->getDesktop()->dt2doc(p_proj_on_cl - getSnapperTolerance() * direction_vector);
- Geom::Point const p_max_on_cl = _snapmanager->getDesktop()->dt2doc(p_proj_on_cl + getSnapperTolerance() * direction_vector);
+ Geom::Point const p_min_on_cl = _snapmanager->getDesktop()->dt2doc(p_proj_on_constraint - getSnapperTolerance() * direction_vector);
+ Geom::Point const p_max_on_cl = _snapmanager->getDesktop()->dt2doc(p_proj_on_constraint + getSnapperTolerance() * direction_vector);
Geom::Coord tolerance = getSnapperTolerance();
// PS: Because the paths we're about to snap to are all expressed relative to document coordinate system, we will have
Geom::Point p_inters = constraint_path[index].pointAt((*m).ta);
// .. and convert it to desktop coordinates
p_inters = _snapmanager->getDesktop()->doc2dt(p_inters);
- Geom::Coord dist = Geom::L2(p_proj_on_cl - p_inters);
+ Geom::Coord dist = Geom::L2(p_proj_on_constraint - p_inters);
SnappedPoint s = SnappedPoint(p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, k->target_bbox);;
if (dist <= tolerance) { // If the intersection is within snapping range, then we might snap to it
sc.points.push_back(s);
return;
}
+ // project the mouse pointer onto the constraint. Only the projected point will be considered for snapping
+ Geom::Point pp = c.projection(p.getPoint());
+
/* Get a list of all the SPItems that we will try to snap to */
if (p.getSourceNum() == 0) {
- Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p.getPoint(), p.getPoint());
+ Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(pp, pp);
_findCandidates(sp_document_root(_snapmanager->getDocument()), it, p.getSourceNum() == 0, local_bbox_to_snap, false, Geom::identity());
}
));
if (snap_nodes) {
- _snapNodes(sc, p, unselected_nodes, c);
+ _snapNodes(sc, p, unselected_nodes, c, pp);
}
if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
- _snapPathsConstrained(sc, p, c);
+ _snapPathsConstrained(sc, p, c, pp);
}
}
diff --git a/src/object-snapper.h b/src/object-snapper.h
index 4933d84598ed72ec1acce5e3ca984c282b5eed59..6bde3dd391a531fd7fc75bea43b0df780e67903d 100644 (file)
--- a/src/object-snapper.h
+++ b/src/object-snapper.h
Geom::Matrix const additional_affine) const;
void _snapNodes(SnappedConstraints &sc,
- Inkscape::SnapCandidatePoint const &p,
+ Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
std::vector<SnapCandidatePoint> *unselected_nodes,
- SnapConstraint const &c = SnapConstraint()) const; // in desktop coordinates
+ SnapConstraint const &c = SnapConstraint(),
+ Geom::Point const &p_proj_on_constraint = Geom::Point()) const;
void _snapTranslatingGuide(SnappedConstraints &sc,
Geom::Point const &p,
void _snapPathsConstrained(SnappedConstraints &sc,
Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
- SnapConstraint const &c) const;
+ SnapConstraint const &c,
+ Geom::Point const &p_proj_on_constraint) const;
bool isUnselectedNode(Geom::Point const &point, std::vector<Inkscape::SnapCandidatePoint> const *unselected_nodes) const;
- void _collectPaths(Inkscape::SnapCandidatePoint const &p,
- bool const &first_point) const;
+ void _collectPaths(Geom::Point p,
+ Inkscape::SnapSourceType const source_type,
+ bool const &first_point) const;
void _clear_paths() const;
Geom::PathVector* _getBorderPathv() const;