Code

Fix #181795
authordvlierop2 <dvlierop2@users.sourceforge.net>
Sat, 12 Jan 2008 20:55:16 +0000 (20:55 +0000)
committerdvlierop2 <dvlierop2@users.sourceforge.net>
Sat, 12 Jan 2008 20:55:16 +0000 (20:55 +0000)
src/seltrans.cpp
src/snap.cpp
src/snap.h

index a747e6b4a9a44c7e8a13c107c34de4628b2475e2..f7ffe69c0b7ca6c38c6d48cc7491fa2a60579cc6 100644 (file)
@@ -919,9 +919,7 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state)
                                                                s,
                                                                _origin_for_specpoints);
 
-        if (bb.second == false && sn.second == false) {
-            /* We didn't snap, so just keep the locked aspect ratio */
-        } else {
+        if (bb.second || sn.second) { // If we snapped to something
             /* Choose the smaller difference in scale.  Since s[X] == s[Y] we can
             ** just compare difference in s[X].
             */
@@ -944,16 +942,18 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state)
                                                         s,
                                                         _origin_for_specpoints);
 
-       /* Pick the snap that puts us closest to the original scale */
-        NR::Coord bd = bb.second ?
-            fabs(NR::L2(NR::Point(bb.first[NR::X], bb.first[NR::Y])) -
-                 NR::L2(NR::Point(s[NR::X], s[NR::Y])))
-            : NR_HUGE;
-        NR::Coord sd = sn.second ?
-            fabs(NR::L2(NR::Point(sn.first[NR::X], sn.first[NR::Y])) -
-                 NR::L2(NR::Point(s[NR::X], s[NR::Y])))
-            : NR_HUGE;
-        s = (bd < sd) ? bb.first : sn.first;
+        if (bb.second || sn.second) { // If we snapped to something
+            /* Pick the snap that puts us closest to the original scale */
+            NR::Coord bd = bb.second ?
+                fabs(NR::L2(NR::Point(bb.first[NR::X], bb.first[NR::Y])) -
+                     NR::L2(NR::Point(s[NR::X], s[NR::Y])))
+                : NR_HUGE;
+            NR::Coord sd = sn.second ?
+                fabs(NR::L2(NR::Point(sn.first[NR::X], sn.first[NR::Y])) -
+                     NR::L2(NR::Point(s[NR::X], s[NR::Y])))
+                : NR_HUGE;
+            s = (bd < sd) ? bb.first : sn.first;
+        }
     }
 
     /* Update the knot position */
@@ -1022,7 +1022,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::
         // on ctrl, apply symmetrical scaling instead of stretching
         s[perp] = fabs(s[axis]);
 
-        std::pair<NR::Coord, bool> const bb = m.freeSnapStretch(
+        std::pair<NR::Coord, bool> const bb = m.constrainedSnapStretch(
             Snapper::SNAPPOINT_BBOX,
             _bbox_points,
             it,
@@ -1031,7 +1031,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::
             axis,
             true);
 
-        std::pair<NR::Coord, bool> const sn = m.freeSnapStretch(
+        std::pair<NR::Coord, bool> const sn = m.constrainedSnapStretch(
             Snapper::SNAPPOINT_NODE,
             _snap_points,
             it,
@@ -1040,15 +1040,20 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::
             axis,
             true);
 
-        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]);
+        if (bb.second || sn.second) { // If we snapped to something
+            /* Choose the smaller difference in scale */
+            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;
+            
+            if (fabs(ratio) < NR_HUGE) {
+                s[axis] = fabs(ratio) * sign(s[axis]);
+            }
+            s[perp] = fabs(s[axis]);
+        }
     } else {
 
-        std::pair<NR::Coord, bool> const bb = m.freeSnapStretch(
+        std::pair<NR::Coord, bool> const bb = m.constrainedSnapStretch(
             Snapper::SNAPPOINT_BBOX,
             _bbox_points,
             it,
@@ -1057,7 +1062,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::
             axis,
             false);
 
-        std::pair<NR::Coord, bool> const sn = m.freeSnapStretch(
+        std::pair<NR::Coord, bool> const sn = m.constrainedSnapStretch(
             Snapper::SNAPPOINT_NODE,
             _snap_points,
             it,
@@ -1066,12 +1071,16 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::
             axis,
             false);
 
-        /* Choose the smaller difference in scale */
-        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;
+        if (bb.second || sn.second) { // If we snapped to something
+            /* Choose the smaller difference in scale */
+            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 nw = (bd < sd) ? bb.first : sn.first; // new stretch scale
+            if (fabs(nw) < NR_HUGE) {
+                s[axis] = nw;
+            }
+            s[perp] = 1;
+        }
     }
 
     pt = ( _point - _origin ) * NR::scale(s) + _origin;
index 73a3b010b277692b8245530ad4cbfcc340baaf40..cb4ea3f5882af10ed7bad80830513ccbb4935728 100644 (file)
@@ -393,7 +393,7 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
     std::vector<NR::Point>::const_iterator j = transformed_points.begin();
 
     //std::cout << std::endl;
-
+    
     for (std::vector<NR::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
         
         /* Snap it */        
@@ -401,11 +401,13 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
                 
         if (constrained) {    
             Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
-            if (transformation_type == SCALE && uniform) {
+            if ((transformation_type == SCALE || transformation_type == STRETCH) && uniform) {
                 // When uniformly scaling, each point will have its own unique constraint line,
                 // running from the scaling origin to the original untransformed point. We will
                 // calculate that line here 
                 dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, (*i) - origin);
+            } else if (transformation_type == STRETCH || transformation_type == SKEW) { // when skewing or non-uniform stretching {
+                dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i), component_vectors[dim]);
             } // else: leave the original constraint, e.g. for constrained translation 
             if (transformation_type == SCALE && !uniform) {
                 g_warning("Non-uniform constrained scaling is not supported!");   
@@ -424,6 +426,9 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
             /* We snapped.  Find the transformation that describes where the snapped point has
             ** ended up, and also the metric for this transformation.
             */
+            NR::Point const a = (snapped.getPoint() - origin); // vector to snapped point
+            NR::Point const b = (*i - origin); // vector to original point
+            
             switch (transformation_type) {
                 case TRANSLATION:
                     result = snapped.getPoint() - *i;
@@ -441,8 +446,6 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
                     break;
                 case SCALE:
                 {
-                    NR::Point const a = (snapped.getPoint() - origin); // vector to snapped point
-                    NR::Point const b = (*i - origin); // vector to original point
                     result = NR::Point(NR_HUGE, NR_HUGE);
                     // If this point *i is horizontally or vertically aligned with
                     // the origin of the scaling, then it will scale purely in X or Y 
@@ -458,17 +461,19 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
                             // if scaling didn't occur in the other direction
                         }
                     }
-                    
                     // Compare the resulting scaling with the desired scaling
                     scale_metric = result - transformation; // One or both of its components might be NR_HUGE
                     break;
                 }
                 case STRETCH:
-                    for (int index = 0; index < 2; index++) {
-                        if (uniform || index == dim) {
-                            result[index] = (snapped.getPoint()[dim] - origin[dim]) / ((*i)[dim] - origin[dim]);
-                        } else {
-                            result[index] = 1;
+                    result = NR::Point(NR_HUGE, NR_HUGE);
+                    if (fabs(b[dim]) > 1e-6) { // if STRETCHING will occur for this point
+                        result[dim] = a[dim] / b[dim];
+                        result[1-dim] = uniform ? result[dim] : 1;
+                    } else { // STRETCHING might occur for this point, but only when the stretching is uniform
+                        if (uniform && fabs(b[1-dim]) > 1e-6) {
+                           result[1-dim] = a[1-dim] / b[1-dim];
+                           result[dim] = result[1-dim];
                         }
                     }
                     metric = std::abs(result[dim] - transformation[dim]);
@@ -521,7 +526,6 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
             }
         }
         
-        
         j++;
     }
     
@@ -655,7 +659,7 @@ std::pair<NR::scale, bool> SnapManager::constrainedSnapScale(Inkscape::Snapper::
  *  \return Snapped stretch, if a snap occurred, and a flag indicating whether a snap occurred.
  */
 
-std::pair<NR::Coord, bool> SnapManager::freeSnapStretch(Inkscape::Snapper::PointType t,
+std::pair<NR::Coord, bool> SnapManager::constrainedSnapStretch(Inkscape::Snapper::PointType t,
                                                         std::vector<NR::Point> const &p,
                                                         std::list<SPItem const *> const &it,
                                                         NR::Coord const &s,
@@ -664,7 +668,7 @@ std::pair<NR::Coord, bool> SnapManager::freeSnapStretch(Inkscape::Snapper::Point
                                                         bool u) const
 {
    std::pair<NR::Point, bool> const r = _snapTransformed(
-        t, p, it, false, NR::Point(), STRETCH, NR::Point(s, s), o, d, u
+        t, p, it, true, NR::Point(), STRETCH, NR::Point(s, s), o, d, u
         );
 
    return std::make_pair(r.first[d], r.second);
@@ -700,23 +704,8 @@ std::pair<NR::Coord, bool> SnapManager::freeSnapSkew(Inkscape::Snapper::PointTyp
 
 Inkscape::SnappedPoint SnapManager::findBestSnap(NR::Point const &p, SnappedConstraints &sc, bool constrained) const
 {
-    NR::Coord const guide_tol = guide.getSnapperTolerance();
-    NR::Coord grid_tol = 0;
-    
-    SnapManager::SnapperList const gs = getGridSnappers();
-    SnapperList::const_iterator i = gs.begin();
-    if (i != gs.end()) {        
-        grid_tol = (*i)->getSnapperTolerance(); // there's only a single tolerance, equal for all grids
-    }
-    
     // Store all snappoints
     std::list<Inkscape::SnappedPoint> sp_list;
-    // Most of these snapped points are already within the snapping range, because
-    // they have already been filtered by their respective snappers. In that case
-    // we can set the snapping range to NR_HUGE here. If however we're looking at
-    // intersections of e.g. a grid and guide line, then we'll have to determine 
-    // once again whether we're within snapping range. In this case we will set
-    // the snapping range to e.g. min(guide_sens, grid_tol)
     
     // search for the closest snapped point
     Inkscape::SnappedPoint closestPoint;
index ee9dbefac4e8810657eb17eaee4ea6c0d9eb1360..9702d011aa5d42f04866ab36d4a21d1f2583d79a 100644 (file)
@@ -94,7 +94,7 @@ public:
                                                     NR::scale const &s,
                                                     NR::Point const &o) const;
 
-    std::pair<NR::Coord, bool> freeSnapStretch(Inkscape::Snapper::PointType t,
+    std::pair<NR::Coord, bool> constrainedSnapStretch(Inkscape::Snapper::PointType t,
                                                std::vector<NR::Point> const &p,
                                                std::list<SPItem const *> const &it,
                                                NR::Coord const &s,