Code

da2b9d6a92c96a1b74fbbad1d7b68270e25243f1
[inkscape.git] / src / live_effects / lpe-powerstroke.cpp
1 #define INKSCAPE_LPE_POWERSTROKE_CPP
2 /** \file
3  * @brief  PowerStroke LPE implementation. Creates curves with modifiable stroke width.
4  */
5 /* Authors:
6  *   Johan Engelen <j.b.c.engelen@utwente.nl>
7  *
8  * Copyright (C) 2010 Authors
9  *
10  * Released under GNU GPL, read the file 'COPYING' for more information
11  */
13 #include "live_effects/lpe-powerstroke.h"
15 #include "sp-shape.h"
16 #include "display/curve.h"
18 #include <2geom/path.h>
19 #include <2geom/piecewise.h>
20 #include <2geom/sbasis-geometric.h>
21 #include <2geom/svg-elliptical-arc.h>
22 #include <2geom/transforms.h>
24 namespace Inkscape {
25 namespace LivePathEffect {
27 LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) :
28     Effect(lpeobject),
29     offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this)
30 {
31     show_orig_path = true;
33     registerParameter( dynamic_cast<Parameter *>(&offset_points) );
34 }
36 LPEPowerStroke::~LPEPowerStroke()
37 {
39 }
42 void
43 LPEPowerStroke::doOnApply(SPLPEItem *lpeitem)
44 {
45     std::vector<Geom::Point> points;
46     points.push_back( *(SP_SHAPE(lpeitem)->curve->first_point()) );
47     Geom::Path const *path = SP_SHAPE(lpeitem)->curve->first_path();
48     points.push_back( path->pointAt(path->size()/2) );
49     points.push_back( *(SP_SHAPE(lpeitem)->curve->last_point()) );
50     offset_points.param_set_and_write_new_value(points);
51 }
53 static void append_half_circle(Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2,
54                                Geom::Point const center, Geom::Point const &dir) {
55     using namespace Geom;
57     double r = L2(dir);
58     SVGEllipticalArc cap(center + dir, r, r, angle_between(Point(1,0), dir), false, false, center - dir);
59     Piecewise<D2<SBasis> > cap_pwd2(cap.toSBasis());
60     pwd2.continuousConcat(cap_pwd2);
61 }
63 Geom::Piecewise<Geom::D2<Geom::SBasis> >
64 LPEPowerStroke::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
65 {
66     using namespace Geom;
68     std::vector<Geom::Point> ts(offset_points.data().size());
70     for (unsigned int i; i < ts.size(); ++i) {
71         double t = nearest_point(offset_points.data().at(i), pwd2_in);
72         double offset = L2(pwd2_in.valueAt(t) - offset_points.data().at(i));
73         ts.at(i) = Geom::Point(t, offset);
74     }
76     // create stroke path where points (x,y) = (t, offset)
77     Path strokepath;
78     strokepath.start( Point(pwd2_in.domain().min(),0) );
79     for (unsigned int i = 0 ; i < ts.size(); ++i) {
80         strokepath.appendNew<Geom::LineSegment>(ts.at(i));
81     }
82     strokepath.appendNew<Geom::LineSegment>( Point(pwd2_in.domain().max(), 0) );
83     for (unsigned int i = 0; i < ts.size(); ++i) {
84         Geom::Point temp = ts.at(ts.size() - 1 - i);
85         strokepath.appendNew<Geom::LineSegment>( Geom::Point(temp[X], - temp[Y]) );
86     }
87     strokepath.close();
89     D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(strokepath.toPwSb());
90     Piecewise<SBasis> x = Piecewise<SBasis>(patternd2[0]);
91     Piecewise<SBasis> y = Piecewise<SBasis>(patternd2[1]);
93     Piecewise<D2<SBasis> > der = unitVector(derivative(pwd2_in));
94     Piecewise<D2<SBasis> > n   = rot90(der);
96 //    output  = pwd2_in + n * offset;
97 //    append_half_circle(output, pwd2_in.lastValue(), n.lastValue() * offset);
98 //    output.continuousConcat(reverse(pwd2_in - n * offset));
99 //    append_half_circle(output, pwd2_in.firstValue(), -n.firstValue() * offset);
101     Piecewise<D2<SBasis> > output = compose(pwd2_in,x) + y*compose(n,x);
102     return output;
105 /* ######################## */
107 } //namespace LivePathEffect
108 } /* namespace Inkscape */
110 /*
111   Local Variables:
112   mode:c++
113   c-file-style:"stroustrup"
114   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
115   indent-tabs-mode:nil
116   fill-column:99
117   End:
118 */
119 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :