From 840daf70ff3f7c2c8e9cc0fae0037befcfa18edf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Nov 2014 20:14:04 +0100 Subject: fix a crash bug applyed on groups (bzr r13708.1.1) --- src/live_effects/effect.cpp | 3 ++- src/live_effects/lpe-copy_rotate.cpp | 11 +++++++---- src/live_effects/lpe-copy_rotate.h | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index e49a15dd0..0f4bdfaaa 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -112,7 +112,6 @@ const Util::EnumData LPETypeData[] = { {PATH_LENGTH, N_("Path length"), "path_length"}, {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"}, {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"}, - {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, {TEXT_LABEL, N_("Text label"), "text_label"}, @@ -153,6 +152,8 @@ const Util::EnumData LPETypeData[] = { {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, +/* 0.92 */ + {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index e466093d3..7e3f35f9d 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -76,11 +76,12 @@ LPECopyRotate::~LPECopyRotate() void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { - SPCurve const *curve = SP_SHAPE(lpeitem)->_curve; + using namespace Geom; - A = *(curve->first_point()); - B = *(curve->last_point()); + original_bbox(lpeitem); + Point A(boundingbox_X.min(), boundingbox_Y.middle()); + Point B(boundingbox_X.max(), boundingbox_Y.middle()); origin.param_setValue(A); dir = unit_vector(B - A); @@ -123,12 +124,14 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point) origin); path.appendNew(rot_pos); - + std::cout << rot_pos << "rot\n"; + std::cout << origin << "origin\n"; PathVector pathv; pathv.push_back(path); hp_vec.push_back(pathv); } + void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index ca7aa269c..c84889f57 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -16,6 +16,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/point.h" +#include "live_effects/lpegroupbbox.h" namespace Inkscape { namespace LivePathEffect { @@ -26,7 +27,7 @@ namespace CR { class KnotHolderEntityRotationAngle; } -class LPECopyRotate : public Effect { +class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); virtual ~LPECopyRotate(); -- cgit v1.2.3 From 015ec174f96c7e0aa96f4bab17a2895b62f4c24c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 16 Nov 2014 20:47:41 +0100 Subject: 360 auto degree calculation check (bzr r13708.1.2) --- src/live_effects/lpe-copy_rotate.cpp | 52 +++++++----------------------------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 10 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 7e3f35f9d..51787e292 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -38,12 +38,6 @@ public: virtual Geom::Point knot_get() const; }; -class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { -public: - KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; } // namespace CR @@ -52,6 +46,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), + copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), dist_angle_handle(100) { @@ -59,6 +54,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: + registerParameter( dynamic_cast(&copiesTo360) ); registerParameter( dynamic_cast(&starting_angle) ); registerParameter( dynamic_cast(&rotation_angle) ); registerParameter( dynamic_cast(&num_copies) ); @@ -82,6 +78,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) Point A(boundingbox_X.min(), boundingbox_Y.middle()); Point B(boundingbox_X.max(), boundingbox_Y.middle()); + Point C(boundingbox_X.middle(), boundingbox_Y.middle()); origin.param_setValue(A); dir = unit_vector(B - A); @@ -96,7 +93,11 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & 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) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle)) * dist_angle_handle; + double rotation_angle_end = rotation_angle; + if(copiesTo360){ + rotation_angle_end = 360.0/(double)num_copies; + } + rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; A = pwd2_in.firstValue(); B = pwd2_in.lastValue(); @@ -108,7 +109,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p for (int i = 0; i < num_copies; ++i) { // 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) - Rotate rot(-deg_to_rad(rotation_angle * i)); + Rotate rot(-deg_to_rad(rotation_angle_end * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } @@ -124,8 +125,6 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point) origin); path.appendNew(rot_pos); - std::cout << rot_pos << "rot\n"; - std::cout << origin << "origin\n"; PathVector pathv; pathv.push_back(path); hp_vec.push_back(pathv); @@ -139,12 +138,6 @@ void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *des _("Adjust the starting angle") ); knotholder->add(e); } - { - KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the rotation angle") ); - knotholder->add(e); - } }; namespace CR { @@ -171,26 +164,6 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } -void -KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) -{ - LPECopyRotate* lpe = dynamic_cast(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - // 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->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); - if (state & GDK_SHIFT_MASK) { - lpe->dist_angle_handle = L2(lpe->B - lpe->A); - } else { - lpe->dist_angle_handle = L2(p - lpe->origin); - } - - // 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); -} - Geom::Point KnotHolderEntityStartingAngle::knot_get() const { @@ -198,13 +171,6 @@ KnotHolderEntityStartingAngle::knot_get() const return lpe->start_pos; } -Geom::Point -KnotHolderEntityRotationAngle::knot_get() const -{ - LPECopyRotate const *lpe = dynamic_cast(_effect); - return lpe->rot_pos; -} - } // namespace CR diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index c84889f57..123c92cdd 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,6 @@ public: /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; - friend class CR::KnotHolderEntityRotationAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -48,6 +47,7 @@ private: ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; + BoolParam copiesTo360; PointParam origin; -- cgit v1.2.3 From 04abdf45fdd7a96b13c09a2a7aabbca95ba9ebb9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 2 Dec 2014 19:36:49 +0100 Subject: adding fussion improvements (bzr r13708.1.3) --- src/live_effects/lpe-copy_rotate.cpp | 122 +++++++++++++++++++++++++++++++++-- src/live_effects/lpe-copy_rotate.h | 1 + 2 files changed, 116 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 51787e292..e0855d452 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -47,6 +47,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), + fusionPaths(_("Fusioned paths"), _("Fusion paths"), "fusionPaths", &wr, this, true), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), dist_angle_handle(100) { @@ -55,6 +56,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast(&copiesTo360) ); + registerParameter( dynamic_cast(&fusionPaths) ); registerParameter( dynamic_cast(&starting_angle) ); registerParameter( dynamic_cast(&rotation_angle) ); registerParameter( dynamic_cast(&num_copies) ); @@ -106,14 +108,120 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - for (int i = 0; i < num_copies; ++i) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); + if(fusionPaths){ + // 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) + Rotate rot(-deg_to_rad(-starting_angle)); + Rotate rot2(-deg_to_rad(rotation_angle_end-starting_angle)); + //Affine t = pre * rot * Translate(origin); + Geom::Path mlineExpanded; + Geom::Point lineStart(0,0); + Geom::Point lineStart[Geom::X] = cos(rot) * 100000.0; + Geom::Point lineStart[Geom::Y] = sin(rot) * 100000.0; + Geom::Point lineEnd(0,0); + Geom::Point lineEnd[Geom::X] = cos(rot2) * 100000.0; + Geom::Point lineEnd[Geom::Y] = sin(rot2) * 100000.0; + mlineExpanded.start( lineStart); + mlineExpanded.appendNew( origin); + mlineExpanded.appendNew( lineEnd); + PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + std::vector temp_path; + double timeStart = 0.0; + int position = 0; + bool end_open = false; + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { + end_open = true; + } + } + Geom::Path original = (Geom::Path)(*path_it); + if(end_open && path_it->closed()){ + original.close(false); + original.appendNew( original.initialPoint() ); + original.close(true); + } + Geom::Crossings cs = crossings(original, mlineExpanded); + for(unsigned int i = 0; i < cs.size(); i++) { + double timeEnd = cs[i].ta; + Geom::Path portion = original.portion(timeStart, timeEnd); + Geom::Point middle = portion.pointAt((double)portion.size()/2.0); + position = pointSideOfLine(lineStart, lineEnd, middle); + Geom::line middleLine; + middleLine->setPoints(origin,middle); + if(middleLine.angle > rot && middleLine < rot2){ + Geom::Path kaleidoscope; + for (int j = 0; j < num_copies; ++j) { + // 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) + Rotate rot(-deg_to_rad(rotation_angle_end * j)); + Affine t = pre * rot * Translate(origin); + kaleidoscope = portion.reverse() * t); + kaleidoscope.setInitial(portion.finalPoint()); + portion.append(kaleidoscope); + } + if(i!=0){ + portion.setFinal(portion.initialPoint()); + portion.close(); + } + temp_path.push_back(portion); + } + portion.clear(); + timeStart = timeEnd; + } + Geom::line middleLine; + middleLine->setPoints(origin,original.finalPoint()); + if(cs.size()!=0 && middleLine.angle > rot && middleLine < rot2){ + Geom::Path portion = original.portion(timeStart, original.size()); + portion = portion.reverse(); + + Geom::Path kaleidoscope; + for (int i = 0; i < num_copies; ++i) { + // 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) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + kaleidoscope = portion.reverse() * t); + kaleidoscope.setInitial(portion.finalPoint()); + portion.append(kaleidoscope); + } + portion = portion.reverse(); + if (!original.closed()){ + temp_path.push_back(portion); + } else { + if(cs.size() >1 ){ + portion.setFinal(temp_path[0].initialPoint()); + portion.setInitial(temp_path[0].finalPoint()); + temp_path[0].append(portion); + } else { + temp_path.push_back(portion); + } + temp_path[0].close(); + } + portion.clear(); + } + if(cs.size() == 0 && position == 1){ + temp_path.push_back(original); + temp_path.push_back(original * m); + } + path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); + temp_path.clear(); + } + output = path_out.toPwSb(); + } else { + for (int i = 0; i < num_copies; ++i) { + // 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) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); + } + } } - return output; } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 123c92cdd..735de2300 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,6 +48,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; + BoolParam fusionPaths; PointParam origin; -- cgit v1.2.3 From 9a944b9317cbe94fb7c3c9f976da9ceffedeadf7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 5 Dec 2014 21:20:55 +0100 Subject: adding fussion improvements (bzr r13708.1.5) --- src/live_effects/lpe-copy_rotate.cpp | 153 ++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 553f273fe..7e3e65f23 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,11 +17,14 @@ #include "live_effects/lpe-copy_rotate.h" #include "sp-shape.h" #include "display/curve.h" - +#include <2geom/path.h> +#include <2geom/path-intersection.h> +#include <2geom/sbasis-to-bezier.h> #include <2geom/path.h> #include <2geom/transforms.h> #include <2geom/d2-sbasis.h> #include <2geom/angle.h> +#include #include "knot-holder-entity.h" #include "knotholder.h" @@ -110,60 +113,57 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(fusionPaths){ - // 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) - Rotate rot(-deg_to_rad(-starting_angle)); - Rotate rot2(-deg_to_rad(rotation_angle_end-starting_angle)); - //Affine t = pre * rot * Translate(origin); - Geom::Path mlineExpanded; - Geom::Point lineStart(0,0); - Geom::Point lineStart[Geom::X] = cos(rot) * 100000.0; - Geom::Point lineStart[Geom::Y] = sin(rot) * 100000.0; - Geom::Point lineEnd(0,0); - Geom::Point lineEnd[Geom::X] = cos(rot2) * 100000.0; - Geom::Point lineEnd[Geom::Y] = sin(rot2) * 100000.0; - mlineExpanded.start( lineStart); - mlineExpanded.appendNew( origin); - mlineExpanded.appendNew( lineEnd); - PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); - for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - std::vector temp_path; - double timeStart = 0.0; - int position = 0; - bool end_open = false; - if (path_it->closed()) { - const Geom::Curve &closingline = path_it->back_closed(); - if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { - end_open = true; - } - } - Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it->closed()){ - original.close(false); - original.appendNew( original.initialPoint() ); - original.close(true); + // 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) + std::vector path_out; + PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in * t, 0.1), 0.001); + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + bool end_open = false; + std::vector temp_path; + double timeStart = 0.0; + int position = 0; + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { + end_open = true; } - Geom::Crossings cs = crossings(original, mlineExpanded); + } + Geom::Path original = (Geom::Path)(*path_it); + if(end_open && path_it2->closed()){ + original.close(false); + original.appendNew( original.initialPoint() ); + original.close(true); + } + //for (int i = 0; i < num_copies; ++i) { + double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); + Rotate rot(rotAngle * i); + Affine t = pre * rot * Translate(origin); + Geom::Point lineEnd(0,0); + lineEnd[Geom::X] = cos((rotAngle * i) - rotAngle/2.0) * 100000.0; + lineEnd[Geom::Y] = sin((rotAngle * i) - rotAngle/2.0) * 100000.0; + Geom::Path kline; + kline.start((Geom::Point)origin); + kline.appendNew(lineEnd); + Geom::Crossings cs = crossings(original, kline); for(unsigned int i = 0; i < cs.size(); i++) { double timeEnd = cs[i].ta; Geom::Path portion = original.portion(timeStart, timeEnd); Geom::Point middle = portion.pointAt((double)portion.size()/2.0); - position = pointSideOfLine(lineStart, lineEnd, middle); - Geom::line middleLine; - middleLine->setPoints(origin,middle); - if(middleLine.angle > rot && middleLine < rot2){ - Geom::Path kaleidoscope; - for (int j = 0; j < num_copies; ++j) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * j)); + position = pointSideOfLine((Geom::Point)origin, lineEnd, middle); + if(reverseFusion){ + position *= -1; + } + if(position == 1){ + for (int i = 0; i < num_copies; ++i) { + double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); + Rotate rot(rotAngle * i); Affine t = pre * rot * Translate(origin); - kaleidoscope = portion.reverse() * t); - kaleidoscope.setInitial(portion.finalPoint()); - portion.append(kaleidoscope); + Geom::Path kaleidoscope = portion * t; + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); } if(i!=0){ portion.setFinal(portion.initialPoint()); @@ -174,23 +174,20 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p portion.clear(); timeStart = timeEnd; } - Geom::line middleLine; - middleLine->setPoints(origin,original.finalPoint()); - if(cs.size()!=0 && middleLine.angle > rot && middleLine < rot2){ - Geom::Path portion = original.portion(timeStart, original.size()); - portion = portion.reverse(); - - Geom::Path kaleidoscope; + position = pointSideOfLine((Geom::Point)origin, lineEnd, original.finalPoint()); + if(reverseFusion){ + position *= -1; + } + if(cs.size()!=0 && position == 1){ for (int i = 0; i < num_copies; ++i) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); + double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); + Rotate rot(rotAngle * i); Affine t = pre * rot * Translate(origin); - kaleidoscope = portion.reverse() * t); + Geom::Path portion = original.portion(timeStart, original.size()); + Geom::Path kaleidoscope = portion * t; kaleidoscope.setInitial(portion.finalPoint()); portion.append(kaleidoscope); } - portion = portion.reverse(); if (!original.closed()){ temp_path.push_back(portion); } else { @@ -205,22 +202,28 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } portion.clear(); } - if(cs.size() == 0 && position == 1){ - temp_path.push_back(original); - temp_path.push_back(original * m); - } - path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); - temp_path.clear(); } - output = path_out.toPwSb(); - } else { - for (int i = 0; i < num_copies; ++i) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); + if(cs.size() == 0 && position == 1){ + for (int i = 0; i < num_copies; ++i) { + // 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) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + temp_path.push_back((Geom::Path)(*path_it) * t); + } } + path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); + temp_path.clear(); + if(path_out.size() > 0){ + output.concat(paths_to_pw(path_out)); + } + } else { + for (int i = 0; i < num_copies; ++i) { + // 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) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); } } return output; -- cgit v1.2.3 From 1d1ec291d89846be2dbd5ce1466b58baeb743994 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 17 Jan 2015 18:14:04 +0100 Subject: adding Kaleidoscope (bzr r13708.1.8) --- src/live_effects/lpe-copy_rotate.cpp | 164 +++++++++++++++-------------------- src/live_effects/lpe-copy_rotate.h | 6 +- 2 files changed, 73 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 7e3e65f23..1eb1f22f2 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -50,7 +50,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), - fusionPaths(_("Fusioned paths"), _("Fusion paths"), "fusionPaths", &wr, this, true), + kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, true), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), dist_angle_handle(100) @@ -60,7 +60,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast(&copiesTo360) ); - registerParameter( dynamic_cast(&fusionPaths) ); + registerParameter( dynamic_cast(&kaleidoscope) ); registerParameter( dynamic_cast(&starting_angle) ); registerParameter( dynamic_cast(&rotation_angle) ); registerParameter( dynamic_cast(&num_copies) ); @@ -91,6 +91,58 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) dist_angle_handle = L2(B - A); } +void +LPECopyRotate::split(std::vector &path_in,Geom:Path divider,bool start){ + double timeStart = 0.0; + for (Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + Geom::Path original = path_it; + std::vector temp_path; + Geom::Crossings cs = crossings(original, divider); + for(unsigned int i = 0; i < cs.size(); i++) { + double timeEnd = cs[i].ta; + Geom::Path portion = original.portion(timeStart, timeEnd); + Geom::Point middle = portion.pointAt((double)portion.size()/2.0); + position = pointSideOfLine(divider.initialPoint(), divider.finalPoint(), middle); + if(position == 1 || (!start && position== -1)){ + temp_path.push_back(portion); + } + portion.clear(); + timeStart = timeEnd; + } + position = pointSideOfLine(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); + if(cs.size()!=0 && (position == 1 || (!start && position== -1))){ + Geom::Path portion = original.portion(timeStart, original.size()); + temp_path.push_back(portion); + portion.clear(); + } + } + path_in = temp_path; +} + +void +LPECopyRotate::setKaleidoscope(std::vector &path_in){ + Geom::Point lineStart(0,0); + lineStart[Geom::X] = cos(starting_angle) * 100000.0; + lineStart[Geom::Y] = sin(starting_angle) * 100000.0; + Geom::Point lineEnd(0,0); + lineEnd[Geom::X] = cos(starting_angle + rotAngle) * 100000.0; + lineEnd[Geom::Y] = sin(starting_angle + rotAngle) * 100000.0; + Geom::Path klineA; + klineA.start(origin); + klineA.appendNew(lineStart); + path_in = split(path_in,klineA,true); + Geom::Path klineB; + klineB.start(origin); + klineB.appendNew(lineEnd); + path_in = split(path_in,klineB,false); + for (int i = 0; i < num_copies; ++i) { + + } +} + Geom::Piecewise > LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -100,7 +152,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; double rotation_angle_end = rotation_angle; - if(copiesTo360){ + if(copiesTo360 || kaleidoscope){ rotation_angle_end = 360.0/(double)num_copies; } rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; @@ -112,19 +164,14 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - if(fusionPaths){ - // 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) + if(kaleidoscope){ std::vector path_out; + std::vector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in * t, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()){ continue; } - bool end_open = false; - std::vector temp_path; - double timeStart = 0.0; - int position = 0; if (path_it->closed()) { const Geom::Curve &closingline = path_it->back_closed(); if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { @@ -137,94 +184,19 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.appendNew( original.initialPoint() ); original.close(true); } - //for (int i = 0; i < num_copies; ++i) { - double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); - Rotate rot(rotAngle * i); - Affine t = pre * rot * Translate(origin); - Geom::Point lineEnd(0,0); - lineEnd[Geom::X] = cos((rotAngle * i) - rotAngle/2.0) * 100000.0; - lineEnd[Geom::Y] = sin((rotAngle * i) - rotAngle/2.0) * 100000.0; - Geom::Path kline; - kline.start((Geom::Point)origin); - kline.appendNew(lineEnd); - Geom::Crossings cs = crossings(original, kline); - for(unsigned int i = 0; i < cs.size(); i++) { - double timeEnd = cs[i].ta; - Geom::Path portion = original.portion(timeStart, timeEnd); - Geom::Point middle = portion.pointAt((double)portion.size()/2.0); - position = pointSideOfLine((Geom::Point)origin, lineEnd, middle); - if(reverseFusion){ - position *= -1; - } - if(position == 1){ - for (int i = 0; i < num_copies; ++i) { - double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); - Rotate rot(rotAngle * i); - Affine t = pre * rot * Translate(origin); - Geom::Path kaleidoscope = portion * t; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - } - if(i!=0){ - portion.setFinal(portion.initialPoint()); - portion.close(); - } - temp_path.push_back(portion); - } - portion.clear(); - timeStart = timeEnd; - } - position = pointSideOfLine((Geom::Point)origin, lineEnd, original.finalPoint()); - if(reverseFusion){ - position *= -1; - } - if(cs.size()!=0 && position == 1){ - for (int i = 0; i < num_copies; ++i) { - double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); - Rotate rot(rotAngle * i); - Affine t = pre * rot * Translate(origin); - Geom::Path portion = original.portion(timeStart, original.size()); - Geom::Path kaleidoscope = portion * t; - kaleidoscope.setInitial(portion.finalPoint()); - portion.append(kaleidoscope); - } - if (!original.closed()){ - temp_path.push_back(portion); - } else { - if(cs.size() >1 ){ - portion.setFinal(temp_path[0].initialPoint()); - portion.setInitial(temp_path[0].finalPoint()); - temp_path[0].append(portion); - } else { - temp_path.push_back(portion); - } - temp_path[0].close(); - } - portion.clear(); - } - } - if(cs.size() == 0 && position == 1){ - for (int i = 0; i < num_copies; ++i) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - temp_path.push_back((Geom::Path)(*path_it) * t); - } - } - path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); - temp_path.clear(); - if(path_out.size() > 0){ - output.concat(paths_to_pw(path_out)); - } + tmp_path.push_back(original); + setKaleidoscope(tmp_path); + path_out.push_back(tmp_path); + tmp_path.clear(); + } + output = path_out.toPwSb(); } else { for (int i = 0; i < num_copies; ++i) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); - } + // 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) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); } return output; } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 735de2300..d0ad2d6ec 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -36,6 +36,10 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + virtual void kaleidoscope(std::vector &path_in); + + virtual void split(std::vector &path_in,Geom:Path divider,bool start); + /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -48,7 +52,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; - BoolParam fusionPaths; + BoolParam setKaleidoscope; PointParam origin; -- cgit v1.2.3 From 8deff8fb8acbbfa8c56db9d6e34b93523872a25b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 21 Jan 2015 00:13:00 +0100 Subject: fixing knots (bzr r13708.1.10) --- src/live_effects/lpe-copy_rotate.cpp | 236 ++++++++++++++++++++++++----------- src/live_effects/lpe-copy_rotate.h | 19 ++- 2 files changed, 179 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 1eb1f22f2..20e08a7d8 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -24,7 +24,8 @@ #include <2geom/transforms.h> #include <2geom/d2-sbasis.h> #include <2geom/angle.h> -#include +#include <2geom/line.h> +#include #include "knot-holder-entity.h" #include "knotholder.h" @@ -41,30 +42,35 @@ public: virtual Geom::Point knot_get() const; }; +class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { +public: + KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; } // namespace CR LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), + origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), - kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, true), - - origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), - dist_angle_handle(100) + kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, false), + dist_angle_handle(100.0) { show_orig_path = true; _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter( dynamic_cast(&copiesTo360) ); - registerParameter( dynamic_cast(&kaleidoscope) ); - registerParameter( dynamic_cast(&starting_angle) ); - registerParameter( dynamic_cast(&rotation_angle) ); - registerParameter( dynamic_cast(&num_copies) ); - registerParameter( dynamic_cast(&origin) ); + registerParameter(&copiesTo360); + registerParameter(&kaleidoscope); + registerParameter(&starting_angle); + registerParameter(&rotation_angle); + registerParameter(&num_copies); + registerParameter(&origin); num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); @@ -79,65 +85,117 @@ void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); - Point A(boundingbox_X.min(), boundingbox_Y.middle()); - Point B(boundingbox_X.max(), boundingbox_Y.middle()); - Point C(boundingbox_X.middle(), boundingbox_Y.middle()); - origin.param_setValue(A); + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); + origin.param_set_value(A); + dist_angle_handle = L2(B - A); + dir = unit_vector(B - A); +} + +void +LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) +{ + using namespace Geom; + original_bbox(lpeitem); + if( kaleidoscope || copiesTo360 ){ + rotation_angle.param_set_value(360.0/(double)num_copies); + } + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); dir = unit_vector(B - A); - dist_angle_handle = L2(B - A); + // 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) + start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; + rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; + if( kaleidoscope || copiesTo360 ){ + rot_pos = origin; + } + SPLPEItem * item = const_cast(lpeitem); + item->apply_to_clippath(item); + item->apply_to_mask(item); +} + +bool +LPECopyRotate::side(Geom::Point p1, Geom::Point p2, Geom::Point p) +{ + using Geom::X; + using Geom::Y; + return (p2[Y] - p1[Y])*(p[X] - p1[X]) + (-p2[X] + p1[X])*(p[Y] - p1[Y]) >= 0; +} + +bool +LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Geom::Point p3) +{ + using Geom::X; + using Geom::Y; + double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); + double t1 = (p[X]*(p3[Y] - p1[Y]) + p[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator; + double t2 = (p[X]*(p2[Y] - p1[Y]) + p[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator; + double s = t1 + t2; + + return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; } void -LPECopyRotate::split(std::vector &path_in,Geom:Path divider,bool start){ +LPECopyRotate::split(std::vector &path_in,Geom::Path divider){ double timeStart = 0.0; + std::vector temp_path; for (Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { if (path_it->empty()){ continue; } - Geom::Path original = path_it; - std::vector temp_path; + Geom::Path original = *path_it; + int position = 0; Geom::Crossings cs = crossings(original, divider); for(unsigned int i = 0; i < cs.size(); i++) { double timeEnd = cs[i].ta; Geom::Path portion = original.portion(timeStart, timeEnd); - Geom::Point middle = portion.pointAt((double)portion.size()/2.0); - position = pointSideOfLine(divider.initialPoint(), divider.finalPoint(), middle); - if(position == 1 || (!start && position== -1)){ + Geom::Point sideChecker = portion.pointAt(portion.size()-0.001); + position = side(divider.initialPoint(), divider.finalPoint(), sideChecker); + if(num_copies > 2){ + position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); + } + std::cout << position << "\n"; + if(position == true){ temp_path.push_back(portion); } portion.clear(); timeStart = timeEnd; } - position = pointSideOfLine(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); - if(cs.size()!=0 && (position == 1 || (!start && position== -1))){ + position = side(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); + if(num_copies > 2){ + position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); + } + if(cs.size()!=0 && position == true){ Geom::Path portion = original.portion(timeStart, original.size()); - temp_path.push_back(portion); + if (!original.closed()){ + temp_path.push_back(portion); + } else { + if(cs.size() > 1 && temp_path[0].size() > 0 ){ + portion.setFinal(temp_path[0].initialPoint()); + portion.append(temp_path[0]); + temp_path[0]=portion; + } else { + temp_path.push_back(portion); + } + //temp_path[0].close(); + } portion.clear(); } + if(cs.size()==0){ + temp_path.push_back(original); + } } path_in = temp_path; } void LPECopyRotate::setKaleidoscope(std::vector &path_in){ - Geom::Point lineStart(0,0); - lineStart[Geom::X] = cos(starting_angle) * 100000.0; - lineStart[Geom::Y] = sin(starting_angle) * 100000.0; - Geom::Point lineEnd(0,0); - lineEnd[Geom::X] = cos(starting_angle + rotAngle) * 100000.0; - lineEnd[Geom::Y] = sin(starting_angle + rotAngle) * 100000.0; - Geom::Path klineA; - klineA.start(origin); - klineA.appendNew(lineStart); - path_in = split(path_in,klineA,true); - Geom::Path klineB; - klineB.start(origin); - klineB.appendNew(lineEnd); - path_in = split(path_in,klineB,false); + + split(path_in,hp); for (int i = 0; i < num_copies; ++i) { } @@ -148,30 +206,21 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - // 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) - start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - double rotation_angle_end = rotation_angle; - if(copiesTo360 || kaleidoscope){ - rotation_angle_end = 360.0/(double)num_copies; + if(num_copies == 1){ + return pwd2_in; } - rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; - - A = pwd2_in.firstValue(); - B = pwd2_in.lastValue(); - dir = unit_vector(B - A); Piecewise > output; - Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope){ std::vector path_out; std::vector tmp_path; - PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in * t, 0.1), 0.001); + PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()){ continue; } + bool end_open = false; if (path_it->closed()) { const Geom::Curve &closingline = path_it->back_closed(); if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { @@ -179,24 +228,25 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it2->closed()){ + if(end_open && path_it->closed()){ original.close(false); original.appendNew( original.initialPoint() ); original.close(true); } tmp_path.push_back(original); setKaleidoscope(tmp_path); - path_out.push_back(tmp_path); + path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - output = path_out.toPwSb(); + if(path_out.size()>0){ + output = paths_to_pw(path_out); + } } else { for (int i = 0; i < num_copies; ++i) { - // 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) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); + Rotate rot(-deg_to_rad(rotation_angle * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); + } } return output; } @@ -205,21 +255,40 @@ void LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { using namespace Geom; - - Path path(start_pos); - path.appendNew((Geom::Point) origin); - path.appendNew(rot_pos); - PathVector pathv; - pathv.push_back(path); + hp_vec.clear(); + double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + double sizeDivider = Geom::distance(origin,bbox) + diagonal + 20; + Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; + Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; + hp.start(lineStart); + hp.appendNew((Geom::Point)origin); + hp.appendNew(lineEnd); + Geom::PathVector pathv; + pathv.push_back(hp); hp_vec.push_back(pathv); } +void +LPECopyRotate::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + original_bbox(SP_LPE_ITEM(item)); + hp.clear(); +} -void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { +void +LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the starting angle") ); + _("Adjust the starting angle")); + knotholder->add(e); + } + { + KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Adjust the rotation angle")); knotholder->add(e); } }; @@ -248,6 +317,26 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } +void +KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + LPECopyRotate* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + // 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->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); + if (state & GDK_SHIFT_MASK) { + lpe->dist_angle_handle = L2(lpe->B - lpe->A); + } else { + lpe->dist_angle_handle = L2(p - lpe->origin); + } + + // 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); +} + Geom::Point KnotHolderEntityStartingAngle::knot_get() const { @@ -255,9 +344,14 @@ KnotHolderEntityStartingAngle::knot_get() const return lpe->start_pos; } -} // namespace CR - +Geom::Point +KnotHolderEntityRotationAngle::knot_get() const +{ + LPECopyRotate const *lpe = dynamic_cast(_effect); + return lpe->rot_pos; +} +} // namespace CR /* ######################## */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index d0ad2d6ec..209118925 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -36,29 +36,38 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); - virtual void kaleidoscope(std::vector &path_in); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void split(std::vector &path_in,Geom:Path divider,bool start); + virtual void setKaleidoscope(std::vector &path_in); + + virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); + + virtual bool side(Geom::Point p1, Geom::Point p2, Geom::Point p); + + virtual void split(std::vector &path_in,Geom::Path divider); + + virtual void resetDefaults(SPItem const* item); /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; + friend class CR::KnotHolderEntityRotationAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: + PointParam origin; ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; - BoolParam setKaleidoscope; - - PointParam origin; + BoolParam kaleidoscope; Geom::Point A; Geom::Point B; Geom::Point dir; + Geom::Path hp; Geom::Point start_pos; Geom::Point rot_pos; -- cgit v1.2.3 From 41368054b3da78b13a049d0020d0eeb4d8a6798d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 10:58:06 +0100 Subject: Added the remove for outer staff to kaleidoscope (bzr r13708.1.12) --- src/live_effects/lpe-copy_rotate.cpp | 131 ++++++++++++++++++----------------- src/live_effects/lpe-copy_rotate.h | 5 +- 2 files changed, 71 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 20e08a7d8..1c01e2aaf 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -89,7 +89,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); - origin.param_set_value(A); + origin.param_setValue(A); dist_angle_handle = L2(B - A); dir = unit_vector(B - A); } @@ -102,7 +102,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) original_bbox(lpeitem); if( kaleidoscope || copiesTo360 ){ rotation_angle.param_set_value(360.0/(double)num_copies); - } + } + if(dist_angle_handle < 1.0){ + dist_angle_handle = 1.0; + } A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); dir = unit_vector(B - A); @@ -118,17 +121,18 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) item->apply_to_mask(item); } -bool -LPECopyRotate::side(Geom::Point p1, Geom::Point p2, Geom::Point p) +int +LPECopyRotate::pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X) { - using Geom::X; - using Geom::Y; - return (p2[Y] - p1[Y])*(p[X] - p1[X]) + (-p2[X] + p1[X])*(p[Y] - p1[Y]) >= 0; + //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line + double pos = (B[Geom::X]-A[Geom::X])*(X[Geom::Y]-A[Geom::Y]) - (B[Geom::Y]-A[Geom::Y])*(X[Geom::X]-A[Geom::X]); + return (pos < 0) ? -1 : (pos > 0); } bool LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Geom::Point p3) { + //http://totologic.blogspot.com.es/2014/01/accurate-point-in-triangle-test.html using Geom::X; using Geom::Y; double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); @@ -140,62 +144,60 @@ LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Ge } void -LPECopyRotate::split(std::vector &path_in,Geom::Path divider){ +LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ + std::vector tmp_path; double timeStart = 0.0; - std::vector temp_path; - for (Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - Geom::Path original = *path_it; - int position = 0; - Geom::Crossings cs = crossings(original, divider); - for(unsigned int i = 0; i < cs.size(); i++) { - double timeEnd = cs[i].ta; - Geom::Path portion = original.portion(timeStart, timeEnd); - Geom::Point sideChecker = portion.pointAt(portion.size()-0.001); - position = side(divider.initialPoint(), divider.finalPoint(), sideChecker); - if(num_copies > 2){ - position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); - } - std::cout << position << "\n"; - if(position == true){ - temp_path.push_back(portion); - } - portion.clear(); - timeStart = timeEnd; - } - position = side(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); + Geom::Path original = path_on[0]; + int position = 0; + Geom::Crossings cs = crossings(original,divider); + std::vector crossed; + for(unsigned int i = 0; i < cs.size(); i++) { + crossed.push_back(cs[i].ta); + } + std::sort (crossed.begin(), crossed.end()); + for(unsigned int i = 0; i < crossed.size(); i++) { + double timeEnd = crossed[i]; + Geom::Path portionOriginal = original.portion(timeStart,timeEnd); + Geom::Point sideChecker = portionOriginal.pointAt(0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), sideChecker); if(num_copies > 2){ - position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); + position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(cs.size()!=0 && position == true){ - Geom::Path portion = original.portion(timeStart, original.size()); - if (!original.closed()){ - temp_path.push_back(portion); + if(position == 1){ + tmp_path.push_back(portionOriginal); + } + portionOriginal.clear(); + timeStart = timeEnd; + } + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); + if(num_copies > 2){ + position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + } + if(cs.size() > 0 && position == 1){ + Geom::Path portionOriginal = original.portion(timeStart, original.size()); + if (!original.closed()){ + tmp_path.push_back(portionOriginal); + } else { + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ){ + portionOriginal.setFinal(tmp_path[0].initialPoint()); + portionOriginal.append(tmp_path[0]); + tmp_path[0] = portionOriginal; } else { - if(cs.size() > 1 && temp_path[0].size() > 0 ){ - portion.setFinal(temp_path[0].initialPoint()); - portion.append(temp_path[0]); - temp_path[0]=portion; - } else { - temp_path.push_back(portion); - } - //temp_path[0].close(); + tmp_path.push_back(portionOriginal); } - portion.clear(); - } - if(cs.size()==0){ - temp_path.push_back(original); + //temp_path[0].close(); } + portionOriginal.clear(); + } + if(cs.size()==0 && position == 1){ + tmp_path.push_back(original); } - path_in = temp_path; + path_on = tmp_path; } void -LPECopyRotate::setKaleidoscope(std::vector &path_in){ - - split(path_in,hp); +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ + split(path_on,divider); for (int i = 0; i < num_copies; ++i) { } @@ -210,6 +212,16 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p return pwd2_in; } + double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + double sizeDivider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; + Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; + //Note:: beter way to do this + //Whith AppendNew have problems whith the crossing order + Geom::Path divider = Geom::Path(lineStart); + divider.appendNew((Geom::Point)origin); + divider.appendNew(lineEnd); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope){ @@ -234,7 +246,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path); + setKaleidoscope(tmp_path,divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } @@ -256,14 +268,10 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point)origin); - hp.appendNew(lineEnd); + hp.appendNew(origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle); Geom::PathVector pathv; pathv.push_back(hp); hp_vec.push_back(pathv); @@ -274,7 +282,6 @@ LPECopyRotate::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); original_bbox(SP_LPE_ITEM(item)); - hp.clear(); } void diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 209118925..78e3b1950 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,11 +38,11 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); - virtual bool side(Geom::Point p1, Geom::Point p2, Geom::Point p); + virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); virtual void split(std::vector &path_in,Geom::Path divider); @@ -67,7 +67,6 @@ private: Geom::Point A; Geom::Point B; Geom::Point dir; - Geom::Path hp; Geom::Point start_pos; Geom::Point rot_pos; -- cgit v1.2.3 From d1a09f4fd642b79542401c6e4eb83e79369c0f9b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 11:08:58 +0100 Subject: added missing header from a merge (bzr r13708.1.14) --- src/live_effects/lpe-copy_rotate.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 35b5c1eb2..d1022dbc2 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -13,7 +13,8 @@ #include #include - +#include <2geom/path-intersection.h> +#include <2geom/sbasis-to-bezier.h> #include "live_effects/lpe-copy_rotate.h" #include <2geom/path.h> #include <2geom/transforms.h> @@ -191,8 +192,13 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ void LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ split(path_on,divider); - for (int i = 0; i < num_copies; ++i) { - + for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + for (int i = 0; i < num_copies; ++i) { + + } } } -- cgit v1.2.3 From 8d82767ca9ff65622eac487afd6aeba78713add5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 12:40:19 +0100 Subject: reverting to non wroken branch (bzr r13708.1.15) --- src/live_effects/lpe-copy_rotate.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index d1022dbc2..3103d8293 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -192,12 +192,17 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ void LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ split(path_on,divider); + Geom::Affine pre = Geom::Translate(-origin) * Geom::Rotate(-Geom::deg_to_rad(starting_angle)); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { if (path_it->empty()){ continue; } for (int i = 0; i < num_copies; ++i) { - + Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * i)); + Geom::Affine t = pre * rot * Geom::Translate(origin); + Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Geom::Path append = *path_it * sca * t; + path_on.push_back(append); } } } -- cgit v1.2.3 From 2218eee67d0032e118cb711b7c612f7b580a6294 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 18:11:22 +0100 Subject: Kaleidoscope check (bzr r13708.1.16) --- src/live_effects/lpe-copy_rotate.cpp | 70 +++++++++++++++++++++++++++++------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 59 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 3103d8293..6c16c6194 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -94,9 +94,18 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if( kaleidoscope || copiesTo360 ){ + if(kaleidoscope || copiesTo360 ){ rotation_angle.param_set_value(360.0/(double)num_copies); } + if(kaleidoscope){ + num_copies.param_set_increments(2,2); + if((int)num_copies%2 !=0){ + num_copies.param_set_value(num_copies+1); + } + } else { + num_copies.param_set_increments(1,1); + } + if(dist_angle_handle < 1.0){ dist_angle_handle = 1.0; } @@ -190,21 +199,58 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider){ split(path_on,divider); - Geom::Affine pre = Geom::Translate(-origin) * Geom::Rotate(-Geom::deg_to_rad(starting_angle)); + std::vector tmp_path; + Geom::Affine pre = Geom::Translate(-origin); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - for (int i = 0; i < num_copies; ++i) { - Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * i)); - Geom::Affine t = pre * rot * Geom::Translate(origin); + Geom::Path original = *path_it; + if (path_it->empty()){ + continue; + } + std::vector tmp_path2; + Geom::Path appendPath = original; + for (int i = 0; i < num_copies; ++i) { + Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); + Geom::Affine m = pre * rot * Geom::Translate(origin); + if(i%2 != 0){ + Geom::Point A = (Geom::Point)origin; + Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * sizeDivider; + Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); + double hyp = Geom::distance(A, B); + double c = (B[0] - A[0]) / hyp; // cos(alpha) + double s = (B[1] - A[1]) / hyp; // sin(alpha) + + Geom::Affine m2(c, -s, s, c, 0.0, 0.0); Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); - Geom::Path append = *path_it * sca * t; - path_on.push_back(append); + + Geom::Affine tmpM = m1.inverse() * m2; + m = tmpM; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + } else { + appendPath = original; } + appendPath *= m; + if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint())){ + tmp_path2[tmp_path2.size()-1].append(appendPath.reverse()); + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())){ + tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); + tmp_path2[tmp_path2.size()-1].append(appendPath); + tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); + } else { + tmp_path2.push_back(appendPath); + } + if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())){ + tmp_path2[tmp_path2.size()-1].close(); + } + } + tmp_path.insert(tmp_path.end(), tmp_path2.begin(), tmp_path2.end()); + tmp_path2.clear(); } + path_on = tmp_path; + tmp_path.clear(); } Geom::Piecewise > @@ -250,7 +296,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider); + setKaleidoscope(tmp_path,divider,sizeDivider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 78e3b1950..bdbc61d07 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); -- cgit v1.2.3 From b21958f914e82435e935bb732b64cdf3f685c3f1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 28 Mar 2015 14:57:06 +0100 Subject: adding rotation transform (bzr r13708.1.20) --- src/live_effects/lpe-copy_rotate.cpp | 18 ++++++++++++++++++ src/live_effects/lpe-copy_rotate.h | 2 ++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 63d6b8bfa..5474bfb70 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -89,6 +89,24 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) dir = unit_vector(B - A); } +void +LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) +{ + if(postmul->isRotation()){ + Geom::Point rot = (Geom::Rotate)postmul::vector(); + coord angle = rad_to_deg(atan2(rot)); + starting_angle.param_setValue(starting_angle + angle); + starting_angle.param_update_default(starting_angle + angle); + rotation_angle.param_setValue(rotation_angle + angle); + rotation_angle.param_update_default(rotation_angle + angle); + } + // cycle through all parameters. Most parameters will not need transformation, but path and point params do. + + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); + } +} void LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index bdbc61d07..d0a5b004b 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,6 +48,8 @@ public: virtual void resetDefaults(SPItem const* item); + virtual void transform_multiply(Geom::Affine const& postmul, bool set); + /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; friend class CR::KnotHolderEntityRotationAngle; -- cgit v1.2.3 From 2763fbcc2619a390e5f81c2887b1f8f312eb5e65 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 28 Mar 2015 22:04:40 +0100 Subject: Allow rotate copies whithout distorsion in kaleidoscope shapes (bzr r13708.1.22) --- src/live_effects/lpe-copy_rotate.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 5474bfb70..2e87133b3 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -92,13 +92,10 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(postmul->isRotation()){ - Geom::Point rot = (Geom::Rotate)postmul::vector(); - coord angle = rad_to_deg(atan2(rot)); - starting_angle.param_setValue(starting_angle + angle); - starting_angle.param_update_default(starting_angle + angle); - rotation_angle.param_setValue(rotation_angle + angle); - rotation_angle.param_update_default(rotation_angle + angle); + if(kaleidoscope){ + Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); + angle += starting_angle; + starting_angle.param_set_value(angle); } // cycle through all parameters. Most parameters will not need transformation, but path and point params do. -- cgit v1.2.3 From 1973e31feb91e5a2bbdd1c3e36b20d1681123447 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:01:46 +0200 Subject: astyle copy-rotate LPE (bzr r13708.1.25) --- src/live_effects/lpe-copy_rotate.cpp | 77 +++++++++++++++++++----------------- src/live_effects/lpe-copy_rotate.h | 6 +-- 2 files changed, 43 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 2e87133b3..bb331b37a 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -65,7 +65,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&rotation_angle); registerParameter(&num_copies); registerParameter(&origin); - + num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); } @@ -92,13 +92,13 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(kaleidoscope){ + if(kaleidoscope) { Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); } // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; param->param_transform_multiply(postmul, set); @@ -110,19 +110,19 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(kaleidoscope || copiesTo360 ){ + if(kaleidoscope || copiesTo360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope){ + if(kaleidoscope) { num_copies.param_set_increments(2,2); - if((int)num_copies%2 !=0){ + if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); } } else { num_copies.param_set_increments(1,1); } - if(dist_angle_handle < 1.0){ + if(dist_angle_handle < 1.0) { dist_angle_handle = 1.0; } A = Point(boundingbox_X.min(), boundingbox_Y.middle()); @@ -132,7 +132,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; - if( kaleidoscope || copiesTo360 ){ + if( kaleidoscope || copiesTo360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -140,7 +140,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) item->apply_to_mask(item); } -int +int LPECopyRotate::pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X) { //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line @@ -163,7 +163,8 @@ LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Ge } void -LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ +LPECopyRotate::split(std::vector &path_on,Geom::Path divider) +{ std::vector tmp_path; double timeStart = 0.0; Geom::Path original = path_on[0]; @@ -179,25 +180,25 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ Geom::Path portionOriginal = original.portion(timeStart,timeEnd); Geom::Point sideChecker = portionOriginal.pointAt(0.001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), sideChecker); - if(num_copies > 2){ + if(num_copies > 2) { position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(position == 1){ + if(position == 1) { tmp_path.push_back(portionOriginal); } portionOriginal.clear(); timeStart = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); - if(num_copies > 2){ + if(num_copies > 2) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(cs.size() > 0 && position == 1){ + if(cs.size() > 0 && position == 1) { Geom::Path portionOriginal = original.portion(timeStart, original.size()); - if (!original.closed()){ + if (!original.closed()) { tmp_path.push_back(portionOriginal); } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ){ + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { portionOriginal.setFinal(tmp_path[0].initialPoint()); portionOriginal.append(tmp_path[0]); tmp_path[0] = portionOriginal; @@ -208,20 +209,21 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ } portionOriginal.clear(); } - if(cs.size()==0 && position == 1){ + if(cs.size()==0 && position == 1) { tmp_path.push_back(original); } path_on = tmp_path; } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider){ +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider) +{ split(path_on,divider); std::vector tmp_path; Geom::Affine pre = Geom::Translate(-origin); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { Geom::Path original = *path_it; - if (path_it->empty()){ + if (path_it->empty()) { continue; } std::vector tmp_path2; @@ -229,7 +231,7 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi for (int i = 0; i < num_copies; ++i) { Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); - if(i%2 != 0){ + if(i%2 != 0) { Geom::Point A = (Geom::Point)origin; Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * sizeDivider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); @@ -249,44 +251,44 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi appendPath = original; } appendPath *= m; - if(i != 0 && tmp_path2.size() > 0 &&( Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint()))){ + if(i != 0 && tmp_path2.size() > 0 &&( Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint()))) { Geom::Path tmpAppend = appendPath.reverse(); tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())) { Geom::Path tmpAppend = appendPath; tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.initialPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.initialPoint())) { Geom::Path tmpAppend = appendPath; tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.finalPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.finalPoint())) { Geom::Path tmpAppend = appendPath.reverse(); tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),appendPath.finalPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),appendPath.finalPoint())) { Geom::Path tmpAppend = appendPath.reverse(); tmpAppend.setInitial(tmp_path2[0].finalPoint()); tmp_path2[0].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].initialPoint(),appendPath.initialPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].initialPoint(),appendPath.initialPoint())) { Geom::Path tmpAppend = appendPath; tmp_path2[0] = tmp_path2[0].reverse(); tmpAppend.setInitial(tmp_path2[0].finalPoint()); tmp_path2[0].append(tmpAppend); tmp_path2[0] = tmp_path2[0].reverse(); - } else { + } else { tmp_path2.push_back(appendPath); } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())){ + if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())) { tmp_path2[tmp_path2.size()-1].close(); } } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),tmp_path2[0].initialPoint())){ + if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),tmp_path2[0].initialPoint())) { tmp_path2[0].close(); } tmp_path.insert(tmp_path.end(), tmp_path2.begin(), tmp_path2.end()); @@ -301,12 +303,12 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if(num_copies == 1){ + if(num_copies == 1) { return pwd2_in; } double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); - Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double sizeDivider = Geom::distance(origin,bbox) + (diagonal * 2); Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; @@ -317,12 +319,12 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(lineEnd); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - if(kaleidoscope){ + if(kaleidoscope) { std::vector path_out; std::vector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()){ + if (path_it->empty()) { continue; } bool end_open = false; @@ -333,7 +335,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it->closed()){ + if(end_open && path_it->closed()) { original.close(false); original.appendNew( original.initialPoint() ); original.close(true); @@ -343,7 +345,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - if(path_out.size()>0){ + if(path_out.size()>0) { output = paths_to_pw(path_out); } } else { @@ -377,8 +379,9 @@ LPECopyRotate::resetDefaults(SPItem const* item) original_bbox(SP_LPE_ITEM(item)); } -void -LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { +void +LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index d0a5b004b..de00226a4 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -22,9 +22,9 @@ namespace Inkscape { namespace LivePathEffect { namespace CR { - // we need a separate namespace to avoid clashes with LPEPerpBisector - class KnotHolderEntityStartingAngle; - class KnotHolderEntityRotationAngle; +// we need a separate namespace to avoid clashes with LPEPerpBisector +class KnotHolderEntityStartingAngle; +class KnotHolderEntityRotationAngle; } class LPECopyRotate : public Effect, GroupBBoxEffect { -- cgit v1.2.3 From d163d3b01c24671f3124c16455d8654d7a1523f7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:13:54 +0200 Subject: Rename some variables to fit coding style (bzr r13708.1.26) --- src/live_effects/lpe-copy_rotate.cpp | 136 +++++++++++++++++------------------ src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 69 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index bb331b37a..4fd605b6d 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -51,7 +51,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), - copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), + copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, false), dist_angle_handle(100.0) { @@ -59,7 +59,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter(&copiesTo360); + registerParameter(&copies_to_360); registerParameter(&kaleidoscope); registerParameter(&starting_angle); registerParameter(&rotation_angle); @@ -110,7 +110,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(kaleidoscope || copiesTo360 ) { + if(kaleidoscope || copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } if(kaleidoscope) { @@ -132,7 +132,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; - if( kaleidoscope || copiesTo360 ) { + if( kaleidoscope || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -166,7 +166,7 @@ void LPECopyRotate::split(std::vector &path_on,Geom::Path divider) { std::vector tmp_path; - double timeStart = 0.0; + double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; Geom::Crossings cs = crossings(original,divider); @@ -177,37 +177,37 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) std::sort (crossed.begin(), crossed.end()); for(unsigned int i = 0; i < crossed.size(); i++) { double timeEnd = crossed[i]; - Geom::Path portionOriginal = original.portion(timeStart,timeEnd); - Geom::Point sideChecker = portionOriginal.pointAt(0.001); - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), sideChecker); + Geom::Path portion_original = original.portion(time_start,timeEnd); + Geom::Point side_checker = portion_original.pointAt(0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); if(num_copies > 2) { - position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(position == 1) { - tmp_path.push_back(portionOriginal); + tmp_path.push_back(portion_original); } - portionOriginal.clear(); - timeStart = timeEnd; + portion_original.clear(); + time_start = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); if(num_copies > 2) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(cs.size() > 0 && position == 1) { - Geom::Path portionOriginal = original.portion(timeStart, original.size()); + Geom::Path portion_original = original.portion(time_start, original.size()); if (!original.closed()) { - tmp_path.push_back(portionOriginal); + tmp_path.push_back(portion_original); } else { if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portionOriginal.setFinal(tmp_path[0].initialPoint()); - portionOriginal.append(tmp_path[0]); - tmp_path[0] = portionOriginal; + portion_original.setFinal(tmp_path[0].initialPoint()); + portion_original.append(tmp_path[0]); + tmp_path[0] = portion_original; } else { - tmp_path.push_back(portionOriginal); + tmp_path.push_back(portion_original); } //temp_path[0].close(); } - portionOriginal.clear(); + portion_original.clear(); } if(cs.size()==0 && position == 1) { tmp_path.push_back(original); @@ -216,7 +216,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider) +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double size_divider) { split(path_on,divider); std::vector tmp_path; @@ -226,14 +226,14 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi if (path_it->empty()) { continue; } - std::vector tmp_path2; - Geom::Path appendPath = original; + std::vector tmp_path_helper; + Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); if(i%2 != 0) { Geom::Point A = (Geom::Point)origin; - Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * sizeDivider; + Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * size_divider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); double hyp = Geom::distance(A, B); double c = (B[0] - A[0]) / hyp; // cos(alpha) @@ -248,51 +248,51 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi m = m * m2.inverse(); m = m * m1; } else { - appendPath = original; + append_path = original; } - appendPath *= m; - if(i != 0 && tmp_path2.size() > 0 &&( Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint()))) { - Geom::Path tmpAppend = appendPath.reverse(); - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())) { - Geom::Path tmpAppend = appendPath; - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.initialPoint())) { - Geom::Path tmpAppend = appendPath; - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.finalPoint())) { - Geom::Path tmpAppend = appendPath.reverse(); - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),appendPath.finalPoint())) { - Geom::Path tmpAppend = appendPath.reverse(); - tmpAppend.setInitial(tmp_path2[0].finalPoint()); - tmp_path2[0].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].initialPoint(),appendPath.initialPoint())) { - Geom::Path tmpAppend = appendPath; - tmp_path2[0] = tmp_path2[0].reverse(); - tmpAppend.setInitial(tmp_path2[0].finalPoint()); - tmp_path2[0].append(tmpAppend); - tmp_path2[0] = tmp_path2[0].reverse(); + append_path *= m; + if(i != 0 && tmp_path_helper.size() > 0 &&( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.finalPoint()))) { + Geom::Path tmp_append = append_path.reverse(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reverse(); + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].initialPoint(),append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_path_helper[0] = tmp_path_helper[0].reverse(); + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { - tmp_path2.push_back(appendPath); + tmp_path_helper.push_back(append_path); } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())) { - tmp_path2[tmp_path2.size()-1].close(); + if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { + tmp_path_helper[tmp_path_helper.size()-1].close(); } } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),tmp_path2[0].initialPoint())) { - tmp_path2[0].close(); + if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { + tmp_path_helper[0].close(); } - tmp_path.insert(tmp_path.end(), tmp_path2.begin(), tmp_path2.end()); - tmp_path2.clear(); + tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); + tmp_path_helper.clear(); } path_on = tmp_path; tmp_path.clear(); @@ -309,14 +309,14 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); - double sizeDivider = Geom::distance(origin,bbox) + (diagonal * 2); - Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; - Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; + double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point line_start = origin + dir * Rotate(-deg_to_rad(starting_angle)) * size_divider; + Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * size_divider; //Note:: beter way to do this //Whith AppendNew have problems whith the crossing order - Geom::Path divider = Geom::Path(lineStart); + Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); - divider.appendNew(lineEnd); + divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope) { @@ -341,7 +341,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider,sizeDivider); + setKaleidoscope(tmp_path,divider,size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index de00226a4..83f4a6984 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -63,7 +63,7 @@ private: ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; - BoolParam copiesTo360; + BoolParam copies_to_360; BoolParam kaleidoscope; Geom::Point A; -- cgit v1.2.3 From 78f080901f40a7390559f88ab14465131bb02717 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 1 Jun 2015 23:46:40 +0200 Subject: opening kaleidscope (bzr r13708.1.28) --- src/live_effects/lpe-copy_rotate.cpp | 95 ++++++++++++++++++++++++++++++++++-- src/live_effects/lpe-copy_rotate.h | 4 +- 2 files changed, 94 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 4fd605b6d..c119ca02e 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -110,10 +110,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(kaleidoscope || copies_to_360 ) { + if(copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope) { + if(kaleidoscope && copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -216,8 +216,72 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double size_divider) +LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider_extreme) { + std::vector tmp_path; + double time_start = 0.0; + Geom::Path original = path_on[0]; + int position = 0; + Geom::Crossings cs = crossings(original,divider_extreme); + std::vector crossed; + for(unsigned int i = 0; i < cs.size(); i++) { + crossed.push_back(cs[i].ta); + } + std::sort (crossed.begin(), crossed.end()); + for(unsigned int i = 0; i < crossed.size(); i++) { + double timeEnd = crossed[i]; + Geom::Path portion_original = original.portion(time_start,timeEnd); + Geom::Point side_checker = portion_original.pointAt(0.001); + position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), side_checker); + if(num_copies > 2) { + position = pointInTriangle(side_checker, divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); + } + if(position == 1) { + Geom::Path start = Geom::Path(divider_extreme.at(0)); + start.appendNew(divider_extreme.at(1)); + if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + portion_original.reverse(); + } + tmp_path.push_back(portion_original); + } + portion_original.clear(); + time_start = timeEnd; + } + position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), original.finalPoint()); + if(num_copies > 2) { + position = pointInTriangle(original.finalPoint(), divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); + } + if(cs.size() > 0 && position == 1) { + Geom::Path portion_original = original.portion(time_start, original.size()); + Geom::Path start = Geom::Path(divider_extreme.at(0)); + start.appendNew(divider_extreme.at(1)); + if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + portion_original.reverse(); + } + if (!original.closed()) { + tmp_path.push_back(portion_original); + } else { + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { + portion_original.setFinal(tmp_path[0].initialPoint()); + portion_original.append(tmp_path[0]); + tmp_path[0] = portion_original; + } else { + tmp_path.push_back(portion_original); + } + //temp_path[0].close(); + } + portion_original.clear(); + } + if(cs.size()==0 && position == 1) { + tmp_path.push_back(original); + } + path_on = tmp_path; +} + +void +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_extreme, double size_divider) +{ + std::vector path_on_start = path_on; split(path_on,divider); std::vector tmp_path; Geom::Affine pre = Geom::Translate(-origin); @@ -282,6 +346,21 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi tmp_path_helper[0].append(tmp_append); tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { + if(rotation_angle * num_copies != 360){ + split_start(path_on_start,divider_extreme); + for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { + Geom::Path original_start = *path_it_start; + if (path_it->empty()) { + continue; + } + std::vector tmp_path_helper; + if(tmp_path_helper.size() > 0 && Geom::are_near(append_path.initialPoint(),path_it_start[0].initialPoint())) { + path_it_start.reverse(); + path_it_start.append(append_path); + append_path = path_it_start; + } + } + } tmp_path_helper.push_back(append_path); } if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { @@ -317,6 +396,14 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); divider.appendNew(line_end); + Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle/2)+starting_angle)) * size_divider; + Geom::Path divider_start = Geom::Path(line_start); + divider_start.appendNew((Geom::Point)origin); + divider_start.appendNew(line_oposite); + Geom::Path divider_end = Geom::Path(line_end); + divider_end.appendNew((Geom::Point)origin); + divider_end.appendNew(line_oposite); + Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope) { @@ -341,7 +428,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider,size_divider); + setKaleidoscope(tmp_path,divider, divider_extreme, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 83f4a6984..638f8a413 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, double sizeDivider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path extreme, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); @@ -46,6 +46,8 @@ public: virtual void split(std::vector &path_in,Geom::Path divider); + virtual void split_extreme(std::vector &path_on,Geom::Path divider_extreme); + virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); -- cgit v1.2.3 From 53ff3799d1f7c05cfa7f1384eb39b5105c29f9ab Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 2 Jun 2015 19:29:54 +0200 Subject: opening kaleidscope (bzr r13708.1.30) --- src/live_effects/lpe-copy_rotate.cpp | 27 +++++++++++++-------------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index c119ca02e..f9d1bffee 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -237,9 +237,9 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider position = pointInTriangle(side_checker, divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); } if(position == 1) { - Geom::Path start = Geom::Path(divider_extreme.at(0)); - start.appendNew(divider_extreme.at(1)); - if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); + start.appendNew(divider_extreme.pointAt(1)); + if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ portion_original.reverse(); } tmp_path.push_back(portion_original); @@ -253,9 +253,9 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - Geom::Path start = Geom::Path(divider_extreme.at(0)); - start.appendNew(divider_extreme.at(1)); - if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); + start.appendNew(divider_extreme.pointAt(1)); + if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ portion_original.reverse(); } if (!original.closed()) { @@ -279,7 +279,7 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_extreme, double size_divider) +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double size_divider) { std::vector path_on_start = path_on; split(path_on,divider); @@ -347,18 +347,17 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { if(rotation_angle * num_copies != 360){ - split_start(path_on_start,divider_extreme); + split_extreme(path_on_start,divider_start); for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { Geom::Path original_start = *path_it_start; if (path_it->empty()) { continue; } - std::vector tmp_path_helper; - if(tmp_path_helper.size() > 0 && Geom::are_near(append_path.initialPoint(),path_it_start[0].initialPoint())) { - path_it_start.reverse(); - path_it_start.append(append_path); - append_path = path_it_start; + if(Geom::are_near(append_path.initialPoint(),original_start.initialPoint())) { + original_start.reverse(); } + original_start.append(append_path); + append_path = original_start; } } tmp_path_helper.push_back(append_path); @@ -428,7 +427,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider, divider_extreme, size_divider); + setKaleidoscope(tmp_path,divider, divider_start, divider_end, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 638f8a413..e16d3ceee 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path extreme, double sizeDivider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); -- cgit v1.2.3 From 22ca2d7d903022da13a50ac2517e1ff2e3b5257d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 00:54:55 +0200 Subject: opening kaleidscope (bzr r13708.1.32) --- src/live_effects/lpe-copy_rotate.cpp | 134 +++++++++++++---------------------- src/live_effects/lpe-copy_rotate.h | 4 +- 2 files changed, 51 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index f9d1bffee..990bc1192 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -113,7 +113,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope && copies_to_360) { + if(kaleidoscope && rotation_angle * num_copies > 360 && rotation_angle > 0){ + num_copies.param_set_value(floor(360/rotation_angle)); + } + if(kaleidoscope || copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -169,6 +172,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; + Geom::Line divider_line(divider.pointAt(0),divider.pointAt(1)); Geom::Crossings cs = crossings(original,divider); std::vector crossed; for(unsigned int i = 0; i < cs.size(); i++) { @@ -184,6 +188,9 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(position == 1) { + if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ + portion_original = portion_original.reverse(); + } tmp_path.push_back(portion_original); } portion_original.clear(); @@ -195,68 +202,8 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - if (!original.closed()) { - tmp_path.push_back(portion_original); - } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portion_original.setFinal(tmp_path[0].initialPoint()); - portion_original.append(tmp_path[0]); - tmp_path[0] = portion_original; - } else { - tmp_path.push_back(portion_original); - } - //temp_path[0].close(); - } - portion_original.clear(); - } - if(cs.size()==0 && position == 1) { - tmp_path.push_back(original); - } - path_on = tmp_path; -} - -void -LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider_extreme) -{ - std::vector tmp_path; - double time_start = 0.0; - Geom::Path original = path_on[0]; - int position = 0; - Geom::Crossings cs = crossings(original,divider_extreme); - std::vector crossed; - for(unsigned int i = 0; i < cs.size(); i++) { - crossed.push_back(cs[i].ta); - } - std::sort (crossed.begin(), crossed.end()); - for(unsigned int i = 0; i < crossed.size(); i++) { - double timeEnd = crossed[i]; - Geom::Path portion_original = original.portion(time_start,timeEnd); - Geom::Point side_checker = portion_original.pointAt(0.001); - position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), side_checker); - if(num_copies > 2) { - position = pointInTriangle(side_checker, divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); - } - if(position == 1) { - Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); - start.appendNew(divider_extreme.pointAt(1)); - if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ - portion_original.reverse(); - } - tmp_path.push_back(portion_original); - } - portion_original.clear(); - time_start = timeEnd; - } - position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), original.finalPoint()); - if(num_copies > 2) { - position = pointInTriangle(original.finalPoint(), divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); - } - if(cs.size() > 0 && position == 1) { - Geom::Path portion_original = original.portion(time_start, original.size()); - Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); - start.appendNew(divider_extreme.pointAt(1)); - if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ - portion_original.reverse(); + if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ + portion_original = portion_original.reverse(); } if (!original.closed()) { tmp_path.push_back(portion_original); @@ -279,7 +226,7 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double size_divider) +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) { std::vector path_on_start = path_on; split(path_on,divider); @@ -346,26 +293,49 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi tmp_path_helper[0].append(tmp_append); tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { - if(rotation_angle * num_copies != 360){ - split_extreme(path_on_start,divider_start); - for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { - Geom::Path original_start = *path_it_start; - if (path_it->empty()) { - continue; - } - if(Geom::are_near(append_path.initialPoint(),original_start.initialPoint())) { - original_start.reverse(); - } - original_start.append(append_path); - append_path = original_start; - } - } tmp_path_helper.push_back(append_path); } if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { tmp_path_helper[tmp_path_helper.size()-1].close(); } } + if(rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0){ + split(path_on_start,divider_start); + for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { + Geom::Path original_start = *path_it_start; + if (path_it->empty()) { + continue; + } + + if( Geom::are_near(tmp_path_helper[0].initialPoint(),original_start.initialPoint())){ + Geom::Point A(divider_start.pointAt(1)); + Geom::Point B(divider_start.pointAt(2)); + + Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); + double hyp = Geom::distance(A, B); + double c = (B[0] - A[0]) / hyp; // cos(alpha) + double s = (B[1] - A[1]) / hyp; // sin(alpha) + + Geom::Affine m2(c, -s, s, c, 0.0, 0.0); + Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + + Geom::Affine m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + original_start.setInitial(tmp_path_helper[0].initialPoint()); + Geom::Path mirror = original_start * m; + mirror = mirror.reverse(); + mirror.setInitial(original_start.finalPoint()); + original_start.append(mirror); + original_start = original_start.reverse(); + original_start.setFinal(tmp_path_helper[0].initialPoint()); + original_start.append(tmp_path_helper[0]); + tmp_path_helper[0] = original_start; + } + } + } + if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { tmp_path_helper[0].close(); } @@ -395,14 +365,10 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); divider.appendNew(line_end); - Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle/2)+starting_angle)) * size_divider; + Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle * num_copies /2)+starting_angle + 180)) * size_divider; Geom::Path divider_start = Geom::Path(line_start); divider_start.appendNew((Geom::Point)origin); divider_start.appendNew(line_oposite); - Geom::Path divider_end = Geom::Path(line_end); - divider_end.appendNew((Geom::Point)origin); - divider_end.appendNew(line_oposite); - Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope) { @@ -427,7 +393,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider, divider_start, divider_end, size_divider); + setKaleidoscope(tmp_path,divider, divider_start, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index e16d3ceee..efbb5f746 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double sizeDivider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); @@ -46,8 +46,6 @@ public: virtual void split(std::vector &path_in,Geom::Path divider); - virtual void split_extreme(std::vector &path_on,Geom::Path divider_extreme); - virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); -- cgit v1.2.3 From d50fe92ba2df09544c11aca985e1746ecdc47fe2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 01:20:27 +0200 Subject: opening kaleidscope (bzr r13708.1.33) --- src/live_effects/lpe-copy_rotate.cpp | 24 ++++++++++++------------ src/live_effects/lpe-copy_rotate.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 990bc1192..559e117cf 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -52,7 +52,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, false), + fusion_paths(_("Fusioned paths"), _("Fusion paths by helper line"), "fusion_paths", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; @@ -60,7 +60,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&copies_to_360); - registerParameter(&kaleidoscope); + registerParameter(&fusion_paths); registerParameter(&starting_angle); registerParameter(&rotation_angle); registerParameter(&num_copies); @@ -92,7 +92,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(kaleidoscope) { + if(fusion_paths) { Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); @@ -113,10 +113,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope && rotation_angle * num_copies > 360 && rotation_angle > 0){ + if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ num_copies.param_set_value(floor(360/rotation_angle)); } - if(kaleidoscope || copies_to_360) { + if(fusion_paths || copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -135,7 +135,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; - if( kaleidoscope || copies_to_360 ) { + if( fusion_paths || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -189,7 +189,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } if(position == 1) { if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - portion_original = portion_original.reverse(); + //portion_original = portion_original.reverse(); } tmp_path.push_back(portion_original); } @@ -203,7 +203,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - portion_original = portion_original.reverse(); + // portion_original = portion_original.reverse(); } if (!original.closed()) { tmp_path.push_back(portion_original); @@ -226,7 +226,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) +LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) { std::vector path_on_start = path_on; split(path_on,divider); @@ -359,7 +359,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); Geom::Point line_start = origin + dir * Rotate(-deg_to_rad(starting_angle)) * size_divider; - Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * size_divider; + Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle + starting_angle)) * size_divider; //Note:: beter way to do this //Whith AppendNew have problems whith the crossing order Geom::Path divider = Geom::Path(line_start); @@ -371,7 +371,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider_start.appendNew(line_oposite); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - if(kaleidoscope) { + if(fusion_paths) { std::vector path_out; std::vector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); @@ -393,7 +393,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider, divider_start, size_divider); + setFusion(tmp_path,divider, divider_start, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index efbb5f746..02141b359 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); + virtual void setFusion(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); @@ -64,7 +64,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copies_to_360; - BoolParam kaleidoscope; + BoolParam fusion_paths; Geom::Point A; Geom::Point B; -- cgit v1.2.3 From ee3b91ebda768eb483c159dc3072cb5a20df5086 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 20:37:00 +0200 Subject: Change from kaleidoscope to multiangle fusion (bzr r13708.1.34) --- src/live_effects/lpe-copy_rotate.cpp | 77 +++++++++++++----------------------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 28 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 559e117cf..d12c03f7e 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -116,7 +116,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ num_copies.param_set_value(floor(360/rotation_angle)); } - if(fusion_paths || copies_to_360) { + if(fusion_paths && copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -172,7 +172,6 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; - Geom::Line divider_line(divider.pointAt(0),divider.pointAt(1)); Geom::Crossings cs = crossings(original,divider); std::vector crossed; for(unsigned int i = 0; i < cs.size(); i++) { @@ -184,27 +183,21 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) Geom::Path portion_original = original.portion(time_start,timeEnd); Geom::Point side_checker = portion_original.pointAt(0.001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); - if(num_copies > 2) { + if(rotation_angle != 180) { position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(position == 1) { - if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - //portion_original = portion_original.reverse(); - } tmp_path.push_back(portion_original); } portion_original.clear(); time_start = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); - if(num_copies > 2) { + if(rotation_angle != 180) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - // portion_original = portion_original.reverse(); - } if (!original.closed()) { tmp_path.push_back(portion_original); } else { @@ -215,7 +208,6 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } else { tmp_path.push_back(portion_original); } - //temp_path[0].close(); } portion_original.clear(); } @@ -226,9 +218,8 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) +LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, double size_divider) { - std::vector path_on_start = path_on; split(path_on,divider); std::vector tmp_path; Geom::Affine pre = Geom::Translate(-origin); @@ -300,39 +291,29 @@ LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, G } } if(rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0){ - split(path_on_start,divider_start); - for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { - Geom::Path original_start = *path_it_start; - if (path_it->empty()) { - continue; + Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); + double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle * num_copies) + starting_angle)) * size_divider; + Geom::Ray base_b(divider.pointAt(1), base_point); + if(Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)){ + tmp_path_helper[0].close(); + if(tmp_path_helper.size() > 1){ + tmp_path_helper[tmp_path_helper.size()-1].close(); } - - if( Geom::are_near(tmp_path_helper[0].initialPoint(),original_start.initialPoint())){ - Geom::Point A(divider_start.pointAt(1)); - Geom::Point B(divider_start.pointAt(2)); - - Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); - double hyp = Geom::distance(A, B); - double c = (B[0] - A[0]) / hyp; // cos(alpha) - double s = (B[1] - A[1]) / hyp; // sin(alpha) - - Geom::Affine m2(c, -s, s, c, 0.0, 0.0); - Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); - - Geom::Affine m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - original_start.setInitial(tmp_path_helper[0].initialPoint()); - Geom::Path mirror = original_start * m; - mirror = mirror.reverse(); - mirror.setInitial(original_start.finalPoint()); - original_start.append(mirror); - original_start = original_start.reverse(); - original_start.setFinal(tmp_path_helper[0].initialPoint()); - original_start.append(tmp_path_helper[0]); - tmp_path_helper[0] = original_start; + } else if(Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)){ + tmp_path_helper[0].close(); + if(tmp_path_helper.size() > 1){ + tmp_path_helper[tmp_path_helper.size()-1].close(); } + } else if((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || + (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))){ + Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + close_path.appendNew((Geom::Point)origin); + close_path.appendNew(tmp_path_helper[0].initialPoint()); + tmp_path_helper[0].append(close_path); } } @@ -351,7 +332,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if(num_copies == 1) { + if(num_copies == 1 && !fusion_paths) { return pwd2_in; } @@ -365,10 +346,6 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); divider.appendNew(line_end); - Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle * num_copies /2)+starting_angle + 180)) * size_divider; - Geom::Path divider_start = Geom::Path(line_start); - divider_start.appendNew((Geom::Point)origin); - divider_start.appendNew(line_oposite); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(fusion_paths) { @@ -393,7 +370,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setFusion(tmp_path,divider, divider_start, size_divider); + setFusion(tmp_path, divider, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 02141b359..b230a6fc9 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setFusion(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); + virtual void setFusion(std::vector &path_in, Geom::Path divider, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); -- cgit v1.2.3 From e9e6116349cc51e31ae3a643a89644aa4e817b0a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 22:21:35 +0200 Subject: fix minor bug (bzr r13708.1.36) --- src/live_effects/lpe-copy_rotate.cpp | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index d12c03f7e..cfc1b92cf 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -110,7 +110,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(copies_to_360 ) { + if( copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ @@ -181,16 +181,18 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) for(unsigned int i = 0; i < crossed.size(); i++) { double timeEnd = crossed[i]; Geom::Path portion_original = original.portion(time_start,timeEnd); - Geom::Point side_checker = portion_original.pointAt(0.001); - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); - if(rotation_angle != 180) { - position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); - } - if(position == 1) { - tmp_path.push_back(portion_original); + if(!portion_original.empty()){ + Geom::Point side_checker = portion_original.pointAt(0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); + if(rotation_angle != 180) { + position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + } + if(position == 1) { + tmp_path.push_back(portion_original); + } + portion_original.clear(); + time_start = timeEnd; } - portion_original.clear(); - time_start = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); if(rotation_angle != 180) { @@ -198,18 +200,20 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - if (!original.closed()) { - tmp_path.push_back(portion_original); - } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portion_original.setFinal(tmp_path[0].initialPoint()); - portion_original.append(tmp_path[0]); - tmp_path[0] = portion_original; - } else { + if(!portion_original.empty()){ + if (!original.closed()) { tmp_path.push_back(portion_original); + } else { + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { + portion_original.setFinal(tmp_path[0].initialPoint()); + portion_original.append(tmp_path[0]); + tmp_path[0] = portion_original; + } else { + tmp_path.push_back(portion_original); + } } + portion_original.clear(); } - portion_original.clear(); } if(cs.size()==0 && position == 1) { tmp_path.push_back(original); -- cgit v1.2.3 From 713ebbaf2d2961951d599543cff3b3cae721955c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 25 Jul 2015 00:19:48 +0200 Subject: fixes for update to trunk (bzr r13708.1.38) --- src/live_effects/lpe-copy_rotate.cpp | 32 ++++++++++++++++---------------- src/live_effects/lpe-copy_rotate.h | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index cfc1b92cf..083f56be8 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -166,9 +166,9 @@ LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Ge } void -LPECopyRotate::split(std::vector &path_on,Geom::Path divider) +LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) { - std::vector tmp_path; + Geom::PathVector tmp_path; double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; @@ -222,17 +222,17 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, double size_divider) +LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double size_divider) { split(path_on,divider); - std::vector tmp_path; + Geom::PathVector tmp_path; Geom::Affine pre = Geom::Translate(-origin); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { Geom::Path original = *path_it; if (path_it->empty()) { continue; } - std::vector tmp_path_helper; + Geom::PathVector tmp_path_helper; Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); @@ -258,35 +258,35 @@ LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, d } append_path *= m; if(i != 0 && tmp_path_helper.size() > 0 &&( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.finalPoint()))) { - Geom::Path tmp_append = append_path.reverse(); + Geom::Path tmp_append = append_path.reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.initialPoint())) { Geom::Path tmp_append = append_path; - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.initialPoint())) { Geom::Path tmp_append = append_path; tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reverse(); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + Geom::Path tmp_append = append_path.reversed(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reverse(); + Geom::Path tmp_append = append_path.reversed(); tmp_append.setInitial(tmp_path_helper[0].finalPoint()); tmp_path_helper[0].append(tmp_append); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].initialPoint(),append_path.initialPoint())) { Geom::Path tmp_append = append_path; - tmp_path_helper[0] = tmp_path_helper[0].reverse(); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); tmp_append.setInitial(tmp_path_helper[0].finalPoint()); tmp_path_helper[0].append(tmp_append); - tmp_path_helper[0] = tmp_path_helper[0].reverse(); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); } else { tmp_path_helper.push_back(append_path); } @@ -353,8 +353,8 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(fusion_paths) { - std::vector path_out; - std::vector tmp_path; + Geom::PathVector path_out; + Geom::PathVector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) { diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index b230a6fc9..e45fa6d37 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,13 +38,13 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setFusion(std::vector &path_in, Geom::Path divider, double sizeDivider); + virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); - virtual void split(std::vector &path_in,Geom::Path divider); + virtual void split(Geom::PathVector &path_in,Geom::Path divider); virtual void resetDefaults(SPItem const* item); -- cgit v1.2.3 From 235b6bd52fd472cbc18224d4724961c70fd6214f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 14 Mar 2016 18:34:24 +0100 Subject: Fix order LPE (bzr r13708.1.41) --- src/live_effects/effect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index c8696ea3a..2e811ed37 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -144,13 +144,13 @@ const Util::EnumData LPETypeData[] = { {BSPLINE, N_("BSpline"), "bspline"}, {JOIN_TYPE, N_("Join type"), "join_type"}, {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, + {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, /* Ponyscape -> Inkscape 0.92*/ {ATTACH_PATH, N_("Attach path"), "attach_path"}, {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, - {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); -- cgit v1.2.3 From 1bd6284551204ec5b44775a27069595366742ac9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 14 Mar 2016 23:56:39 +0100 Subject: Fix compiling bugs (bzr r13708.1.42) --- src/live_effects/lpe-copy_rotate.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index c60de961d..a16a21bf0 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -93,7 +93,7 @@ void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { if(fusion_paths) { - Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); + Geom::Coord angle = Geom::deg_from_rad(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); } @@ -235,11 +235,11 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s Geom::PathVector tmp_path_helper; Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { - Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); + Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); if(i%2 != 0) { Geom::Point A = (Geom::Point)origin; - Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * size_divider; + Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); double hyp = Geom::distance(A, B); double c = (B[0] - A[0]) / hyp; // cos(alpha) @@ -299,7 +299,7 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); - Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle * num_copies) + starting_angle)) * size_divider; + Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; Geom::Ray base_b(divider.pointAt(1), base_point); if(Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)){ tmp_path_helper[0].close(); @@ -343,8 +343,8 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); - Geom::Point line_start = origin + dir * Rotate(-deg_to_rad(starting_angle)) * size_divider; - Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle + starting_angle)) * size_divider; + Geom::Point line_start = origin + dir * Rotate(-rad_from_deg(starting_angle)) * size_divider; + Geom::Point line_end = origin + dir * Rotate(-rad_from_deg(rotation_angle + starting_angle)) * size_divider; //Note:: beter way to do this //Whith AppendNew have problems whith the crossing order Geom::Path divider = Geom::Path(line_start); @@ -383,7 +383,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } else { for (int i = 0; i < num_copies; ++i) { - Rotate rot(-deg_to_rad(rotation_angle * i)); + Rotate rot(-rad_from_deg(rotation_angle * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } -- cgit v1.2.3 From 56b52d05b683b379bd9711531cc052fc1d7c3ecf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 18 Mar 2016 23:30:57 +0100 Subject: Fix Krzysztof comments on merge proposal (bzr r13708.1.43) --- src/live_effects/lpe-copy_rotate.cpp | 203 +++++++++++++++++++---------------- src/live_effects/lpe-copy_rotate.h | 17 +-- 2 files changed, 109 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index a16a21bf0..83175f3e2 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -44,6 +44,29 @@ public: } // namespace CR +int +pointSideOfLine(Geom::Point const &A, Geom::Point const &B, Geom::Point const &X) +{ + //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line + double pos = (B[Geom::X]-A[Geom::X])*(X[Geom::Y]-A[Geom::Y]) - (B[Geom::Y]-A[Geom::Y])*(X[Geom::X]-A[Geom::X]); + return (pos < 0) ? -1 : (pos > 0); +} + +bool +pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3) +{ + //http://totologic.blogspot.com.es/2014/01/accurate-point-in-triangle-test.html + using Geom::X; + using Geom::Y; + double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); + double t1 = (p[X]*(p3[Y] - p1[Y]) + p[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator; + double t2 = (p[X]*(p2[Y] - p1[Y]) + p[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator; + double s = t1 + t2; + + return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; +} + + LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), @@ -110,22 +133,22 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if( copies_to_360 ) { + if (copies_to_360) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ + if (fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { num_copies.param_set_value(floor(360/rotation_angle)); } - if(fusion_paths && copies_to_360) { + if (fusion_paths && copies_to_360) { num_copies.param_set_increments(2,2); - if((int)num_copies%2 !=0) { + if ((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); } } else { num_copies.param_set_increments(1,1); } - if(dist_angle_handle < 1.0) { + if (dist_angle_handle < 1.0) { dist_angle_handle = 1.0; } A = Point(boundingbox_X.min(), boundingbox_Y.middle()); @@ -135,7 +158,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; - if( fusion_paths || copies_to_360 ) { + if ( fusion_paths || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -143,30 +166,8 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) item->apply_to_mask(item); } -int -LPECopyRotate::pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X) -{ - //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line - double pos = (B[Geom::X]-A[Geom::X])*(X[Geom::Y]-A[Geom::Y]) - (B[Geom::Y]-A[Geom::Y])*(X[Geom::X]-A[Geom::X]); - return (pos < 0) ? -1 : (pos > 0); -} - -bool -LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Geom::Point p3) -{ - //http://totologic.blogspot.com.es/2014/01/accurate-point-in-triangle-test.html - using Geom::X; - using Geom::Y; - double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); - double t1 = (p[X]*(p3[Y] - p1[Y]) + p[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator; - double t2 = (p[X]*(p2[Y] - p1[Y]) + p[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator; - double s = t1 + t2; - - return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; -} - void -LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) +LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) { Geom::PathVector tmp_path; double time_start = 0.0; @@ -177,34 +178,34 @@ LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) for(unsigned int i = 0; i < cs.size(); i++) { crossed.push_back(cs[i].ta); } - std::sort (crossed.begin(), crossed.end()); - for(unsigned int i = 0; i < crossed.size(); i++) { - double timeEnd = crossed[i]; - Geom::Path portion_original = original.portion(time_start,timeEnd); - if(!portion_original.empty()){ + std::sort(crossed.begin(), crossed.end()); + for (unsigned int i = 0; i < crossed.size(); i++) { + double time_end = crossed[i]; + Geom::Path portion_original = original.portion(time_start,time_end); + if (!portion_original.empty()) { Geom::Point side_checker = portion_original.pointAt(0.001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); - if(rotation_angle != 180) { + if (rotation_angle != 180) { position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(position == 1) { + if (position == 1) { tmp_path.push_back(portion_original); } portion_original.clear(); - time_start = timeEnd; + time_start = time_end; } } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); - if(rotation_angle != 180) { + if (rotation_angle != 180) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(cs.size() > 0 && position == 1) { + if (cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); if(!portion_original.empty()){ if (!original.closed()) { tmp_path.push_back(portion_original); } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { + if (tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { portion_original.setFinal(tmp_path[0].initialPoint()); portion_original.append(tmp_path[0]); tmp_path[0] = portion_original; @@ -215,7 +216,7 @@ LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) portion_original.clear(); } } - if(cs.size()==0 && position == 1) { + if (cs.size()==0 && position == 1) { tmp_path.push_back(original); } path_on = tmp_path; @@ -235,9 +236,11 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s Geom::PathVector tmp_path_helper; Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { + Geom::Path last_helper; + Geom::Path start_helper; Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); - if(i%2 != 0) { + if (i%2 != 0) { Geom::Point A = (Geom::Point)origin; Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); @@ -257,72 +260,82 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s append_path = original; } append_path *= m; - if(i != 0 && tmp_path_helper.size() > 0 &&( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.finalPoint()))) { - Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.initialPoint())) { - Geom::Path tmp_append = append_path; - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.initialPoint())) { - Geom::Path tmp_append = append_path; - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reversed(); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(tmp_path_helper[0].finalPoint()); - tmp_path_helper[0].append(tmp_append); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].initialPoint(),append_path.initialPoint())) { - Geom::Path tmp_append = append_path; - tmp_path_helper[0] = tmp_path_helper[0].reversed(); - tmp_append.setInitial(tmp_path_helper[0].finalPoint()); - tmp_path_helper[0].append(tmp_append); - tmp_path_helper[0] = tmp_path_helper[0].reversed(); + if (i != 0 && tmp_path_helper.size() > 0) { + last_helper = tmp_path_helper[tmp_path_helper.size()-1]; + start_helper = tmp_path_helper[0]; + if (Geom::are_near(last_helper.finalPoint(), append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reversed(); + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + } else if (Geom::are_near(last_helper.initialPoint(), append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + last_helper = last_helper.reversed(); + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + last_helper = last_helper.reversed(); + } else if (Geom::are_near(last_helper.finalPoint(), append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + } else if (Geom::are_near(last_helper.initialPoint(), append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reversed(); + last_helper = last_helper.reversed(); + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + last_helper = last_helper.reversed(); + } else if (Geom::are_near(start_helper.finalPoint(), append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reversed(); + tmp_append.setInitial(start_helper.finalPoint()); + start_helper.append(tmp_append); + } else if (Geom::are_near(start_helper.initialPoint(), append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + start_helper = start_helper.reversed(); + tmp_append.setInitial(start_helper.finalPoint()); + start_helper.append(tmp_append); + start_helper = start_helper.reversed(); + } else { + tmp_path_helper.push_back(append_path); + } } else { tmp_path_helper.push_back(append_path); } - if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { - tmp_path_helper[tmp_path_helper.size()-1].close(); + if (tmp_path_helper.size() > 0) { + if ( Geom::are_near(last_helper.finalPoint(),last_helper.initialPoint())) { + last_helper.close(); + } } } - if(rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0){ + if (rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0) { + Geom::Path last_helper = tmp_path_helper[tmp_path_helper.size()-1]; + Geom::Path start_helper = tmp_path_helper[0]; Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; Geom::Ray base_b(divider.pointAt(1), base_point); - if(Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)){ - tmp_path_helper[0].close(); - if(tmp_path_helper.size() > 1){ - tmp_path_helper[tmp_path_helper.size()-1].close(); + if (Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(start_helper.finalPoint(),base_a)) { + start_helper.close(); + if (tmp_path_helper.size() > 1) { + last_helper.close(); } - } else if(Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && - Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)){ - tmp_path_helper[0].close(); - if(tmp_path_helper.size() > 1){ - tmp_path_helper[tmp_path_helper.size()-1].close(); + } else if (Geom::are_near(last_helper.initialPoint(),base_b) && + Geom::are_near(last_helper.finalPoint(),base_b)) { + start_helper.close(); + if (tmp_path_helper.size() > 1) { + last_helper.close(); } - } else if((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || - (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))){ - Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + } else if ((Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(last_helper.finalPoint(),base_b)) || + (Geom::are_near(start_helper.initialPoint(),base_b) && Geom::are_near(last_helper.finalPoint(),base_a))) { + Geom::Path close_path = Geom::Path(last_helper.finalPoint()); close_path.appendNew((Geom::Point)origin); - close_path.appendNew(tmp_path_helper[0].initialPoint()); - tmp_path_helper[0].append(close_path); + close_path.appendNew(start_helper.initialPoint()); + start_helper.append(close_path); } } - if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { - tmp_path_helper[0].close(); + if (tmp_path_helper.size() > 0 && Geom::are_near(start_helper.finalPoint(),start_helper.initialPoint())) { + start_helper.close(); } tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); tmp_path_helper.clear(); @@ -336,7 +349,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if(num_copies == 1 && !fusion_paths) { + if (num_copies == 1 && !fusion_paths) { return pwd2_in; } @@ -352,7 +365,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); - if(fusion_paths) { + if (fusion_paths) { Geom::PathVector path_out; Geom::PathVector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); @@ -368,7 +381,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it->closed()) { + if (end_open && path_it->closed()) { original.close(false); original.appendNew( original.initialPoint() ); original.close(true); @@ -378,7 +391,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - if(path_out.size()>0) { + if (path_out.size()>0) { output = paths_to_pw(path_out); } } else { diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index e45fa6d37..077699b80 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -31,25 +31,13 @@ class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); virtual ~LPECopyRotate(); - virtual void doOnApply (SPLPEItem const* lpeitem); - virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); - - virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); - - virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); - virtual void split(Geom::PathVector &path_in,Geom::Path divider); - virtual void resetDefaults(SPItem const* item); - virtual void transform_multiply(Geom::Affine const& postmul, bool set); - /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; friend class CR::KnotHolderEntityRotationAngle; @@ -64,16 +52,13 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copies_to_360; - BoolParam fusion_paths; - + BoolParam fusion_paths ; Geom::Point A; Geom::Point B; Geom::Point dir; - Geom::Point start_pos; Geom::Point rot_pos; double dist_angle_handle; - LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); }; -- cgit v1.2.3 From 16a30a307c06154881b9c563cb77309810a15baf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 19 Mar 2016 01:13:27 +0100 Subject: Fix more Krzysztof comments on merge proposal, temporary disable LPE on clip and paths (bzr r13708.1.44) --- src/live_effects/lpe-copy_rotate.cpp | 147 ++++++++++++++++++----------------- src/live_effects/lpe-copy_rotate.h | 4 +- 2 files changed, 77 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 83175f3e2..f204f8608 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -74,7 +74,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - fusion_paths(_("Fusioned paths"), _("Fusion paths by helper line"), "fusion_paths", &wr, this, false), + fuse_paths(_("Fuse paths"), _("Fuse paths by helper line"), "fuse_paths", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; @@ -83,7 +83,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&copies_to_360); - registerParameter(&fusion_paths); + registerParameter(&fuse_paths); registerParameter(&starting_angle); registerParameter(&rotation_angle); registerParameter(&num_copies); @@ -115,7 +115,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(fusion_paths) { + if(fuse_paths) { Geom::Coord angle = Geom::deg_from_rad(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); @@ -136,10 +136,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if (copies_to_360) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if (fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { + if (fuse_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { num_copies.param_set_value(floor(360/rotation_angle)); } - if (fusion_paths && copies_to_360) { + if (fuse_paths && copies_to_360) { num_copies.param_set_increments(2,2); if ((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -158,7 +158,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; - if ( fusion_paths || copies_to_360 ) { + if ( fuse_paths || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -235,9 +235,8 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s } Geom::PathVector tmp_path_helper; Geom::Path append_path = original; + for (int i = 0; i < num_copies; ++i) { - Geom::Path last_helper; - Geom::Path start_helper; Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); if (i%2 != 0) { @@ -251,8 +250,8 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s Geom::Affine m2(c, -s, s, c, 0.0, 0.0); Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); - Geom::Affine tmpM = m1.inverse() * m2; - m = tmpM; + Geom::Affine tmp_m = m1.inverse() * m2; + m = tmp_m; m = m * sca; m = m * m2.inverse(); m = m * m1; @@ -260,82 +259,86 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s append_path = original; } append_path *= m; - if (i != 0 && tmp_path_helper.size() > 0) { - last_helper = tmp_path_helper[tmp_path_helper.size()-1]; - start_helper = tmp_path_helper[0]; - if (Geom::are_near(last_helper.finalPoint(), append_path.finalPoint())) { + if (tmp_path_helper.size() > 0) { + if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - } else if (Geom::are_near(last_helper.initialPoint(), append_path.initialPoint())) { + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; - last_helper = last_helper.reversed(); - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - last_helper = last_helper.reversed(); - } else if (Geom::are_near(last_helper.finalPoint(), append_path.initialPoint())) { + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - } else if (Geom::are_near(last_helper.initialPoint(), append_path.finalPoint())) { + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); - last_helper = last_helper.reversed(); - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - last_helper = last_helper.reversed(); - } else if (Geom::are_near(start_helper.finalPoint(), append_path.finalPoint())) { + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + } else if (Geom::are_near(tmp_path_helper[0].finalPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(start_helper.finalPoint()); - start_helper.append(tmp_append); - } else if (Geom::are_near(start_helper.initialPoint(), append_path.initialPoint())) { + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + } else if (Geom::are_near(tmp_path_helper[0].initialPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; - start_helper = start_helper.reversed(); - tmp_append.setInitial(start_helper.finalPoint()); - start_helper.append(tmp_append); - start_helper = start_helper.reversed(); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); } else { tmp_path_helper.push_back(append_path); } + if ( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { + tmp_path_helper[tmp_path_helper.size()-1].close(); + } } else { tmp_path_helper.push_back(append_path); } - if (tmp_path_helper.size() > 0) { - if ( Geom::are_near(last_helper.finalPoint(),last_helper.initialPoint())) { - last_helper.close(); - } - } } - if (rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0) { - Geom::Path last_helper = tmp_path_helper[tmp_path_helper.size()-1]; - Geom::Path start_helper = tmp_path_helper[0]; - Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); - double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); - Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); - double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); - Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; - Geom::Ray base_b(divider.pointAt(1), base_point); - if (Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(start_helper.finalPoint(),base_a)) { - start_helper.close(); - if (tmp_path_helper.size() > 1) { - last_helper.close(); - } - } else if (Geom::are_near(last_helper.initialPoint(),base_b) && - Geom::are_near(last_helper.finalPoint(),base_b)) { - start_helper.close(); - if (tmp_path_helper.size() > 1) { - last_helper.close(); + if (tmp_path_helper.size() > 0) { + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1]; + tmp_path_helper[0] = tmp_path_helper[0]; + if (rotation_angle * num_copies != 360) { + Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); + double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); + double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; + Geom::Ray base_b(divider.pointAt(1), base_point); + if (Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && + Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)) + { + tmp_path_helper[0].close(); + if (tmp_path_helper.size() > 1) { + tmp_path_helper[tmp_path_helper.size()-1].close(); + } + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) + { + tmp_path_helper[0].close(); + if (tmp_path_helper.size() > 1) { + tmp_path_helper[tmp_path_helper.size()-1].close(); + } + } else if ((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || + (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))) + { + Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + close_path.appendNew((Geom::Point)origin); + close_path.appendNew(tmp_path_helper[0].initialPoint()); + tmp_path_helper[0].append(close_path); } - } else if ((Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(last_helper.finalPoint(),base_b)) || - (Geom::are_near(start_helper.initialPoint(),base_b) && Geom::are_near(last_helper.finalPoint(),base_a))) { - Geom::Path close_path = Geom::Path(last_helper.finalPoint()); - close_path.appendNew((Geom::Point)origin); - close_path.appendNew(start_helper.initialPoint()); - start_helper.append(close_path); } - } - if (tmp_path_helper.size() > 0 && Geom::are_near(start_helper.finalPoint(),start_helper.initialPoint())) { - start_helper.close(); + if (Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { + tmp_path_helper[0].close(); + } } tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); tmp_path_helper.clear(); @@ -349,7 +352,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if (num_copies == 1 && !fusion_paths) { + if (num_copies == 1 && !fuse_paths) { return pwd2_in; } @@ -365,7 +368,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); - if (fusion_paths) { + if (fuse_paths) { Geom::PathVector path_out; Geom::PathVector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 077699b80..87af867df 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -35,7 +35,7 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); - virtual void split(Geom::PathVector &path_in,Geom::Path divider); + virtual void split(Geom::PathVector &path_in, Geom::Path const ÷r); virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); /* the knotholder entity classes must be declared friends */ @@ -52,7 +52,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copies_to_360; - BoolParam fusion_paths ; + BoolParam fuse_paths; Geom::Point A; Geom::Point B; Geom::Point dir; -- cgit v1.2.3