From 09f5ae2dc48630fe49482e0cf7b21eda1f3b765b Mon Sep 17 00:00:00 2001 From: cth103 Date: Fri, 5 May 2006 16:44:29 +0000 Subject: [PATCH] More snapping cleanups. --- src/nodepath.cpp | 19 ++++---- src/seltrans.cpp | 54 +++++++++++++-------- src/snap.cpp | 120 ++++++++++++++++++++++++++--------------------- src/snap.h | 28 ++++++----- 4 files changed, 125 insertions(+), 96 deletions(-) diff --git a/src/nodepath.cpp b/src/nodepath.cpp index 7eb68d7d6..e81abdacb 100644 --- a/src/nodepath.cpp +++ b/src/nodepath.cpp @@ -921,22 +921,19 @@ void sp_node_moveto(Inkscape::NodePath::Node *node, NR::Point p) static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath, NR::Coord dx, NR::Coord dy, bool const snap = true) { - NR::Coord best[2] = { NR_HUGE, NR_HUGE }; + NR::Coord best = NR_HUGE; NR::Point delta(dx, dy); NR::Point best_pt = delta; if (snap) { + SnapManager const &m = nodepath->desktop->namedview->snap_manager; + for (GList *l = nodepath->selected; l != NULL; l = l->next) { - Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; - NR::Point p = n->pos + delta; - for (int dim = 0; dim < 2; dim++) { - NR::Coord dist = namedview_dim_snap(nodepath->desktop->namedview, - Inkscape::Snapper::SNAP_POINT, p, - NR::Dim2(dim), nodepath->path); - if (dist < best[dim]) { - best[dim] = dist; - best_pt[dim] = p[dim] - n->pos[dim]; - } + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAP_POINT, n->pos + delta, NULL); + if (s.getDistance() < best) { + best = s.getDistance(); + best_pt = s.getPoint(); } } } diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 70dd0d1a0..2eeafd8d2 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -894,41 +894,55 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: if ( state & GDK_CONTROL_MASK ) { s[perp] = fabs(s[axis]); - std::pair sn = namedview_vector_snap_list(_desktop->namedview, - Snapper::BBOX_POINT, - _bbox_points, _origin, s, it); - std::pair bb = namedview_vector_snap_list(_desktop->namedview, - Snapper::SNAP_POINT, - _snap_points, _origin, s, it); + std::pair const bb = m.freeSnapStretch( + Snapper::BBOX_POINT, + _bbox_points, + it, + s[axis], + _origin, + axis, + true); + + std::pair const sn = m.freeSnapStretch( + Snapper::SNAP_POINT, + _snap_points, + it, + s[axis], + _origin, + axis, + true); - double bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; - double sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; - double ratio = (bd < sd) ? bb.first : sn.first; + NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + NR::Coord const ratio = (bd < sd) ? bb.first : sn.first; s[axis] = fabs(ratio) * sign(s[axis]); s[perp] = fabs(s[axis]); } else { - std::pair const bb = m.constrainedSnapScale( + std::pair const bb = m.freeSnapStretch( Snapper::BBOX_POINT, _bbox_points, it, - Inkscape::Snapper::ConstraintLine(component_vectors[axis]), - s, - _origin); + s[axis], + _origin, + axis, + false); - std::pair const sn = m.constrainedSnapScale( + std::pair const sn = m.freeSnapStretch( Snapper::SNAP_POINT, _snap_points, it, - Inkscape::Snapper::ConstraintLine(component_vectors[axis]), - s, - _origin); + s[axis], + _origin, + axis, + false); /* Choose the smaller difference in scale */ - NR::Coord const bd = bb.second ? fabs(bb.first[axis] - s[axis]) : NR_HUGE; - NR::Coord const sd = sn.second ? fabs(sn.first[axis] - s[axis]) : NR_HUGE; - s = (bd < sd) ? bb.first : sn.first; + NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + s[axis] = (bd < sd) ? bb.first : sn.first; + s[perp] = 1; } pt = ( _point - _origin ) * NR::scale(s) + _origin; diff --git a/src/snap.cpp b/src/snap.cpp index bf5385910..4971bada4 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -108,14 +108,17 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType } -std::pair SnapManager::_snapTransformed(Inkscape::Snapper::PointType type, - std::vector const &points, - std::list const &ignore, - bool constrained, - Inkscape::Snapper::ConstraintLine const &constraint, - Transformation transformation_type, - NR::Point const &transformation, - NR::Point const &origin) const +std::pair SnapManager::_snapTransformed( + Inkscape::Snapper::PointType type, + std::vector const &points, + std::list const &ignore, + bool constrained, + Inkscape::Snapper::ConstraintLine const &constraint, + Transformation transformation_type, + NR::Point const &transformation, + NR::Point const &origin, + NR::Dim2 dim, + bool uniform) const { /* We have a list of points, which we are proposing to transform in some way. We need to see ** if any of these points, when transformed, snap to anything. If they do, we return the @@ -129,10 +132,11 @@ std::pair SnapManager::_snapTransformed(Inkscape::Snapper::Poin /* The current best transformation */ NR::Point best_transformation = transformation; + /* The current best metric for the best transformation; lower is better, NR_HUGE ** means that we haven't snapped anything. */ - NR::Coord best_metric = NR_HUGE; + double best_metric = NR_HUGE; for (std::vector::const_iterator i = points.begin(); i != points.end(); i++) { @@ -145,6 +149,18 @@ std::pair SnapManager::_snapTransformed(Inkscape::Snapper::Poin case SCALE: transformed = ((*i - origin) * NR::scale(transformation[NR::X], transformation[NR::Y])) + origin; break; + case STRETCH: + { + NR::scale s(1, 1); + if (uniform) + s[NR::X] = s[NR::Y] = transformation[dim]; + else { + s[dim] = transformation[dim]; + s[1 - dim] = 1; + } + transformed = ((*i - origin) * s) + origin; + break; + } default: g_assert_not_reached(); } @@ -172,6 +188,18 @@ std::pair SnapManager::_snapTransformed(Inkscape::Snapper::Poin metric = std::abs(NR::L2(result) - NR::L2(transformation)); break; } + case STRETCH: + { + for (int j = 0; j < 2; j++) { + if (uniform || j == dim) { + result[j] = (snapped.getPoint()[dim] - origin[dim]) / ((*i)[dim] - origin[dim]); + } else { + result[j] = 1; + } + } + metric = std::abs(result[dim] - transformation[dim]); + break; + } default: g_assert_not_reached(); } @@ -193,7 +221,9 @@ std::pair SnapManager::freeSnapTranslation(Inkscape::Snapper::P std::list const &it, NR::Point const &tr) const { - return _snapTransformed(t, p, it, false, NR::Point(), TRANSLATION, tr, NR::Point(0, 0)); + return _snapTransformed( + t, p, it, false, NR::Point(), TRANSLATION, tr, NR::Point(), NR::X, false + ); } @@ -204,7 +234,9 @@ std::pair SnapManager::constrainedSnapTranslation(Inkscape::Sna Inkscape::Snapper::ConstraintLine const &c, NR::Point const &tr) const { - return _snapTransformed(t, p, it, true, c, TRANSLATION, tr, NR::Point(0, 0)); + return _snapTransformed( + t, p, it, true, c, TRANSLATION, tr, NR::Point(), NR::X, false + ); } std::pair SnapManager::freeSnapScale(Inkscape::Snapper::PointType t, @@ -213,7 +245,9 @@ std::pair SnapManager::freeSnapScale(Inkscape::Snapper::PointTy NR::scale const &s, NR::Point const &o) const { - return _snapTransformed(t, p, it, false, NR::Point(0, 0), SCALE, NR::Point(s[NR::X], s[NR::Y]), o); + return _snapTransformed( + t, p, it, false, NR::Point(), SCALE, NR::Point(s[NR::X], s[NR::Y]), o, NR::X, false + ); } @@ -224,8 +258,27 @@ std::pair SnapManager::constrainedSnapScale(Inkscape::Snapper:: NR::scale const &s, NR::Point const &o) const { - return _snapTransformed(t, p, it, true, c, SCALE, NR::Point(s[NR::X], s[NR::Y]), o); -} + return _snapTransformed( + t, p, it, true, c, SCALE, NR::Point(s[NR::X], s[NR::Y]), o, NR::X, false + ); +} + + +std::pair SnapManager::freeSnapStretch(Inkscape::Snapper::PointType t, + std::vector const &p, + std::list const &it, + NR::Coord const &s, + NR::Point const &o, + NR::Dim2 d, + bool u) const +{ + std::pair const r = _snapTransformed( + t, p, it, false, NR::Point(), STRETCH, NR::Point(s, s), o, d, u + ); + + return std::make_pair(r.first[d], r.second); +} + /// Minimal distance to norm before point is considered for snap. @@ -300,45 +353,6 @@ NR::Coord namedview_vector_snap(SPNamedView const *nv, Inkscape::Snapper::PointT * They return the updated transformation parameter. */ -/** - * Snap list of points in two dimensions. - */ -std::pair namedview_vector_snap_list(SPNamedView const *nv, Inkscape::Snapper::PointType t, - const std::vector &p, NR::Point const &norm, - NR::scale const &s, std::list const &it) -{ - using NR::X; - using NR::Y; - - SnapManager const &m = nv->snap_manager; - - if (m.willSnapSomething() == false) { - return std::make_pair(s[X], false); - } - - NR::Coord dist = NR_HUGE; - double ratio = fabs(s[X]); - for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { - NR::Point const &q = *i; - NR::Point check = ( q - norm ) * s + norm; - if (NR::LInfty( q - norm ) > MIN_DIST_NORM) { - NR::Coord d = namedview_vector_snap(nv, t, check, check - norm, it); - if (d < dist) { - dist = d; - NR::Dim2 const dominant = ( ( fabs( q[X] - norm[X] ) > - fabs( q[Y] - norm[Y] ) ) - ? X - : Y ); - ratio = ( ( check[dominant] - norm[dominant] ) - / ( q[dominant] - norm[dominant] ) ); - } - } - } - - return std::make_pair(ratio, dist < NR_HUGE); -} - - /** * Try to snap points after they have been skewed. */ diff --git a/src/snap.h b/src/snap.h index d7050d822..ad5c68857 100644 --- a/src/snap.h +++ b/src/snap.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "grid-snapper.h" #include "guide-snapper.h" #include "object-snapper.h" @@ -75,6 +76,14 @@ public: NR::scale const &s, NR::Point const &o) const; + std::pair freeSnapStretch(Inkscape::Snapper::PointType t, + std::vector const &p, + std::list const &it, + NR::Coord const &s, + NR::Point const &o, + NR::Dim2 d, + bool uniform) const; + Inkscape::GridSnapper grid; Inkscape::GuideSnapper guide; Inkscape::ObjectSnapper object; @@ -84,12 +93,12 @@ public: private: - enum Transformation - { + enum Transformation { TRANSLATION, - SCALE + SCALE, + STRETCH }; - + std::pair _snapTransformed(Inkscape::Snapper::PointType type, std::vector const &points, std::list const &ignore, @@ -97,7 +106,9 @@ private: Inkscape::Snapper::ConstraintLine const &constraint, Transformation transformation_type, NR::Point const &transformation, - NR::Point const &origin) const; + NR::Point const &origin, + NR::Dim2 dim, + bool uniform) const; }; @@ -113,13 +124,6 @@ NR::Coord namedview_dim_snap(SPNamedView const *nv, Inkscape::Snapper::PointType /* List of points methods */ -std::pair namedview_vector_snap_list(SPNamedView const *nv, - Inkscape::Snapper::PointType t, const std::vector &p, - NR::Point const &norm, NR::scale const &s, - std::list const &it - ); - - NR::Coord namedview_dim_snap_list_skew(SPNamedView const *nv, Inkscape::Snapper::PointType t, const std::vector &p, NR::Point const &norm, double const sx, NR::Dim2 const dim); -- 2.39.5