ac720b88b2c874a17a8ee3d1d774ed40d8ba95c0
1 #define INKSCAPE_LPE_PERP_BISECTOR_CPP
2 /** \file
3 * LPE <perp_bisector> implementation.
4 */
5 /*
6 * Authors:
7 * Maximilian Albert
8 * Johan Engelen
9 *
10 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
11 * Copyright (C) Maximilin Albert 2008 <maximilian.albert@gmail.com>
12 *
13 * Released under GNU GPL, read the file 'COPYING' for more information
14 */
16 #include "live_effects/lpe-perp_bisector.h"
17 #include "display/curve.h"
18 #include "sp-path.h"
19 #include "line-geometry.h"
20 #include "sp-lpe-item.h"
21 #include <2geom/path.h>
23 namespace Inkscape {
24 namespace LivePathEffect {
25 namespace PB {
27 class KnotHolderEntityEnd : public LPEKnotHolderEntity {
28 public:
29 void bisector_end_set(Geom::Point const &p, bool left = true);
30 };
32 class KnotHolderEntityLeftEnd : public KnotHolderEntityEnd {
33 public:
34 virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
35 virtual Geom::Point knot_get();
36 };
38 class KnotHolderEntityRightEnd : public KnotHolderEntityEnd {
39 public:
40 virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
41 virtual Geom::Point knot_get();
42 };
44 // TODO: Make this more generic
45 static LPEPerpBisector *
46 get_effect(SPItem *item)
47 {
48 Effect *effect = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item));
49 if (effect->effectType() != PERP_BISECTOR) {
50 g_print ("Warning: Effect is not of type LPEPerpBisector!\n");
51 return NULL;
52 }
53 return static_cast<LPEPerpBisector *>(effect);
54 }
56 Geom::Point
57 KnotHolderEntityLeftEnd::knot_get() {
58 Inkscape::LivePathEffect::LPEPerpBisector *lpe = get_effect(item);
59 return Geom::Point(lpe->C);
60 }
62 Geom::Point
63 KnotHolderEntityRightEnd::knot_get() {
64 Inkscape::LivePathEffect::LPEPerpBisector *lpe = get_effect(item);
65 return Geom::Point(lpe->D);
66 }
68 void
69 KnotHolderEntityEnd::bisector_end_set(Geom::Point const &p, bool left) {
70 Inkscape::LivePathEffect::LPEPerpBisector *lpe =
71 dynamic_cast<Inkscape::LivePathEffect::LPEPerpBisector *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
72 if (!lpe) return;
74 Geom::Point const s = snap_knot_position(p);
76 double lambda = Geom::nearest_point(s, lpe->M, lpe->perp_dir);
77 if (left) {
78 lpe->C = lpe->M + lpe->perp_dir * lambda;
79 lpe->length_left.param_set_value(lambda);
80 } else {
81 lpe->D = lpe->M + lpe->perp_dir * lambda;
82 lpe->length_right.param_set_value(-lambda);
83 }
85 // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
86 sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), true, true);
87 }
89 void
90 KnotHolderEntityLeftEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) {
91 bisector_end_set(p);
92 }
94 void
95 KnotHolderEntityRightEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) {
96 bisector_end_set(p, false);
97 }
99 } //namescape PB
101 LPEPerpBisector::LPEPerpBisector(LivePathEffectObject *lpeobject) :
102 Effect(lpeobject),
103 length_left(_("Length left"), _("Specifies the left end of the bisector"), "length-left", &wr, this, 200),
104 length_right(_("Length right"), _("Specifies the right end of the bisector"), "length-right", &wr, this, 200),
105 A(0,0), B(0,0), M(0,0), C(0,0), D(0,0), perp_dir(0,0)
106 {
107 show_orig_path = true;
109 // register all your parameters here, so Inkscape knows which parameters this effect has:
110 registerParameter( dynamic_cast<Parameter *>(&length_left) );
111 registerParameter( dynamic_cast<Parameter *>(&length_right) );
113 registerKnotHolderHandle(new PB::KnotHolderEntityLeftEnd(), _("Adjust the bisector's \"left\" end"));
114 registerKnotHolderHandle(new PB::KnotHolderEntityRightEnd(), _("Adjust the bisector's \"right\" end"));
115 }
117 LPEPerpBisector::~LPEPerpBisector()
118 {
119 }
121 void
122 LPEPerpBisector::doOnApply (SPLPEItem */*lpeitem*/)
123 {
124 /* make the path a straight line */
125 /**
126 SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()?
128 Geom::Point A(curve->first_point());
129 Geom::Point B(curve->last_point());
131 SPCurve *c = new SPCurve();
132 c->moveto(A);
133 c->lineto(B);
134 // TODO: Why doesn't sp_path_set_original_curve(SP_PATH(lpeitem), c, TRUE, true) work?
135 SP_PATH(lpeitem)->original_curve = c->ref();
136 c->unref();
137 **/
138 }
141 Geom::Piecewise<Geom::D2<Geom::SBasis> >
142 LPEPerpBisector::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
143 {
144 using namespace Geom;
146 Piecewise<D2<SBasis> > output;
148 A = pwd2_in.firstValue();
149 B = pwd2_in.lastValue();
150 M = (A + B)/2;
152 perp_dir = unit_vector((B - A).ccw());
154 C = M + perp_dir * length_left;
155 D = M - perp_dir * length_right;
157 output = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(C[X], D[X]), Linear(C[Y], D[Y])));
159 return output;
160 }
162 /* ######################## */
164 } //namespace LivePathEffect
165 } /* namespace Inkscape */
167 /*
168 Local Variables:
169 mode:c++
170 c-file-style:"stroustrup"
171 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
172 indent-tabs-mode:nil
173 fill-column:99
174 End:
175 */
176 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :