summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2017-12-01 22:13:57 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2017-12-01 22:13:57 +0000
commit5eb7d43e7f43c68191ef9ec616b9bd48c9b6c251 (patch)
tree4ed5cac1c941c8e3580bd1010f58d560515fa44b /src
parentMerge branch 'powerpencilII' of https://gitlab.com/inkscape/inkscape into pow... (diff)
downloadinkscape-5eb7d43e7f43c68191ef9ec616b9bd48c9b6c251.tar.gz
inkscape-5eb7d43e7f43c68191ef9ec616b9bd48c9b6c251.zip
Working on BSpline interpolator
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-interpolate_points.cpp3
-rw-r--r--src/live_effects/lpe-powerstroke-interpolators.h78
-rw-r--r--src/live_effects/lpe-powerstroke.cpp3
3 files changed, 80 insertions, 4 deletions
diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp
index 7d4c88dc1..c745921c2 100644
--- a/src/live_effects/lpe-interpolate_points.cpp
+++ b/src/live_effects/lpe-interpolate_points.cpp
@@ -25,7 +25,8 @@ static const Util::EnumData<unsigned> InterpolatorTypeData[] = {
{Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"},
{Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"},
{Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"},
- {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"}
+ {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"},
+ {Geom::Interpolate::INTERP_BSPLINE , N_("BSpline"), "BSpline"}
};
static const Util::EnumDataConverter<unsigned> InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData));
diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h
index e3ab37e27..0c1b60754 100644
--- a/src/live_effects/lpe-powerstroke-interpolators.h
+++ b/src/live_effects/lpe-powerstroke-interpolators.h
@@ -15,7 +15,7 @@
#include <2geom/path.h>
#include <2geom/bezier-utils.h>
#include <2geom/sbasis-to-bezier.h>
-
+#include <math.h>
#include "live_effects/spiro.h"
@@ -29,7 +29,8 @@ enum InterpolatorType {
INTERP_CUBICBEZIER_JOHAN,
INTERP_SPIRO,
INTERP_CUBICBEZIER_SMOOTH,
- INTERP_CENTRIPETAL_CATMULLROM
+ INTERP_CENTRIPETAL_CATMULLROM,
+ INTERP_BSPLINE
};
class Interpolator {
@@ -65,6 +66,77 @@ private:
Linear& operator=(const Linear&);
};
+class BSpline : public Interpolator {
+public:
+ BSpline() {};
+ virtual ~BSpline() {};
+
+ virtual Path interpolateToPath(std::vector<Point> const &points) const {
+ Path path;
+ path.start( points.at(0) );
+
+ Geom::Point point_a = points.at(0);
+ Geom::Point point_b = points.at(1);
+ Geom::Point point_c = points.at(2);
+ Geom::Point point_d = points.at(2);
+ if (points.size() > 3) {
+ point_d = points.at(3);
+ }
+ Geom::Point handle_1 = point_a;
+ Geom::Point handle_2 = point_b;
+ Geom::Point node_1 = point_a;
+ Geom::Point node_2 = point_b; //if the line is straight with next
+ Geom::Line line_ab(point_a, point_b);
+ Geom::Line line_bc(point_b, point_c);
+ Geom::Line line_cd(point_c, point_d);
+ Geom::Point handle_next(line_bc.pointAt(0.33334)); //if the line is straight with next
+ Geom::Point center_ab = line_ab.pointAt(0.5);
+ Geom::Point center_bc = line_bc.pointAt(0.5);
+ Geom::Point center_cd = line_cd.pointAt(0.5);
+ Geom::Line cross_line_hlp(line_ab.pointAt(0.66667), center_cd);
+ Geom::Point cross_center_hlp = cross_line_hlp.pointAt(0.5);
+ double angle_ab = line_ab.angle();
+ double angle_bc = line_bc.angle();
+ double angle_cd = line_cd.angle();
+ double cross_angle_hlp = cross_line_hlp.angle();
+ Geom::Line perpend_ab(center_ab, center_ab + Geom::Point::polar(angle_ab + Geom::rad_from_deg(90),1));
+ Geom::Line perpend_bc(center_bc, center_bc + Geom::Point::polar(angle_bc + Geom::rad_from_deg(90),1));
+ Geom::Line cross_1 (cross_center_hlp, cross_center_hlp + Geom::Point::polar(cross_angle_hlp + Geom::rad_from_deg(90),1));
+ std::vector<CurveIntersection> cross_hlp = perpend_ab.intersect(perpend_bc);
+ if(cross_hlp.size() > 0) {
+ cross_line_hlp.setPoints(cross_hlp[0], line_ab.pointAt(0.66667));
+ cross_angle_hlp = cross_line_hlp.angle();
+ Geom::Line cross_2(line_ab.pointAt(0.66667), line_ab.pointAt(0.66667) + Geom::Point::polar(cross_angle_hlp + Geom::rad_from_deg(90),1));
+ std::vector<CurveIntersection> cross = cross_1.intersect(cross_2);
+ if(cross.size() > 0) {
+ Geom::Line handle_line(cross[0],point_b);
+ handle_2 = handle_line.pointAt(2.0);
+ Geom::Line rootline(points.at(0),handle_2);
+ handle_1 = rootline.pointAt(0.5);
+ node_2 = rootline.pointAt(1.5);
+ handle_next = cross[0];
+ }
+ }
+ path.appendNew<CubicBezier>(handle_1, handle_2, points.at(1));
+ for (unsigned int i = 2 ; i < points.size(); ++i) {
+ Geom::Line rootline(node_2, handle_next);
+ handle_2 = rootline.pointAt(2.0);
+ node_2 = rootline.pointAt(3.0);
+ path.appendNew<CubicBezier>(handle_next, handle_2, points.at(i));
+ Geom::Line handleline(handle_2, points.at(i));
+ handle_next = handleline.pointAt(2.0);
+ }
+ Geom::Point last = points.at(points.size()-1);
+ Geom::LineSegment last_segment(handle_next,last);
+ path.appendNew<CubicBezier>(last_segment.initialPoint(), last_segment.pointAt(0.5), last);
+ return path;
+ };
+
+private:
+ BSpline(const BSpline&);
+ BSpline& operator=(const BSpline&);
+};
+
// this class is terrible
class CubicBezierFit : public Interpolator {
public:
@@ -302,6 +374,8 @@ Interpolator::create(InterpolatorType type) {
return new Geom::Interpolate::CubicBezierSmooth();
case INTERP_CENTRIPETAL_CATMULLROM:
return new Geom::Interpolate::CentripetalCatmullRomInterpolator();
+ case INTERP_BSPLINE:
+ return new Geom::Interpolate::BSpline();
default:
return new Geom::Interpolate::Linear();
}
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index 170995b90..47543107b 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -123,7 +123,8 @@ static const Util::EnumData<unsigned> InterpolatorTypeData[] = {
{Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"},
{Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"},
{Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"},
- {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"}
+ {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"},
+ {Geom::Interpolate::INTERP_BSPLINE , N_("BSpline"), "BSpline"}
};
static const Util::EnumDataConverter<unsigned> InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData));