50 (
double)((
rgb & 0x00FF0000) >> 16) / 255.0,
51 (
double)((
rgb & 0x0000FF00) >> 8) / 255.0,
58 cairo_set_font_size(
c, 12);
60 cairo_show_text(
c, text);
65 std::ostringstream ss;
73 double const dist =
distance(from, to);
74 auto angle =
atan2(to - from);
75 bool sweep = std::abs(angle) > M_PI_2;
77 angle = std::fmod(angle, 2.0 * M_PI);
93 void setPath(
Path &&new_path)
95 _path = std::forward<Path>(new_path);
96 std::ostringstream oss;
103 cairo_set_line_width(cr, 2);
107 _drawBezierTangents(cr);
108 _drawSelfIntersections(cr);
116 std::string
const& getSVGD()
const {
return _d; }
119 void _drawBezierTangents(
cairo_t *
c)
const
121 cairo_set_line_width(
c, 1);
124 for (
auto const &
curve : _path) {
126 if (bezier->order() > 1) {
127 auto points = bezier->controlPoints();
139 void _drawSelfIntersections(
cairo_t *cr)
const
142 for (
auto const &xing : _path.intersectSelf()) {
150class AutoCross :
public Toy
156 bezier_handles.pts = { {200, 400}, {100, 300}, {300, 400}, {300, 300}, {450, 300}, {500, 500}, {400, 400} };
157 elliptical_handles.pts = { {500, 200}, {700, 400}, {600, 500} };
158 mixed_handles.pts = { {100, 600}, {120, 690}, {300, 650}, {330, 600}, {500, 800} };
159 handles.push_back(&bezier_handles);
160 handles.push_back(&elliptical_handles);
161 handles.push_back(&mixed_handles);
165 std::ostringstream *timer_stream)
override
181 void key_hit(
unsigned keyval,
unsigned modifiers)
override
183 if (keyval == GDK_KEY_space) {
185 }
else if ((keyval == GDK_KEY_V || keyval == GDK_KEY_v) && (modifiers & GDK_CONTROL_MASK)) {
192 std::vector<Item>
items;
194 bool crashed =
false;
207 std::cerr <<
"Error pasting path d: " << error.
what() << std::endl;
213 Item paste_item{
RED};
214 paste_item.setPath(std::move(pv[0]));
215 items.push_back(paste_item);
222 std::cout <<
"Path snapshots:\n";
223 for (
auto it =
items.rbegin(); it !=
items.rend(); ++it) {
224 std::cout << it->getSVGD() <<
'\n';
228 void refresh_geometry()
231 auto const &cp = bezier_handles.
pts;
235 items[0].setPath(std::move(bezier));
238 auto const &ae = elliptical_handles.
pts;
242 items[1].setPath(std::move(elliptical));
245 auto const &mh = mixed_handles.
pts;
250 items[2].setPath(std::move(mixed));
262 text_pos -=
Point(0, 20);
269 cairo_set_font_size(
c, 30);
271 cairo_show_text(
c,
"Self-intersection of paths in lib2geom!");
272 cairo_set_font_size(
c, 14);
274 cairo_show_text(
c,
"[Space]: Print SVG 'd' attributes to stdout");
276 cairo_show_text(
c,
"[Ctrl-V]: Paste a 'd' attribute from clipboard");
286 cairo_close_path(cr);
287 cairo_set_source_rgb(cr, 1, 0, 0);
294 cairo_close_path(cr);
295 cairo_set_source_rgb(cr, 1, 0, 0);
299 cairo_show_text(cr,
"Sorry, your toy has just broken :-/");
301 cairo_show_text(cr, error.c_str());
307 auto toy = AutoCross();
308 init(argc, argv, &toy, 800, 800);
Path - a sequence of contiguous curves.
static void write_text(cairo_t *c, const char *text, Point const &position, Color color)
static std::string format_point(Point const &pt)
static void set_cairo_rgb(cairo_t *c, Color rgb)
static EllipticalArc random_arc(Point from, Point to)
Bezier curve with compile-time specified order.
Two-dimensional Bezier curve of arbitrary order.
Base exception class, all 2geom exceptions should be derived from this one.
const char * what() const noexcept override
bool empty() const
Check whether the vector contains any paths.
Sequence of contiguous curves, aka spline.
void close(bool closed=true)
Set whether the path is closed.
void append(Curve *curve)
Add a new curve to the end of the path.
Two-dimensional point that doubles as a vector.
std::vector< Geom::Point > pts
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
vector< Handle * > handles
virtual void save(FILE *f)
virtual void key_hit(unsigned keyval, unsigned modifiers)
virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream)
void draw(cairo_t *cr, xAx C, Rect bnd)
void parse_svg_path(char const *str, PathSink &sink)
Feed SVG path data to the specified sink.
Various utility functions.
Angle distance(Angle const &a, Angle const &b)
double atan2(Point const &p)
void cairo_line_to(cairo_t *cr, Geom::Point p1)
void draw_cross(cairo_t *cr, Geom::Point h)
void cairo_path(cairo_t *cr, Geom::Path const &p)
void cairo_move_to(cairo_t *cr, Geom::Point p1)
char const * what() const noexcept override
parse SVG path specifications
void cairo_set_source_rgba(cairo_t *cr, colour c)
void get_clipboard_text(std::function< void(char const *)> &&on_completion)
void init(int argc, char **argv, Toy *t, int width=600, int height=600)