1 #include <2geom/d2.h>
2 #include <2geom/sbasis.h>
3 
4 #include <2geom/path.h>
5 #include <2geom/pathvector.h>
6 #include <2geom/svg-path-parser.h>
7 
8 #include <toys/path-cairo.h>
9 #include <toys/toy-framework-2.h>
10 #include <2geom/transforms.h>
11 #include <2geom/sbasis-geometric.h>
12 #include <2geom/sbasis-to-bezier.h>
13 #include <2geom/sbasis-math.h>
14 
15 #include <cstdlib>
16 
17 using namespace Geom;
18 
sore_tooth(Interval intv)19 Piecewise<SBasis > sore_tooth(Interval intv) {
20     Piecewise<SBasis >  out;
21     double t = intv.min();
22     Point p(0,0);
23     out.push_cut(0);
24     double r = 20;
25     double dir = 0.5;
26     while(t < intv.max()) {
27         double nt = t + 10;
28         if(nt > intv.max())
29             nt = intv.max();
30         SBasis zag(r*Linear(dir,-dir));
31         out.push(zag, nt);
32         t = nt;
33         dir = -dir;
34     }
35     return out;
36 }
37 
zaggy(Interval intv,double dt,double radius)38 Piecewise< D2<SBasis> > zaggy(Interval intv, double dt, double radius) {
39     Piecewise<D2<SBasis> >  out;
40     double t = intv.min();
41     Point p(0,0);
42     out.push_cut(0);
43     while(t < intv.max()) {
44         double nt = t + uniform()*dt;
45         if(nt > intv.max())
46             nt = intv.max();
47         Point np = Point((uniform()-0.5)*2*radius, (uniform()-0.5)*2*radius);
48         D2<SBasis> zag(SBasis(p[0],np[0]), SBasis(p[1],np[1]));
49         p = np;
50         //std::cout << t <<","<< nt << p << np << std::endl;
51         out.push(zag, nt);
52         t = nt;
53     }
54     return out;
55 }
56 
57 
58 class BoolOps: public Toy {
59     PathVector pv;
60     PointHandle offset_handle;
draw(cairo_t * cr,std::ostringstream * notify,int width,int height,bool save,std::ostringstream * timer_stream)61     virtual void draw(cairo_t *cr, std::ostringstream *notify, int width, int height, bool save, std::ostringstream *timer_stream) {
62         Geom::Translate t(offset_handle.pos);
63 
64         cairo_set_line_width(cr, 1);
65         cairo_set_source_rgb(cr, 0.75,0.75,1);
66 
67         //cairo_shape(cr, bst);
68         cairo_path(cr, pv*t);
69         cairo_stroke(cr);
70 
71         cairo_set_source_rgb(cr, 0,0,0);
72 	for(unsigned i = 0; i < pv.size(); i++) {
73 	  Piecewise<D2<SBasis> > B = pv[i].toPwSb();
74 	  Piecewise<D2<SBasis> > n = rot90(unitVector(derivative(B)));
75 	  Piecewise<SBasis > al = arcLengthSb(B);
76 
77 #if 0
78 	  Piecewise<D2<SBasis> > offset_curve = Piecewise<D2<SBasis> >(B)+n*offset;
79 	  PathVector offset_path = path_from_piecewise(offset_curve, 0.1);
80 
81 	  cairo_path(cr, offset_path*t);
82 	  cairo_stroke(cr);
83 #endif
84 	  //Piecewise<D2<SBasis> > zz_curve = B+zaggy(B.domain(), 0.1, 20);//al*n;
85 	  //Piecewise<D2<SBasis> > zz_curve = Piecewise<D2<SBasis> >(B)+
86 	  //    compose(sore_tooth(Interval(al.firstValue(),al.lastValue())), al)*n;
87 	  Piecewise<D2<SBasis> > zz_curve = Piecewise<D2<SBasis> >(B)+
88 	      sin(al*0.1)*10*n;
89 	  PathVector zz_path = path_from_piecewise(zz_curve, 0.1);
90 
91 	  cairo_path(cr, zz_path*t);
92 	  cairo_stroke(cr);
93 	}
94         for(unsigned i = 0; i < pv.size(); i++) {
95             if(pv[i].size() == 0) {
96                 *notify << "naked moveto;";
97             } else
98             for(unsigned j = 0; j < pv[i].size(); j++) {
99                 const Curve* c = &pv[i][j];
100                 *notify << typeid(*c).name() << ';' ;
101             }
102         }
103 
104         Toy::draw(cr, notify, width, height, save,timer_stream);
105     }
106     public:
BoolOps()107     BoolOps () {}
108 
first_time(int argc,char ** argv)109     void first_time(int argc, char** argv) {
110         const char *path_b_name="star.svgd";
111         if(argc > 1)
112             path_b_name = argv[1];
113         pv = read_svgd(path_b_name);
114         std::cout << pv.size() << "\n";
115         std::cout << pv[0].size() << "\n";
116         pv *= Translate(-pv[0].initialPoint());
117 
118         Rect bounds = *pv[0].boundsExact();
119         handles.push_back(&offset_handle);
120         offset_handle.pos = bounds.midpoint() - bounds.corner(0);
121 
122         //bs = cleanup(pv);
123     }
124 };
125 
main(int argc,char ** argv)126 int main(int argc, char **argv) {
127     init(argc, argv, new BoolOps());
128     return 0;
129 }
130 
131 /*
132   Local Variables:
133   mode:c++
134   c-file-style:"stroustrup"
135   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
136   indent-tabs-mode:nil
137   fill-column:99
138   End:
139 */
140 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:fileencoding=utf-8:textwidth=99 :
141