Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
ineaa.cpp
Go to the documentation of this file.
1#include <2geom/convex-hull.h>
2
3#include <toys/path-cairo.h>
5#include <2geom/d2.h>
6#include <2geom/geom.h>
8
9#include <aa.h>
10#include <complex>
11#include <algorithm>
12#include <optional>
13
14using std::vector;
15using namespace Geom;
16using namespace std;
17
18typedef std::complex<AAF> CAAF;
19
20struct PtLexCmp{
21 bool operator()(const Point &a, const Point &b) {
22 return (a[0] < b[0]) || ((a[0] == b[0]) and (a[1] < b[1]));
23 }
24};
25
26// draw ax + by + c = 0
27void draw_line_in_rect(cairo_t*cr, Rect &r, Point n, double c) {
28 std::optional<Geom::LineSegment> ls =
29 rect_line_intersect(r, Line::fromNormalDistance(n, c));
30
31 if(ls) {
32 cairo_move_to(cr, (*ls)[0]);
33 cairo_line_to(cr, (*ls)[1]);
34 cairo_stroke(cr);
35
36 }
37}
38
39void fill_line_in_rect(cairo_t*cr, Rect &r, Point n, double c) {
40 ConvexHull ch;
41
42 std::optional<Geom::LineSegment> ls =
43 rect_line_intersect(r, Line::fromNormalDistance(n, c));
44
45 if(ls) {
46 ch.boundary.push_back((*ls)[0]);
47 ch.boundary.push_back((*ls)[1]);
48 }
49 for(int i = 0; i < 4; i++) {
50 Point p = r.corner(i);
51 if(dot(n,p) < c) {
52 ch.boundary.push_back(p);
53 }
54 }
55 ch.graham();
56 cairo_convex_hull(cr, ch.boundary);
57}
58
60 vector<Geom::Point> result;
61 Point resultp;
62 for(int i = 0; i < 4; i++) {
63 Point cnr = r.corner(i);
64 double z = dot(cnr, n);
65 if((z > lu[0]) and (z < lu[1]))
66 result.push_back(cnr);
67 }
68 for(int i = 0; i < 2; i++) {
69 double c = lu[i];
70
71 std::optional<Geom::LineSegment> ls =
72 rect_line_intersect(r, Line::fromNormalDistance(n, c));
73
74 if(ls) {
75 result.push_back((*ls)[0]);
76 result.push_back((*ls)[1]);
77 }
78 }
79 if(result.size() < 2)
80 return OptRect();
81 Rect nr(result[0], result[1]);
82 for(size_t i = 2; i < result.size(); i++) {
83 nr.expandTo(result[i]);
84 }
85 return intersect(nr, r);
86}
87
88AAF ls_sample_based(AAF x, vector<Point> pts) {
89 NL::Matrix m(pts.size(), 2);
90 NL::Vector v(pts.size());
91 NL::LinearSystem ls(m, v);
92
93 m.set_all(0);
94 v.set_all(0);
95 for (unsigned int k = 0; k < pts.size(); ++k)
96 {
97 m(k,0) += pts[k][0];
98 m(k,1) += 1;
99 //std::cout << pts[k] << " ";
100
101 v[k] += pts[k][1];
102 //v[1] += pts[k][1];
103 //v[2] += y2;
104 }
105
106 ls.SV_solve();
107
108 double A = ls.solution()[0];
109 double B = ls.solution()[1];
110 // Ax + B = y
111 Interval bnd(0,0);
112 for (unsigned int k = 0; k < pts.size(); ++k)
113 {
114 bnd.extendTo(A*pts[k][0]+B - pts[k][1]);
115 }
116 //std::cout << A << "," << B << std::endl;
117 return AAF(x, A, B, bnd.extent(),
118 x.special);
119}
120
121AAF md_sample_based(AAF x, vector<Point> pts) {
122 Geom::ConvexHull ch1(pts);
123 Point a, b, c;
124 ch1.narrowest_diameter(a, b, c);
125 Point db = c-b;
126 double A = db[1]/db[0];
127 Point aa = db*(dot(db, a-b)/dot(db,db))+b;
128 Point mid = (a+aa)/2;
129 double B = mid[1] - A*mid[0];
130 double dB = (a[1] - A*a[0]) - B;
131 // Ax + B = y
132 //std::cout << A << "," << B << std::endl;
133 return AAF(x, A, B, dB,
134 x.special);
135}
136
138 interval ab(x);
139 const double a = ab.min(); // [a,b] is our interval
140 const double b = ab.max();
141
142 const double ea = atan(a);
143 const double eb = atan(b);
144 vector<Point> pts;
145 pts.push_back(Point(a,ea));
146 pts.push_back(Point(b,eb));
147 const double alpha = (eb-ea)/(b-a);
148 double xs = sqrt(1/alpha-1);
149 if((a < xs) and (xs < b))
150 pts.push_back(Point(xs,atan(xs)));
151 xs = -xs;
152 if((a < xs) and (xs < b))
153 pts.push_back(Point(xs,atan(xs)));
154
155 return md_sample_based(x, pts);
156}
157
159 interval ab(x);
160 const double a = ab.min(); // [a,b] is our interval
161 const double b = ab.max();
162 AAF_TYPE type;
163 if(a > 0)
164 type = AAF_TYPE_AFFINE;
165 else if(b < 0) { // no point in continuing
166 type = AAF_TYPE_NAN;
167 return AAF(type);
168 }
169 else if(a <= 0) { // undefined, can we do better?
170 type = (AAF_TYPE)(AAF_TYPE_AFFINE | AAF_TYPE_NAN);
171 return AAF(type);
172 // perhaps we should make a = 0+eps and try to continue?
173 }
174
175 const double ea = log(a);
176 const double eb = log(b);
177 vector<Point> pts;
178 pts.push_back(Point(a,ea));
179 pts.push_back(Point(b,eb));
180 const double alpha = (eb-ea)/(b-a);
181 // dlog(xs) = alpha
182 double xs = 1/(alpha);
183 if((a < xs) and (xs < b))
184 pts.push_back(Point(xs,log(xs)));
185
186 return md_sample_based(x, pts);
187}
188
190 interval ab(x);
191 const double a = ab.min(); // [a,b] is our interval
192 const double b = ab.max();
193
194 const double ea = exp(a);
195 const double eb = exp(b);
196 vector<Point> pts;
197 pts.push_back(Point(a,ea));
198 pts.push_back(Point(b,eb));
199 const double alpha = (eb-ea)/(b-a);
200 // dexp(xs) = alpha
201 double xs = log(alpha);
202 if((a < xs) and (xs < b))
203 pts.push_back(Point(xs,exp(xs)));
204
205 return md_sample_based(x, pts);
206}
207
208double
209desy_lambert_W(double x) {
210 if (x <= 500.0) {
211 double lx1 = log(x + 1.0);
212 return 0.665 * (1 + 0.0195 * lx1) * lx1 + 0.04;
213 }
214 return log(x - 4.0) - (1.0 - 1.0/log(x)) * log(log(x));
215}
216
217double lambertW(double x, double prec = 1E-12, int maxiters = 100) {
218 double w = desy_lambert_W(x);
219 const double e = exp(1);
220 for(int i = 0; i < maxiters; i++) {
221 double we = w * pow(e,w);
222 double w1e = (w + 1) * pow(e,w);
223 if( prec > abs((x - we) / w1e))
224 return w;
225 w -= (we - x) / (w1e - (w+2) * (we-x) / (2*w+2));
226 }
227 //raise ValueError("W doesn't converge fast enough for abs(z) = %f" % abs(x))
228 return 0./0.;
229}
230
231#include <gsl/gsl_errno.h>
232#include <gsl/gsl_math.h>
233#include <gsl/gsl_min.h>
234
235typedef struct{
236 double a, b;
237} param_W;
238
239double fn1 (double x, void * params)
240{
241 param_W *pw = (param_W*)params;
242 return (pw->a*x+pw->b) - lambertW(x);
243}
244
245double optimise(void * params, double a, double b) {
246 int status;
247 //param_W *pw = (param_W*)params;
248 int iter = 0, max_iter = 100;
249 double m = (a+b)/2;
250 gsl_function F;
251
252 F.function = &fn1;
253 F.params = params;
254
255 const gsl_min_fminimizer_type *T = gsl_min_fminimizer_brent;
256 gsl_min_fminimizer *s = gsl_min_fminimizer_alloc (T);
257 if(a+1e-10 >= b) return m;
258#if 0
259 cout << a << " " << b << " " << m << endl;
260 cout << "fn:" << fn1(a, params) << " " << fn1(b, params) << " " << fn1(m, params) << endl;
261 cout << "fn:" << (pw->a*a+pw->b) << " " << (pw->a*b+pw->b) << " " << (pw->a*m+pw->b) << endl;
262#endif
263 gsl_min_fminimizer_set (s, &F, m, a, b);
264 do
265 {
266 iter++;
267 status = gsl_min_fminimizer_iterate (s);
268
269 m = gsl_min_fminimizer_x_minimum (s);
270 a = gsl_min_fminimizer_x_lower (s);
271 b = gsl_min_fminimizer_x_upper (s);
272
273 status
274 = gsl_min_test_interval (a, b, 0.001, 0.0);
275
276 }
277 while (status == GSL_CONTINUE && iter < max_iter);
278
279 gsl_min_fminimizer_free (s);
280
281 return m;
282}
283
284
285AAF W_sample_based(AAF x) {
286 interval ab(x);
287 const double a = ab.min(); // [a,b] is our interval
288 const double b = ab.max();
289 const double e = exp(1);
290 AAF_TYPE type;
291 if(a >= -1./e)
292 type = AAF_TYPE_AFFINE;
293 else if(b < 0) { // no point in continuing
294 type = AAF_TYPE_NAN;
295 return AAF(type);
296 }
297 else if(a <= 0) { // undefined, can we do better?
298 type = (AAF_TYPE)(AAF_TYPE_AFFINE | AAF_TYPE_NAN);
299 return AAF(type);
300 // perhaps we should make a = 0+eps and try to continue?
301 }
302 const double ea = lambertW(a);
303 const double eb = lambertW(b);
304 vector<Point> pts;
305 pts.push_back(Point(a,ea));
306 pts.push_back(Point(b,eb));
307 const double alpha = (eb-ea)/(b-a);
308 // d(W(xs)) = alpha
309 // W =
310 param_W pw;
311 pw.a = alpha;
312 pw.b = ea - alpha*a;
313 if(a < b) {
314 double xs = optimise(&pw, a, b);
315 if((a < xs) and (xs < b))
316 pts.push_back(Point(xs,lambertW(xs)));
317 }
318 return md_sample_based(x, pts);
319}
320
321AAF pow_sample_based(AAF x, double p) {
322 interval ab(x);
323 const double a = ab.min(); // [a,b] is our interval
324 const double b = ab.max();
325 AAF_TYPE type;
326 if(floor(p) != p) {
327 if(a >= 0)
328 type = AAF_TYPE_AFFINE;
329 else if(b < 0) { // no point in continuing
330 type = AAF_TYPE_NAN;
331 return AAF(type);
332 }
333 else if(a <= 0) { // undefined, can we do better?
334 type = (AAF_TYPE)(AAF_TYPE_AFFINE | AAF_TYPE_NAN);
335 return AAF(type);
336 // perhaps we should make a = 0+eps and try to continue?
337 }
338 }
339 const double ea = pow(a, p);
340 const double eb = pow(b, p);
341 vector<Point> pts;
342 pts.push_back(Point(a,ea));
343 pts.push_back(Point(b,eb));
344 const double alpha = (eb-ea)/(b-a);
345 // d(xs^p) = alpha
346 // p xs^(p-1) = alpha
347 // xs = (alpha/p)^(1-p)
348 double xs = pow(alpha/p, 1./(p-1));
349 if((a < xs) and (xs < b))
350 pts.push_back(Point(xs,pow(xs, p)));
351 xs = -xs;
352 if((a < xs) and (xs < b))
353 pts.push_back(Point(xs,pow(xs, p)));
354
355 return md_sample_based(x, pts);
356}
357
359AAF trial_eval(AAF x, AAF y) {
360 x = x-origin[0];
361 y = y-origin[1];
362 x = x/200;
363 y = y/200;
364 AAF x2 = pow_sample_based(x,2);
365 AAF y2 = pow_sample_based(y,2);
366 //return x2 + y2 - 1;
367 //return y - pow(x,3);
368 return y + W_sample_based(x);
369 //return y - pow_sample_based(x,2.5);
370 //return y - log_sample_based(x);
371 //return y - log(x);
372 //return -y + -exp_sample_based(x*log(x));
373 return -x + -exp_sample_based(y*log(y));
374 //return y - sqrt(sin(x));
375 //return sqrt(y)*x - sqrt(x) - y - 1;
376 //return y-1/x;
377 //return exp(x)-y;
378 //return sin(x)-y;
379 //return exp_sample_based(x)-y;
380 //return atan(x)-y;
381 //return atan_sample_based(x)-y;
382 //return atanh(x)-y;
383 //return x*y;
384 //return 4*x+3*y-1;
385 //return x*x + y*y - 1;
386 return pow_sample_based((x2 + y2), 2) - (x2-y2);
387 //return x*x-y;
388 //return (x*x*x-y*x)*sin(x) + (x-y*y)*cos(y)-0.5;
389}
390
391AAF xaxis(AAF x, AAF y) {
392 (void)x;
393 y = y-origin[1];
394 y = y/200;
395 return y;
396}
397
398AAF yaxis(AAF x, AAF y) {
399 (void)y;
400 x = x-origin[0];
401 x = x/200;
402 return x;
403}
404
405class ConvexTest: public Toy {
406public:
407 PointSetHandle test_window;
408 PointSetHandle samples;
409 PointHandle orig_handle;
410 ConvexTest () {
411 toggles.push_back(Toggle("Show trials", false));
412 handles.push_back(&test_window);
413 handles.push_back(&samples);
414 handles.push_back(&orig_handle);
415 orig_handle.pos = Point(00,300);
416 test_window.push_back(Point(100,100));
417 test_window.push_back(Point(200,200));
418 for(int i = 0; i < 0; i++) {
419 samples.push_back(Point(i*100, i*100+25));
420 }
421 }
422 int iters;
423 int splits[4];
424 bool show_splits;
425 std::vector<Toggle> toggles;
426 AAF (*eval)(AAF, AAF);
427 void recursive_implicit(Rect r, cairo_t*cr, double w) {
428 if(show_splits) {
429 cairo_save(cr);
430 cairo_set_line_width(cr, 0.3);
431 /*if(f.is_partial())
432 cairo_set_source_rgba(cr, 1, 0, 1, 0.25);
433 else*/
434 cairo_set_source_rgba(cr, 0, 1, 0, 0.25);
435 cairo_rectangle(cr, r);
436 cairo_stroke(cr);
437 cairo_restore(cr);
438 }
439 iters++;
440 AAF x(interval(r.left(), r.right()));
441 AAF y(interval(r.top(), r.bottom()));
442 //assert(x.rad() > 0);
443 //assert(y.rad() > 0);
444 AAF f = (*eval)(x, y);
445 double a = f.index_coeff(x.get_index(0))/x.index_coeff(x.get_index(0));
446 double b = f.index_coeff(y.get_index(0))/y.index_coeff(y.get_index(0));
447 AAF d = a*x + b*y - f;
448 interval ivl(d);
449 Point n(a,b);
450 OptRect out = tighten(r, n, Interval(ivl.min(), ivl.max()));
451 if(ivl.extent() < 0.5*L2(n)) {
452
453 cairo_save(cr);
454 cairo_set_source_rgba(cr, 0,1,0,0.125);
455 fill_line_in_rect(cr, r, n, ivl.middle());
456 cairo_fill(cr);
457 cairo_restore(cr);
458 draw_line_in_rect(cr, r, n, ivl.middle());
459 return;
460 }
461 if(f.strictly_neg()) {
462 cairo_save(cr);
463 cairo_set_source_rgba(cr, 0,1,0,0.125);
464 cairo_rectangle(cr, r);
465 cairo_fill(cr);
466 cairo_restore(cr);
467 return;
468 }
469 if(!f.is_partial() and f.is_indeterminate()) {
470 cairo_save(cr);
471 cairo_set_line_width(cr, 0.3);
472 if(f.is_infinite()) {
473 cairo_set_source_rgb(cr, 1, 0.5, 0.5);
474 } else if(f.is_nan()) {
475 cairo_set_source_rgb(cr, 1, 1, 0);
476 } else {
477 cairo_set_source_rgb(cr, 1, 0, 0);
478 }
479 cairo_rectangle(cr, r);
480 if(show_splits) {
481 cairo_stroke(cr);
482 } else {
483 cairo_fill(cr);
484 }
485 cairo_restore(cr);
486 return;
487 }
488
489 if((r.width() > w) or (r.height()>w)) {
490 if(f.strictly_neg() or f.straddles_zero()) {
491 // Three possibilities:
492 // 1) the trim operation buys us enough that we should just iterate
493 Point c = r.midpoint();
494 Rect oldr = r;
495 if(1 && out) {
496 r = *out;
497 for(int i = 0; i < 4; i++) {
498 Point p = oldr.corner(i);
499 if(dot(n,p) < ivl.middle()) {
500 r.expandTo(p);
501 }
502 }
503 }
504 if(1 && out && (r.area() < oldr.area()*0.25)) {
505 splits[0] ++;
506 recursive_implicit(r, cr, w);
507 // 2) one dimension is significantly smaller
508 } else if(1 && (r[1].extent() < oldr[1].extent()*0.5)) {
509 splits[1]++;
510 recursive_implicit(Rect(Interval(r.left(), r.right()),
511 Interval(r.top(), c[1])), cr,w);
512 recursive_implicit(Rect(Interval(r.left(), r.right()),
513 Interval(c[1], r.bottom())), cr,w);
514 } else if(1 && (r[0].extent() < oldr[0].extent()*0.5)) {
515 splits[2]++;
516 recursive_implicit(Rect(Interval(r.left(), c[0]),
517 Interval(r.top(), r.bottom())), cr,w);
518 recursive_implicit(Rect(Interval(c[0], r.right()),
519 Interval(r.top(), r.bottom())), cr,w);
520 // 3) to ensure progress we must do a four way split
521 } else {
522 splits[3]++;
523 recursive_implicit(Rect(Interval(r.left(), c[0]),
524 Interval(r.top(), c[1])), cr,w);
525 recursive_implicit(Rect(Interval(c[0], r.right()),
526 Interval(r.top(), c[1])), cr,w);
527 recursive_implicit(Rect(Interval(r.left(), c[0]),
528 Interval(c[1], r.bottom())), cr,w);
529 recursive_implicit(Rect(Interval(c[0], r.right()),
530 Interval(c[1], r.bottom())), cr,w);
531 }
532 }
533 } else {
534 }
535 }
536
537 void key_hit(unsigned keyval, unsigned modifiers) override {
538 if(keyval == 'w') toggles[0].toggle(); else
539 if(keyval == 'a') toggles[1].toggle(); else
540 if(keyval == 'q') toggles[2].toggle(); else
541 if(keyval == 's') toggles[3].toggle();
542 redraw();
543 }
544 void mouse_pressed(Geom::Point const &pos, unsigned button, unsigned modifiers) override {
545 toggle_events(toggles, pos, button);
546 Toy::mouse_pressed(pos, button, modifiers);
547 }
548 void draw(cairo_t *cr, std::ostringstream *notify, int width, int height, bool save, std::ostringstream *timer_stream) override {
549 cairo_set_source_rgba (cr, 0., 0., 0, 1);
550 cairo_set_line_width (cr, 1);
551 origin = orig_handle.pos;
552 if(1) {
553 cairo_save(cr);
554 cairo_set_line_width(cr, 0.3);
555 cairo_set_source_rgb(cr, 0.5, 0.5, 1);
556 eval = xaxis;
557 //recursive_implicit(Rect(Interval(0,width), Interval(0, height)), cr, 3);
558 eval = yaxis;
559 //recursive_implicit(Rect(Interval(0,width), Interval(0, height)), cr, 3);
560 cairo_restore(cr);
561 iters = 0;
562 for(int & split : splits)
563 split = 0;
564 show_splits = toggles[0].on;
565 eval = trial_eval;
566 recursive_implicit(Rect(Interval(0,width), Interval(0, height)), cr, 3);
567 for(int split : splits)
568 *notify << split << " + ";
569 *notify << " = " << iters;
570 }
571 if(1) {
572 Rect r(test_window.pts[0], test_window.pts[1]);
573 AAF x(interval(r.left(), r.right()));
574 AAF y(interval(r.top(), r.bottom()));
575 //AAF f = md_sample_based(x, samples.pts)-y;
576 if(0) {
577 x = x-500;
578 y = y-300;
579 x = x/200;
580 y = y/200;
581 AAF f = atan_sample_based(x)-y;
582 cout << f << endl;
583 }
584 AAF f = (*eval)(x, y);
585 double a = f.index_coeff(x.get_index(0))/x.index_coeff(x.get_index(0));
586 double b = f.index_coeff(y.get_index(0))/y.index_coeff(y.get_index(0));
587 AAF d = a*x + b*y - f;
588 //cout << d << endl;
589 interval ivl(d);
590 Point n(a,b);
591 OptRect out = tighten(r, n, Interval(ivl.min(), ivl.max()));
592 if(out)
593 cairo_rectangle(cr, *out);
594 cairo_rectangle(cr, r);
595 draw_line_in_rect(cr, r, n, ivl.min());
596 if(f.strictly_neg()) {
597 cairo_save(cr);
598 cairo_set_source_rgba(cr, .5, 0.5, 0, 0.125);
599 cairo_fill(cr);
600 cairo_restore(cr);
601 } else
602 cairo_stroke(cr);
603 cairo_save(cr);
604 cairo_set_line_width(cr, 0.3);
605 cairo_set_source_rgb(cr, 0.5, 0.5, 0);
606 draw_line_in_rect(cr, r, n, ivl.middle());
607 cairo_stroke(cr);
608 cairo_restore(cr);
609 //fill_line_in_rect(cr, r, n, c);
610 draw_line_in_rect(cr, r, n, ivl.max());
611 cairo_stroke(cr);
612 }
613 if(0) {
614 Geom::ConvexHull gm(samples.pts);
615 cairo_convex_hull(cr, gm);
616 cairo_stroke(cr);
617 Point a, b, c;
618 gm.narrowest_diameter(a, b, c);
619 cairo_save(cr);
620 cairo_set_line_width(cr, 2);
621 cairo_set_source_rgba(cr, 1, 0, 0, 0.5);
622 cairo_move_to(cr, b);
623 cairo_line_to(cr, c);
624 cairo_move_to(cr, a);
625 cairo_line_to(cr, (c-b)*dot(a-b, c-b)/dot(c-b,c-b)+b);
626 cairo_stroke(cr);
627 //std::cout << a << ", " << b << ", " << c << ": " << dia << "\n";
628 cairo_restore(cr);
629 }
630 Toy::draw(cr, notify, width, height, save,timer_stream);
631 Point d(25,25);
632 toggles[0].bounds = Rect(Point(10, height-80)+d,
633 Point(10+120, height-80+d[1])+d);
634
635 draw_toggles(cr, toggles);
636 }
637
638};
639
640int main(int argc, char **argv) {
641 init(argc, argv, new ConvexTest());
642
643 return 0;
644}
645
646/*
647 Local Variables:
648 mode:c++
649 c-file-style:"stroustrup"
650 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
651 indent-tabs-mode:nil
652 fill-column:99
653 End:
654*/
655// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Various geometrical calculations.
void draw_line_in_rect(cairo_t *cr, Rect &r, Point n, double c)
Definition aa.cpp:30
AAF trial_eval(AAF x, AAF y)
Definition aa.cpp:230
AAF yaxis(AAF x, AAF y)
Definition aa.cpp:281
AAF atan_sample_based(AAF x)
Definition aa.cpp:120
AAF xaxis(AAF x, AAF y)
Definition aa.cpp:269
OptRect tighten(Rect &r, Point n, Interval lu)
Definition aa.cpp:42
int main()
Convex hull based on the Andrew's monotone chain algorithm.
constexpr C extent() const
C right() const
Return rightmost coordinate of the rectangle (+X is to the right).
C area() const
Compute the rectangle's area.
C top() const
Return top coordinate of the rectangle (+Y is downwards).
CPoint midpoint() const
Get the point in the geometric center of the rectangle.
C left() const
Return leftmost coordinate of the rectangle (+X is to the right).
void expandTo(CPoint const &p)
Enlarge the rectangle to contain the given point.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
C bottom() const
Return bottom coordinate of the rectangle (+Y is downwards).
CPoint corner(unsigned i) const
Return the n-th corner of the rectangle.
Range of real numbers that is never empty.
Definition interval.h:59
const Vector & SV_solve()
const Vector & solution() const
void set_all(double x)
Definition matrix.h:225
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
Geom::Point pos
void push_back(double x, double y)
std::vector< Geom::Point > pts
virtual void mouse_pressed(Geom::Point const &pos, unsigned button, unsigned modifiers)
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)
const double w
Definition conic-4.cpp:19
Convex hull data structures.
Css & result
double c[8][4]
Lifts one dimensional objects into 2D.
T pow(T const &t, int n)
Integer exponentiation for transforms.
Definition transforms.h:98
auto floor(Geom::Rect const &rect)
Definition geom.h:131
AAF md_sample_based(AAF x, vector< Point > pts)
Definition ineaa.cpp:121
AAF log_sample_based(AAF x)
Definition ineaa.cpp:158
double fn1(double x, void *params)
Definition ineaa.cpp:239
AAF exp_sample_based(AAF x)
Definition ineaa.cpp:189
void draw_line_in_rect(cairo_t *cr, Rect &r, Point n, double c)
Definition ineaa.cpp:27
AAF trial_eval(AAF x, AAF y)
Definition ineaa.cpp:359
AAF yaxis(AAF x, AAF y)
Definition ineaa.cpp:398
Point origin
Definition ineaa.cpp:358
AAF pow_sample_based(AAF x, double p)
Definition ineaa.cpp:321
double optimise(void *params, double a, double b)
Definition ineaa.cpp:245
AAF atan_sample_based(AAF x)
Definition ineaa.cpp:137
std::complex< AAF > CAAF
Definition ineaa.cpp:18
void fill_line_in_rect(cairo_t *cr, Rect &r, Point n, double c)
Definition ineaa.cpp:39
double desy_lambert_W(double x)
Definition ineaa.cpp:209
AAF xaxis(AAF x, AAF y)
Definition ineaa.cpp:391
AAF ls_sample_based(AAF x, vector< Point > pts)
Definition ineaa.cpp:88
double lambertW(double x, double prec=1E-12, int maxiters=100)
Definition ineaa.cpp:217
OptRect tighten(Rect &r, Point n, Interval lu)
Definition ineaa.cpp:59
AAF W_sample_based(AAF x)
Definition ineaa.cpp:285
Various utility functions.
Definition affine.h:22
SBasisN< n > sqrt(SBasisN< n > const &a, int k)
std::optional< Geom::LineSegment > rect_line_intersect(Geom::Rect &r, Geom::LineSegment ls)
Determine whether & where an (infinite) line intersects a rectangle.
Definition geom.cpp:333
void split(vector< Point > const &p, double t, vector< Point > &left, vector< Point > &right)
Piecewise< SBasis > log(SBasis const &f, double tol=1e-3, int order=3)
SBasis L2(D2< SBasis > const &a, unsigned k)
Definition d2-sbasis.cpp:42
T dot(D2< T > const &a, D2< T > const &b)
Definition d2.h:355
std::vector< Point > intersect(const xAx &C1, const xAx &C2)
Definition conicsec.cpp:361
Point abs(Point const &b)
int n
Definition spiro.cpp:57
STL namespace.
void cairo_rectangle(cairo_t *cr, Geom::Rect const &r)
void cairo_line_to(cairo_t *cr, Geom::Point p1)
struct _cairo cairo_t
Definition path-cairo.h:16
void cairo_convex_hull(cairo_t *cr, Geom::ConvexHull const &r)
void cairo_move_to(cairo_t *cr, Geom::Point p1)
double height
double width
void toggle_events(std::vector< Toggle > &ts, Geom::Point const &pos, unsigned button)
void cairo_set_source_rgba(cairo_t *cr, colour c)
void draw_toggles(cairo_t *cr, std::vector< Toggle > &ts)
void redraw()
void init(int argc, char **argv, Toy *t, int width=600, int height=600)