summaryrefslogtreecommitdiffstats
path: root/src/live_effects/lpe-interpolate.cpp
diff options
context:
space:
mode:
authorTanja Bast <tanja.s.bast@gmail.com>2018-10-19 19:00:25 +0000
committerPatrick Storz <eduard.braun2@gmx.de>2018-10-24 20:55:51 +0000
commit6848264f334f03d19aba07121aa820805a4f4b4b (patch)
treef3c8db7542ccfec1cfc86d3de1bc5bc6ca4eb937 /src/live_effects/lpe-interpolate.cpp
parentApply clang format (diff)
downloadinkscape-6848264f334f03d19aba07121aa820805a4f4b4b.tar.gz
inkscape-6848264f334f03d19aba07121aa820805a4f4b4b.zip
Modify behavior of interpolation
Make sure that the original paths stay the start and end of the interpolation, even after modifying their shape. This is done by transforming the trajectory so that it starts at the bounding box center of the first path and ends at the bounding box center of the second path.
Diffstat (limited to 'src/live_effects/lpe-interpolate.cpp')
-rw-r--r--src/live_effects/lpe-interpolate.cpp54
1 files changed, 47 insertions, 7 deletions
diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp
index e8dc338f3..c3aff543a 100644
--- a/src/live_effects/lpe-interpolate.cpp
+++ b/src/live_effects/lpe-interpolate.cpp
@@ -65,11 +65,13 @@ Geom::PathVector LPEInterpolate::doEffect_path(Geom::PathVector const &path_in)
Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_B = path_in[1].toPwSb();
// Transform both paths to (0,0) midpoint, so they can easily be positioned along interpolate_path
- if (Geom::OptRect bounds = Geom::bounds_exact(pwd2_A)) {
- pwd2_A -= bounds->midpoint();
+ Geom::OptRect bounds_A = Geom::bounds_exact(pwd2_A);
+ if (bounds_A) {
+ pwd2_A -= bounds_A->midpoint();
}
- if (Geom::OptRect bounds = Geom::bounds_exact(pwd2_B)) {
- pwd2_B -= bounds->midpoint();
+ Geom::OptRect bounds_B = Geom::bounds_exact(pwd2_B);
+ if (bounds_B) {
+ pwd2_B -= bounds_B->midpoint();
}
// Make sure both paths have the same number of segments and cuts at the same locations
@@ -77,9 +79,7 @@ Geom::PathVector LPEInterpolate::doEffect_path(Geom::PathVector const &path_in)
Geom::Piecewise<Geom::D2<Geom::SBasis> > pA = Geom::partition(pwd2_A, pwd2_B.cuts);
Geom::Piecewise<Geom::D2<Geom::SBasis> > pB = Geom::partition(pwd2_B, pwd2_A.cuts);
- Geom::Piecewise<Geom::D2<Geom::SBasis> > trajectory = trajectory_path.get_pathvector()[0].toPwSb();
- if (equidistant_spacing)
- trajectory = Geom::arc_length_parametrization(trajectory);
+ auto trajectory = calculate_trajectory(bounds_A, bounds_B);
Geom::Interval trajectory_domain = trajectory.domain();
@@ -96,6 +96,46 @@ Geom::PathVector LPEInterpolate::doEffect_path(Geom::PathVector const &path_in)
return path_out;
}
+
+// returns the lpe parameter trajectory_path, transformed so that it starts at the
+// bounding box center of the first path and ends at the bounding box center of the
+// second path
+Geom::Piecewise<Geom::D2<Geom::SBasis> > LPEInterpolate::calculate_trajectory(Geom::OptRect bounds_A,
+ Geom::OptRect bounds_B)
+{
+ Geom::Piecewise<Geom::D2<Geom::SBasis> > trajectory = trajectory_path.get_pathvector()[0].toPwSb();
+
+ if (equidistant_spacing) {
+ trajectory = Geom::arc_length_parametrization(trajectory);
+ }
+
+ if (!bounds_A || !bounds_B) {
+ return trajectory;
+ }
+
+ auto trajectory_start = trajectory.firstValue();
+ auto trajectory_end = trajectory.lastValue();
+
+ auto midpoint_A = bounds_A->midpoint();
+ auto midpoint_B = bounds_B->midpoint();
+
+ Geom::Ray original(trajectory_start, trajectory_end);
+ Geom::Ray transformed(midpoint_A, midpoint_B);
+
+ double rotation = transformed.angle() - original.angle();
+ double scale = Geom::distance(midpoint_A, midpoint_B) / Geom::distance(trajectory_start, trajectory_end);
+
+ Geom::Affine transformation;
+
+ transformation *= Geom::Translate(-trajectory_start);
+ transformation *= Geom::Scale(scale, scale);
+ transformation *= Geom::Rotate(rotation);
+
+ transformation *= Geom::Translate(midpoint_A);
+
+ return trajectory * transformation;
+}
+
void LPEInterpolate::resetDefaults(SPItem const *item)
{
Effect::resetDefaults(item);