Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
lpe-tangent_to_curve.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
6/*
7 * Authors:
8 * Johan Engelen
9 * Maximilian Albert
10 *
11 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
12 * Copyright (C) Maximilian Albert 2008 <maximilian.albert@gmail.com>
13 *
14 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
15 */
16
18
19#include "display/curve.h"
20
21#include "object/sp-shape.h"
23#include "ui/knot/knot-holder.h"
25
26// TODO due to internal breakage in glibmm headers, this must be last:
27#include <glibmm/i18n.h>
28
29namespace Inkscape {
30namespace LivePathEffect {
31
32namespace TtC {
33
34class KnotHolderEntityAttachPt : public LPEKnotHolderEntity {
35public:
36 KnotHolderEntityAttachPt(LPETangentToCurve *effect) : LPEKnotHolderEntity(effect) {};
37 void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) override;
38 Geom::Point knot_get() const override;
39};
40
41class KnotHolderEntityLeftEnd : public LPEKnotHolderEntity {
42public:
43 KnotHolderEntityLeftEnd(LPETangentToCurve *effect) : LPEKnotHolderEntity(effect) {};
44 void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) override;
45 Geom::Point knot_get() const override;
46};
47
48class KnotHolderEntityRightEnd : public LPEKnotHolderEntity
49{
50public:
51 KnotHolderEntityRightEnd(LPETangentToCurve *effect) : LPEKnotHolderEntity(effect) {};
52 void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) override;
53 Geom::Point knot_get() const override;
54};
55
56} // namespace TtC
57
59 Effect(lpeobject),
60 angle(_("Angle:"), _("Additional angle between tangent and curve"), "angle", &wr, this, 0.0),
61 t_attach(_("Location along curve:"), _("Location of the point of attachment along the curve (between 0.0 and number-of-segments)"), "t_attach", &wr, this, 0.5),
62 length_left(_("Length left:"), _("Specifies the left end of the tangent"), "length-left", &wr, this, 150),
63 length_right(_("Length right:"), _("Specifies the right end of the tangent"), "length-right", &wr, this, 150)
64{
65 show_orig_path = true;
67
72}
73
75
78{
79 using namespace Geom;
80 Piecewise<D2<SBasis> > output;
81
82 ptA = pwd2_in.valueAt(t_attach);
83 derivA = unit_vector(derivative(pwd2_in).valueAt(t_attach));
84
85 // TODO: Why are positive angles measured clockwise, not counterclockwise?
87 derivA = derivA * rot;
88
89 C = ptA - derivA * length_left;
91
92 output = Piecewise<D2<SBasis> >(D2<SBasis>(SBasis(C[X], D[X]), SBasis(C[Y], D[Y])));
93
94 return output;
95}
96
97void
99 {
101 e->create(nullptr, item, knotholder, Inkscape::CANVAS_ITEM_CTRL_TYPE_LPE, "LPE:TangentToCurvePT",
102 _("Adjust the point of attachment of the tangent"));
103 knotholder->add(e);
104 }
105 {
107 e->create(nullptr, item, knotholder, Inkscape::CANVAS_ITEM_CTRL_TYPE_LPE, "LPE:TangentToCurveLeftEnd",
108 _("Adjust the <b>left</b> end of the tangent"));
109 knotholder->add(e);
110 }
111 {
113 e->create(nullptr, item, knotholder, Inkscape::CANVAS_ITEM_CTRL_TYPE_LPE, "LPE:TangetToCurveRightEnd",
114 _("Adjust the <b>right</b> end of the tangent"));
115 knotholder->add(e);
116 }
117};
118
119namespace TtC {
120
121void
122KnotHolderEntityAttachPt::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
123{
124 using namespace Geom;
125
126 LPETangentToCurve* lpe = dynamic_cast<LPETangentToCurve *>(_effect);
127
128 Geom::Point const s = snap_knot_position(p, state);
129
130 if ( !is<SPShape>(lpe->sp_lpe_item) ) {
131 //lpe->t_attach.param_set_value(0);
132 g_warning("LPEItem is not a path! %s:%d\n", __FILE__, __LINE__);
133 return;
134 }
136
137 double t0 = nearest_time(s, pwd2);
138 lpe->t_attach.param_set_value(t0);
139
140 // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
141 sp_lpe_item_update_patheffect (cast<SPLPEItem>(item), false, true);
142}
143
144void
145KnotHolderEntityLeftEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
146{
147 LPETangentToCurve *lpe = dynamic_cast<LPETangentToCurve *>(_effect);
148
149 Geom::Point const s = snap_knot_position(p, state);
150
151 double lambda = Geom::nearest_time(s, lpe->ptA, lpe->derivA);
152 lpe->length_left.param_set_value(-lambda);
153
154 sp_lpe_item_update_patheffect (cast<SPLPEItem>(item), false, true);
155}
156
157void
158KnotHolderEntityRightEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
159{
160 LPETangentToCurve *lpe = dynamic_cast<LPETangentToCurve *>(_effect);
161
162 Geom::Point const s = snap_knot_position(p, state);
163
164 double lambda = Geom::nearest_time(s, lpe->ptA, lpe->derivA);
165 lpe->length_right.param_set_value(lambda);
166
167 sp_lpe_item_update_patheffect (cast<SPLPEItem>(item), false, true);
168}
169
171KnotHolderEntityAttachPt::knot_get() const
172{
173 LPETangentToCurve const *lpe = dynamic_cast<LPETangentToCurve const*>(_effect);
174 return lpe->ptA;
175}
176
178KnotHolderEntityLeftEnd::knot_get() const
179{
180 LPETangentToCurve const *lpe = dynamic_cast<LPETangentToCurve const*>(_effect);
181 return lpe->C;
182}
183
185KnotHolderEntityRightEnd::knot_get() const
186{
187 LPETangentToCurve const *lpe = dynamic_cast<LPETangentToCurve const*>(_effect);
188 return lpe->D;
189}
190
191} // namespace TtC
192
193} //namespace LivePathEffect
194} /* namespace Inkscape */
195
196/*
197 Local Variables:
198 mode:c++
199 c-file-style:"stroustrup"
200 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
201 indent-tabs-mode:nil
202 fill-column:99
203 End:
204*/
205// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
Point origin
Definition aa.cpp:227
Adaptor that creates 2D functions from 1D ones.
Definition d2.h:55
Function defined as discrete pieces.
Definition piecewise.h:71
Two-dimensional point that doubles as a vector.
Definition point.h:66
Rotation around the origin.
Definition transforms.h:187
static Rotate from_degrees(Coord deg)
Construct a rotation from its angle in degrees.
Definition transforms.h:218
Polynomial in symmetric power basis.
Definition sbasis.h:70
void registerParameter(Parameter *param)
Definition effect.cpp:1710
Geom::PathVector pathvector_before_effect
Definition effect.h:174
LPETangentToCurve(LivePathEffectObject *lpeobject)
Geom::Piecewise< Geom::D2< Geom::SBasis > > doEffect_pwd2(Geom::Piecewise< Geom::D2< Geom::SBasis > > const &pwd2_in) override
void addKnotHolderEntities(KnotHolder *knotholder, SPItem *item) override
KnotHolderEntity definition.
void create(SPDesktop *desktop, SPItem *item, KnotHolder *parent, Inkscape::CanvasItemCtrlType type=Inkscape::CANVAS_ITEM_CTRL_TYPE_DEFAULT, Glib::ustring const &name="unknown", char const *tip="", uint32_t color=0xffffff00)
void add(KnotHolderEntity *e)
Base class for visual SVG elements.
Definition sp-item.h:109
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
SPItem * item
LPE <tangent_to_curve> implementation, see lpe-tangent_to_curve.cpp.
Various utility functions.
Definition affine.h:22
Piecewise< D2< SBasis > > paths_to_pw(PathVector const &paths)
Definition path.cpp:1123
Coord nearest_time(Point const &p, Curve const &c)
Definition curve.h:354
Bezier derivative(Bezier const &a)
Definition bezier.cpp:282
Point unit_vector(Point const &a)
Helper class to stream background task notifications as a series of messages.
@ CANVAS_ITEM_CTRL_TYPE_LPE
void sp_lpe_item_update_patheffect(SPLPEItem *lpeitem, bool wholetree, bool write, bool with_satellites)
Calls any registered handlers for the update_patheffect action.