summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/live_effects/lpe-interpolate.cpp54
-rw-r--r--src/live_effects/lpe-interpolate.h2
2 files changed, 49 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);
diff --git a/src/live_effects/lpe-interpolate.h b/src/live_effects/lpe-interpolate.h
index 84551786e..21c6f9ac8 100644
--- a/src/live_effects/lpe-interpolate.h
+++ b/src/live_effects/lpe-interpolate.h
@@ -36,6 +36,8 @@ class LPEInterpolate : public Effect {
ScalarParam number_of_steps;
BoolParam equidistant_spacing;
+ Geom::Piecewise<Geom::D2<Geom::SBasis> > calculate_trajectory(Geom::OptRect bounds_A, Geom::OptRect bounds_B);
+
LPEInterpolate(const LPEInterpolate &) = delete;
LPEInterpolate &operator=(const LPEInterpolate &) = delete;
};