Code

Make LPE knotholder handles snap
authorcilix42 <cilix42@users.sourceforge.net>
Fri, 1 Aug 2008 17:39:57 +0000 (17:39 +0000)
committercilix42 <cilix42@users.sourceforge.net>
Fri, 1 Aug 2008 17:39:57 +0000 (17:39 +0000)
src/live_effects/lpe-angle_bisector.cpp
src/live_effects/lpe-copy_rotate.cpp
src/live_effects/lpe-parallel.cpp
src/live_effects/lpe-perp_bisector.cpp
src/live_effects/lpe-perp_bisector.h
src/live_effects/lpe-perspective_path.cpp
src/live_effects/lpe-tangent_to_curve.cpp

index 41c11fc5e3f5fe6a9016e852565d1ed2a75ba646..179d46a52b6668ed16c1e22813d684830e0be997 100644 (file)
@@ -106,7 +106,9 @@ KnotHolderEntityLeftEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*
 {
     LPEAngleBisector *lpe = get_effect(item);
     
-    double lambda = Geom::nearest_point(p.to_2geom(), lpe->ptA, lpe->dir);
+    NR::Point const s = snap_knot_position(p);
+
+    double lambda = Geom::nearest_point(s.to_2geom(), lpe->ptA, lpe->dir);
     lpe->length_left.param_set_value(-lambda);
 
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
@@ -117,7 +119,9 @@ KnotHolderEntityRightEnd::knot_set(NR::Point const &p, NR::Point const &/*origin
 {
     LPEAngleBisector *lpe = get_effect(item);
     
-    double lambda = Geom::nearest_point(p.to_2geom(), lpe->ptA, lpe->dir);
+    NR::Point const s = snap_knot_position(p);
+
+    double lambda = Geom::nearest_point(s.to_2geom(), lpe->ptA, lpe->dir);
     lpe->length_right.param_set_value(lambda);
 
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
index 142b6eb64039f0b0b3a01b477d54f6a70b91466f..9c475d46a3c075cbc6ad1b57ef34c399aaf5af89 100644 (file)
@@ -124,9 +124,11 @@ KnotHolderEntityAngle::knot_set(NR::Point const &p, NR::Point const &/*origin*/,
 {
     LPECopyRotate* lpe = get_effect(item);
 
+    NR::Point const s = snap_knot_position(p);
+
     // I first suspected the minus sign to be a bug in 2geom but it is
     // likely due to SVG's choice of coordinate system orientation (max)
-    lpe->angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, p.to_2geom() - lpe->origin)));
+    lpe->angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s.to_2geom() - lpe->origin)));
     if (state & GDK_SHIFT_MASK) {
         lpe->dist_angle_handle = L2(lpe->B - lpe->A);
     } else {
@@ -144,7 +146,8 @@ KnotHolderEntityAngle::knot_get()
     // I first suspected the minus sign to be a bug in 2geom but it is
     // likely due to SVG's choice of coordinate system orientation (max)
     Point d = lpe->dir * Rotate(-deg_to_rad(lpe->angle)) * lpe->dist_angle_handle;
-    return lpe->origin + d;
+
+    return snap_knot_position(lpe->origin + d);
 }
 
 } // namespace CR
index e0e15626300a9ef159f964f05e8e591049abb38f..e6d49b0b234f3ff9699312cdf5b255f15ae58707 100644 (file)
@@ -114,7 +114,9 @@ KnotHolderEntityLeftEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*
 
     LPEParallel *lpe = get_effect(item);
     
-    double lambda = L2(p - lpe->offset_pt) * sgn(dot(p.to_2geom() - lpe->offset_pt, lpe->dir));
+    NR::Point const s = snap_knot_position(p);
+
+    double lambda = L2(s - lpe->offset_pt) * sgn(dot(s.to_2geom() - lpe->offset_pt, lpe->dir));
     lpe->length_left.param_set_value(-lambda);
 
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
@@ -127,7 +129,9 @@ KnotHolderEntityRightEnd::knot_set(NR::Point const &p, NR::Point const &/*origin
 
     LPEParallel *lpe = get_effect(item);
     
-    double lambda = L2(p - lpe->offset_pt) * sgn(dot(p.to_2geom() - lpe->offset_pt, lpe->dir));
+    NR::Point const s = snap_knot_position(p);
+
+    double lambda = L2(s - lpe->offset_pt) * sgn(dot(s.to_2geom() - lpe->offset_pt, lpe->dir));
     lpe->length_right.param_set_value(lambda);
 
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
index c4146a1d9baff9a3aa80adb40a064ab27bb1fef6..f9aca2ada9ca493c47974471893a5eabdee1b9e8 100644 (file)
@@ -25,15 +25,18 @@ namespace Inkscape {
 namespace LivePathEffect {
 namespace PB {
 
-class KnotHolderEntityLeftEnd : public LPEKnotHolderEntity
-{
+class KnotHolderEntityEnd : public LPEKnotHolderEntity {
+public:
+    void bisector_end_set(NR::Point const &p, bool left = true);
+};
+
+class KnotHolderEntityLeftEnd : public KnotHolderEntityEnd {
 public:
     virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
     virtual NR::Point knot_get();
 };
 
-class KnotHolderEntityRightEnd : public LPEKnotHolderEntity
-{
+class KnotHolderEntityRightEnd : public KnotHolderEntityEnd {
 public:
     virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
     virtual NR::Point knot_get();
@@ -64,14 +67,14 @@ KnotHolderEntityRightEnd::knot_get() {
 }
 
 void
-bisector_end_set(SPItem *item, NR::Point const &p, bool left) {
+KnotHolderEntityEnd::bisector_end_set(NR::Point const &p, bool left) {
     Inkscape::LivePathEffect::LPEPerpBisector *lpe =
         dynamic_cast<Inkscape::LivePathEffect::LPEPerpBisector *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
+    if (!lpe) return;
 
-    if (!lpe)
-        return;
+    NR::Point const s = snap_knot_position(p);
 
-    double lambda = Geom::nearest_point(p.to_2geom(), lpe->M, lpe->perp_dir);
+    double lambda = Geom::nearest_point(s.to_2geom(), lpe->M, lpe->perp_dir);
     if (left) {
         lpe->C = lpe->M + lpe->perp_dir * lambda;
         lpe->length_left.param_set_value(lambda);
@@ -86,12 +89,12 @@ bisector_end_set(SPItem *item, NR::Point const &p, bool left) {
 
 void
 KnotHolderEntityLeftEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/) {
-    bisector_end_set(item, p);
+    bisector_end_set(p);
 }
 
 void
 KnotHolderEntityRightEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/) {
-    bisector_end_set(item, p, false);
+    bisector_end_set(p, false);
 }
 
 /**
index 19fb7d23e29ea04b1ae2f21d90781c68525735e1..1544eb4ffa1d03613da5df6d8c9b0680985b51be 100644 (file)
@@ -24,6 +24,7 @@ namespace LivePathEffect {
 
 namespace PB {
   // we need a separate namespace to avoid clashes with LPETangentToCurve
+  class KnotHolderEntityEnd;
   class KnotHolderEntityLeftEnd;
   class KnotHolderEntityRightEnd;
   void bisector_end_set(SPItem *item, NR::Point const &p, bool left);
@@ -42,6 +43,7 @@ public:
       doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
 
     /* the knotholder entity functions must be declared friends */
+    friend class PB::KnotHolderEntityEnd;
     friend class PB::KnotHolderEntityLeftEnd;
     friend class PB::KnotHolderEntityRightEnd;
     friend void PB::bisector_end_set(SPItem *item, NR::Point const &p, bool left = true);
index e3397a20eb27b556c54726227a74e2cafc663d53..9985542413953c11ab6c7b6bacbd6a21f7b7db68 100644 (file)
@@ -168,8 +168,10 @@ KnotHolderEntityOffset::knot_set(NR::Point const &p, NR::Point const &origin, gu
  
     LPEPerspectivePath* lpe = get_effect(item);
 
-    lpe->offsetx.param_set_value((p - origin)[NR::X]);
-    lpe->offsety.param_set_value(-(p - origin)[NR::Y]); // additional minus sign is due to coordinate system flipping
+    NR::Point const s = snap_knot_position(p);
+
+    lpe->offsetx.param_set_value((s - origin)[NR::X]);
+    lpe->offsety.param_set_value(-(s - origin)[NR::Y]); // additional minus sign is due to coordinate system flipping
 
     // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
index 33188382c5a5c33680f8f3a51d1803c049d6189c..0d21b38e093e26e443e01e7b96beb78fa43dd2ed 100644 (file)
@@ -113,9 +113,11 @@ get_effect(SPItem *item)
 void
 KnotHolderEntityAttachPt::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/)
 {
-     using namespace Geom;
-     LPETangentToCurve* lpe = get_effect(item);
+    using namespace Geom;
+
+    LPETangentToCurve* lpe = get_effect(item);
+
+    NR::Point const s = snap_knot_position(p);
 
     // FIXME: There must be a better way of converting the path's SPCurve* to pwd2.
     SPCurve *curve = sp_path_get_curve_for_edit (SP_PATH(item));
@@ -125,7 +127,7 @@ KnotHolderEntityAttachPt::knot_set(NR::Point const &p, NR::Point const &/*origin
         pwd2.concat(pathv[i].toPwSb());
     }
 
-    double t0 = nearest_point(p.to_2geom(), pwd2);
+    double t0 = nearest_point(s.to_2geom(), pwd2);
     lpe->t_attach.param_set_value(t0);
 
     // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
@@ -136,8 +138,10 @@ void
 KnotHolderEntityLeftEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/)
 {
     LPETangentToCurve *lpe = get_effect(item);
-    
-    double lambda = Geom::nearest_point(p.to_2geom(), lpe->ptA, lpe->derivA);
+
+    NR::Point const s = snap_knot_position(p);
+
+    double lambda = Geom::nearest_point(s.to_2geom(), lpe->ptA, lpe->derivA);
     lpe->length_left.param_set_value(-lambda);
 
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
@@ -148,7 +152,9 @@ KnotHolderEntityRightEnd::knot_set(NR::Point const &p, NR::Point const &/*origin
 {
     LPETangentToCurve *lpe = get_effect(item);
     
-    double lambda = Geom::nearest_point(p.to_2geom(), lpe->ptA, lpe->derivA);
+    NR::Point const s = snap_knot_position(p);
+
+    double lambda = Geom::nearest_point(s.to_2geom(), lpe->ptA, lpe->derivA);
     lpe->length_right.param_set_value(lambda);
 
     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);