index 40a4b1a54833f70b4b7ec1d03790f570edfbd138..dac34c5d485bad8057bae5966942e8e5f8b02463 100644 (file)
#include <2geom/path.h>
#include <2geom/transforms.h>
#include <2geom/d2-sbasis.h>
+#include <2geom/angle.h>
namespace Inkscape {
namespace LivePathEffect {
namespace CR {
-class KnotHolderEntityAngle : public KnotHolderEntity
+class KnotHolderEntityStartingAngle : public LPEKnotHolderEntity
{
public:
- virtual bool isLPEParam() { return true; }
+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+ virtual Geom::Point knot_get();
+};
- virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state);
- virtual NR::Point knot_get();
+class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity
+{
+public:
+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+ virtual Geom::Point knot_get();
};
} // namespace CR
LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
- include_original(_("Include original?"), _(""), "include_original", &wr, this, false),
- angle(_("Angle"), _("Angle"), "angle", &wr, this, 30.0),
- num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 1),
- origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this),
+ 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),
+ origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"),
dist_angle_handle(100)
{
show_orig_path = true;
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter( dynamic_cast<Parameter *>(&include_original) );
- registerParameter( dynamic_cast<Parameter *>(&angle) );
+ registerParameter( dynamic_cast<Parameter *>(&starting_angle) );
+ registerParameter( dynamic_cast<Parameter *>(&rotation_angle) );
registerParameter( dynamic_cast<Parameter *>(&num_copies) );
registerParameter( dynamic_cast<Parameter *>(&origin) );
- registerKnotHolderHandle(new CR::KnotHolderEntityAngle(), _("Adjust the angle"));
+ registerKnotHolderHandle(new CR::KnotHolderEntityStartingAngle(), _("Adjust the starting angle"));
+ registerKnotHolderHandle(new CR::KnotHolderEntityRotationAngle(), _("Adjust the rotation angle"));
num_copies.param_make_integer(true);
num_copies.param_set_range(0, 1000);
{
SPCurve *curve = SP_SHAPE(lpeitem)->curve;
- A = curve->first_point().to_2geom();
- B = curve->last_point().to_2geom();
+ A = *(curve->first_point());
+ B = *(curve->last_point());
origin.param_setValue(A);
@@ -83,25 +90,43 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > 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;
+ rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle)) * dist_angle_handle;
+
A = pwd2_in.firstValue();
B = pwd2_in.lastValue();
dir = unit_vector(B - A);
Piecewise<D2<SBasis> > output;
- if (include_original) {
- output = pwd2_in;
- }
-
- for (int i = 1; i <= num_copies; ++i) {
- Rotate rot(deg_to_rad(angle * i));
- Matrix t = Translate(-origin) * rot * Translate(origin);
+ Matrix 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 * i));
+ Matrix t = pre * rot * Translate(origin);
output.concat(pwd2_in * t);
}
return output;
}
+void
+LPECopyRotate::addCanvasIndicators(SPLPEItem */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
+{
+ using namespace Geom;
+
+ Path path(start_pos);
+ path.appendNew<LineSegment>((Geom::Point) origin);
+ path.appendNew<LineSegment>(rot_pos);
+
+ PathVector pathv;
+ pathv.push_back(path);
+ hp_vec.push_back(pathv);
+}
+
namespace CR {
using namespace Geom;
}
void
-KnotHolderEntityAngle::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint state)
+KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
LPECopyRotate* lpe = get_effect(item);
- // FIXME: is the minus sign due to a bug in 2geom?
- lpe->angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, p.to_2geom() - lpe->origin)));
+ Geom::Point const s = snap_knot_position(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)
+ lpe->starting_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)));
if (state & GDK_SHIFT_MASK) {
lpe->dist_angle_handle = L2(lpe->B - lpe->A);
} else {
@@ -135,15 +163,38 @@ KnotHolderEntityAngle::knot_set(NR::Point const &p, NR::Point const &/*origin*/,
sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
}
-NR::Point
-KnotHolderEntityAngle::knot_get()
+void
+KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
LPECopyRotate* lpe = get_effect(item);
- // FIXME: is the minus sign due to a bug in 2geom?
- Point d = lpe->dir * Rotate(-deg_to_rad(lpe->angle)) * lpe->dist_angle_handle;
+ Geom::Point const s = snap_knot_position(p);
- return lpe->origin + d;
+ // 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()
+{
+ LPECopyRotate* lpe = get_effect(item);
+ return snap_knot_position(lpe->start_pos);
+}
+
+Geom::Point
+KnotHolderEntityRotationAngle::knot_get()
+{
+ LPECopyRotate* lpe = get_effect(item);
+ return snap_knot_position(lpe->rot_pos);
}
} // namespace CR