Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
sanitize.cpp
Go to the documentation of this file.
1#include <toys/path-cairo.h>
4#include <2geom/utils.h>
5#include <cstdlib>
6#include <2geom/crossing.h>
8#include <2geom/transforms.h>
10#include <2geom/d2.h>
11#include <2geom/sbasis.h>
12#include <2geom/pathvector.h>
13
14using namespace Geom;
15
16struct EndPoint {
17 public:
18 Point point, norm;
19 double time;
20 EndPoint() : time(0) { }
21 EndPoint(Point p, Point n, double t) : point(p), norm(n), time(t) { }
22};
23
24struct Edge {
25 public:
26 EndPoint from, to;
27 int ix;
28 bool cw;
29 Edge() { }
30 Edge(EndPoint f, EndPoint t, int i, bool c) : from(f), to(t), ix(i), cw(c) { }
31 bool operator==(Edge const &other) const { return from.time == other.from.time && to.time == other.to.time; }
32};
33
34typedef std::vector<Edge> Edges;
35
36Edges edges(Path const &p, Crossings const &cr, unsigned ix) {
37 Edges ret = Edges();
38 EndPoint prev;
39 for(unsigned i = 0; i <= cr.size(); i++) {
40 double t = cr[i == cr.size() ? 0 : i].getTime(ix);
41 Point pnt = p.pointAt(t);
42 Point normal = p.pointAt(t+0.01) - pnt;
43 normal.normalize();
44 std::cout << pnt << "\n";
45 EndPoint cur(pnt, normal, t);
46 if(i == 0) { prev = cur; continue; }
47 ret.push_back(Edge(prev, cur, ix, false));
48 ret.push_back(Edge(prev, cur, ix, true));
49 prev = cur;
50 }
51 return ret;
52}
53
54template<class T>
55void append(std::vector<T> &vec, std::vector<T> const &other) {
56 vec.insert(vec.end(),other.begin(), other.end());
57}
58
59Edges edges(PathVector const &ps, CrossingSet const &crs) {
60 Edges ret = Edges();
61 for(unsigned i = 0; i < crs.size(); i++) {
62 Edges temp = edges(ps[i], crs[i], i);
63 append(ret, temp);
64 }
65 return ret;
66}
67
69 PathVector ret;
70 for(const auto & e : es) {
71 ret.push_back(ps[e.ix].portion(e.from.time, e.to.time));
72 }
73 return ret;
74}
75
76void draw_cell(cairo_t *cr, Edges const &es, PathVector const &ps) {
78 cairo_set_line_width(cr, uniform() * 10);
81 double area;
82 Point centre;
83 Geom::centroid(pw, centre, area);
84 cairo_path(cr, paths); //* (Translate(-centre) * Scale(0.2) * Translate(centre*2)));
85 cairo_stroke(cr);
86}
87
88//Only works for normal
89double ang(Point n1, Point n2) {
90 return (dot(n1, n2)+1) * (cross(n1, n2) < 0 ? -1 : 1);
91}
92
93template<class T>
94void remove(std::vector<T> &vec, T const &val) {
95 for (typename std::vector<T>::iterator it = vec.begin(); it != vec.end(); ++it) {
96 if(*it == val) {
97 vec.erase(it);
98 return;
99 }
100 }
101}
102
103std::vector<Edges> cells(cairo_t */*cr*/, PathVector const &ps) {
105 Edges es = edges(ps, crs);
106 std::vector<Edges> ret = std::vector<Edges>();
107
108 while(!es.empty()) {
109 std::cout << "hello!\n";
110 Edge start = es.front();
111 Path p = Path();
112 Edge cur = start;
113 bool rev = false;
114 Edges cell = Edges();
115 do {
116 std::cout << rev << " " << cur.from.time << ", " << cur.to.time << "\n";
117 double a = 0;
118 Edge was = cur;
119 EndPoint curpnt = rev ? cur.from : cur.to;
120 Point norm = rev ? -curpnt.norm : curpnt.norm;
121 //Point to = curpnt.point + norm *20;
122
123 //std::cout << norm;
124 for(auto & e : es) {
125 if(e == was || e.cw != start.cw) continue;
126 if((!are_near(curpnt.time, e.from.time)) &&
127 are_near(curpnt.point, e.from.point, 0.1)) {
128 double v = ang(norm, e.from.norm);
129 //draw_line_seg(cr, curpnt.point, to);
130 //draw_line_seg(cr, to, es[i].from.point + es[i].from.norm*30);
131 //std::cout << v << "\n";
132 if(start.cw ? v < a : v > a ) {
133 a = v;
134 cur = e;
135 rev = false;
136 }
137 }
138 if((!are_near(curpnt.time, e.to.time)) &&
139 are_near(curpnt.point, e.to.point, 0.1)) {
140 double v = ang(norm, -e.to.norm);
141 if(start.cw ? v < a : v > a) {
142 a = v;
143 cur = e;
144 rev = true;
145 }
146 }
147 }
148 cell.push_back(cur);
149 remove(es, cur);
150 if(cur == was) break;
151 } while(!(cur == start));
152 if(are_near(start.to.point, rev ? cur.from.point : cur.to.point)) {
153 ret.push_back(cell);
154 }
155 }
156 return ret;
157}
158
159int cellWinding(Edges const &/*es*/, PathVector const &/*ps*/) {
160 return 0;
161}
162
163class Sanitize: public Toy {
165 std::vector<Edges> es;
166 PointSetHandle angh;
167 PointSetHandle pathix;
168 void draw(cairo_t *cr, std::ostringstream *notify, int width, int height, bool save,
169 std::ostringstream *timer_stream) override
170 {
171 int ix = pathix.pts[0][X] / 10;
172 es = cells(cr, paths);
173 draw_cell(cr, es[ix], paths);
174
175 cairo_set_source_rgba(cr, 0, 0, 0, 1);
176 //cairo_path(cr, paths);
177 //cairo_stroke(cr);
178
179 Point ap = angh.pts[1] - angh.pts[0], bp = angh.pts[2] - angh.pts[0];
180 ap.normalize(); bp.normalize();
181 *notify << ang(ap, bp);
182 Toy::draw(cr, notify, width, height, save,timer_stream);
183 }
184
185 public:
186 Sanitize () {}
187 void first_time(int argc, char** argv) override {
188 const char *path_name="sanitize_examples.svgd";
189 if(argc > 1)
190 path_name = argv[1];
191 paths = read_svgd(path_name);
192
193 handles.push_back(&angh); handles.push_back(&pathix);
194 angh.push_back(100, 100);
195 angh.push_back(80, 100);
196 angh.push_back(100, 80);
197 pathix.push_back(30, 200);
198 }
199};
200
201int main(int argc, char **argv) {
202 init(argc, argv, new Sanitize());
203 return 0;
204}
Various utility functions.
int main()
Sequence of subpaths.
Definition pathvector.h:122
void push_back(Path const &path)
Append a path at the end.
Definition pathvector.h:172
Sequence of contiguous curves, aka spline.
Definition path.h:353
Point pointAt(Coord t) const
Get the point at the specified time value.
Definition path.cpp:449
Function defined as discrete pieces.
Definition piecewise.h:71
Two-dimensional point that doubles as a vector.
Definition point.h:66
void normalize()
Normalize the vector representing the point.
Definition point.cpp:96
constexpr Point cw() const
Return a point like this point but rotated +90 degrees.
Definition point.h:137
void push_back(double x, double y)
std::vector< Geom::Point > pts
virtual void first_time(int, char **)
vector< Handle * > handles
virtual void save(FILE *f)
virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream)
vector< Edge > es
Structure representing the intersection of two curves.
double c[8][4]
Lifts one dimensional objects into 2D.
PathVector read_svgd(char const *filename)
Create path vector from SVG path data stored in a file.
@ X
Definition coord.h:48
Geom::Point start
vector< vector< Point > > paths
Definition metro.cpp:36
Various utility functions.
Definition affine.h:22
Piecewise< D2< SBasis > > paths_to_pw(PathVector const &paths)
Definition path.cpp:1123
void append(T &a, T const &b)
A little sugar for appending a list to another.
int centroid(std::vector< Geom::Point > const &p, Geom::Point &centroid, double &area)
polyCentroid: Calculates the centroid (xCentroid, yCentroid) and area of a polygon,...
Definition geom.cpp:366
static double area(Geom::Point a, Geom::Point b, Geom::Point c)
CrossingSet crossings_among(PathVector const &p)
std::vector< Crossing > Crossings
Definition crossing.h:126
std::vector< Crossings > CrossingSet
Definition crossing.h:128
Piecewise< SBasis > cross(Piecewise< D2< SBasis > > const &a, Piecewise< D2< SBasis > > const &b)
T dot(D2< T > const &a, D2< T > const &b)
Definition d2.h:355
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
bool operator==(D2< T > const &a, D2< T > const &b)
Definition d2.h:177
gdouble norm(const Fvector &v)
returns the euclidean norm of the vector v
int n
Definition spiro.cpp:57
std::pair< unsigned, unsigned > Edge
Edges are simply a pair of indices to entries in the Node vector.
Definition cola.h:68
struct _cairo cairo_t
Definition path-cairo.h:16
void cairo_path(cairo_t *cr, Geom::Path const &p)
Path intersection.
PathVector - a sequence of subpaths.
unsigned n1
unsigned n2
void remove(std::vector< T > &vec, T const &val)
Definition sanitize.cpp:94
void draw_cell(cairo_t *cr, Edges const &es, PathVector const &ps)
Definition sanitize.cpp:76
PathVector edges_to_paths(Edges const &es, PathVector const &ps)
Definition sanitize.cpp:68
std::vector< Edge > Edges
Definition sanitize.cpp:34
int cellWinding(Edges const &, PathVector const &)
Definition sanitize.cpp:159
Edges edges(Path const &p, Crossings const &cr, unsigned ix)
Definition sanitize.cpp:36
std::vector< Edges > cells(cairo_t *, PathVector const &ps)
Definition sanitize.cpp:103
double ang(Point n1, Point n2)
Definition sanitize.cpp:89
two-dimensional geometric operators.
Polynomial in symmetric power basis (S-basis)
parse SVG path specifications
double height
double width
double uniform()
void cairo_set_source_rgba(cairo_t *cr, colour c)
void init(int argc, char **argv, Toy *t, int width=600, int height=600)
Affine transformation classes.