diff options
| author | Jabier Arraiza <jabier.arraiza@marker.es> | 2017-12-01 22:13:57 +0000 |
|---|---|---|
| committer | Jabier Arraiza <jabier.arraiza@marker.es> | 2017-12-01 22:13:57 +0000 |
| commit | 5eb7d43e7f43c68191ef9ec616b9bd48c9b6c251 (patch) | |
| tree | 4ed5cac1c941c8e3580bd1010f58d560515fa44b /src | |
| parent | Merge branch 'powerpencilII' of https://gitlab.com/inkscape/inkscape into pow... (diff) | |
| download | inkscape-5eb7d43e7f43c68191ef9ec616b9bd48c9b6c251.tar.gz inkscape-5eb7d43e7f43c68191ef9ec616b9bd48c9b6c251.zip | |
Working on BSpline interpolator
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/lpe-interpolate_points.cpp | 3 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke-interpolators.h | 78 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke.cpp | 3 |
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)); |
