Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tikz_computational_geometry_gallery_example.cc
Go to the documentation of this file.
1// Comprehensive gallery of Aleph-w's computational-geometry module rendered
2// through the TikZ backend: primitives, hulls, triangulations, Voronoi/power
3// diagrams, boolean/decomposition operations, simplification/offset/
4// smoothing, visibility/shortest-path, arrangements, and convex-polygon
5// algorithms (Minkowski sum, half-plane intersection, rotating calipers,
6// alpha shapes). See Examples/tikz_tree_structures_example.cc for the
7// companion gallery of spatial data structures (KD-tree, range tree, AABB
8// tree, quadtree, R-tree/R*-tree).
9
10#include <fstream>
11#include <iostream>
12#include <string>
13
14#include <htlist.H>
15#include <tikzgeom_algorithms.H>
16
17using namespace Aleph;
18
19namespace
20{
21
22// ---------------------------------------------------------------------------
23// Panel 1: primitives & polygons
24// ---------------------------------------------------------------------------
25
27{
28 Polygon p;
29 p.add_vertex(Point(-18, -10));
30 p.add_vertex(Point(-4, -14));
31 p.add_vertex(Point(10, -8));
32 p.add_vertex(Point(6, 4));
33 p.add_vertex(Point(-8, 8));
34 p.close();
35 return p;
36}
37
38// ---------------------------------------------------------------------------
39// Panel 2: convex hull
40// ---------------------------------------------------------------------------
41
43{
45 pts.append(Point(-20, -10));
46 pts.append(Point(-14, 8));
47 pts.append(Point(-6, -16));
48 pts.append(Point(0, 2));
49 pts.append(Point(4, -12));
50 pts.append(Point(10, 14));
51 pts.append(Point(16, -4));
52 pts.append(Point(18, 10));
53 pts.append(Point(-2, 16));
54 pts.append(Point(6, 6));
55 pts.append(Point(-10, -2));
56 pts.append(Point(12, -14));
57 return pts;
58}
59
60// ---------------------------------------------------------------------------
61// Panel 3: Delaunay + Voronoi overlay
62// ---------------------------------------------------------------------------
63
65{
66 // Chosen so no Delaunay triangle is near-degenerate: a nearly-collinear
67 // triple has a legitimately distant circumcenter (Geom_Number is exact
68 // rational, so this is correct math, not a precision bug), which makes for
69 // a visually confusing demo panel with a Voronoi edge shooting far off
70 // frame. All triangles here have comparable area.
72 pts.append(Point(-20, -4));
73 pts.append(Point(-8, 16));
74 pts.append(Point(4, -18));
75 pts.append(Point(16, 4));
76 pts.append(Point(20, 18));
77 pts.append(Point(2, 4));
78 pts.append(Point(-14, -14));
79 return pts;
80}
81
82// ---------------------------------------------------------------------------
83// Panel 4: constrained Delaunay triangulation
84// ---------------------------------------------------------------------------
85
87{
89 pts.append(Point(-16, -10));
90 pts.append(Point(-16, 10));
91 pts.append(Point(16, 10));
92 pts.append(Point(16, -10));
93 pts.append(Point(-4, -2));
94 pts.append(Point(4, 4));
95 pts.append(Point(0, 0));
96 return pts;
97}
98
100{
102 segs.append(Segment(Point(-4, -2), Point(4, 4)));
103 return segs;
104}
105
106// ---------------------------------------------------------------------------
107// Panel 5: minimum enclosing circle + closest pair (shared point set)
108// ---------------------------------------------------------------------------
109
111{
113 pts.append(Point(-14, -6));
114 pts.append(Point(-8, 12));
115 pts.append(Point(4, 16));
116 pts.append(Point(16, 6));
117 pts.append(Point(12, -10));
118 pts.append(Point(-2, -14));
119 pts.append(Point(0, 2));
120 pts.append(Point(1, 3));
121 return pts;
122}
123
124// ---------------------------------------------------------------------------
125// Panel 6: convex decomposition
126// ---------------------------------------------------------------------------
127
129{
130 Polygon p; // a six-pointed star outline (non-convex)
131 p.add_vertex(Point(0, 16));
132 p.add_vertex(Point(4, 5));
133 p.add_vertex(Point(15, 5));
134 p.add_vertex(Point(6, -2));
135 p.add_vertex(Point(9, -14));
136 p.add_vertex(Point(0, -7));
137 p.add_vertex(Point(-9, -14));
138 p.add_vertex(Point(-6, -2));
139 p.add_vertex(Point(-15, 5));
140 p.add_vertex(Point(-4, 5));
141 p.close();
142 return p;
143}
144
145// ---------------------------------------------------------------------------
146// Panel 7: boolean intersection
147// ---------------------------------------------------------------------------
148
150{
151 Polygon p;
152 p.add_vertex(Point(-14, -10));
153 p.add_vertex(Point(6, -10));
154 p.add_vertex(Point(6, 10));
155 p.add_vertex(Point(-14, 10));
156 p.close();
157 return p;
158}
159
161{
162 Polygon p;
163 p.add_vertex(Point(-4, -4));
164 p.add_vertex(Point(16, -4));
165 p.add_vertex(Point(16, 16));
166 p.add_vertex(Point(-4, 16));
167 p.close();
168 return p;
169}
170
171// ---------------------------------------------------------------------------
172// Panel 8: Douglas-Peucker simplification
173// ---------------------------------------------------------------------------
174
176{
177 Polygon p;
178 p.add_vertex(Point(-16, -8));
179 p.add_vertex(Point(-12, -9));
180 p.add_vertex(Point(-8, -7));
181 p.add_vertex(Point(-4, -10));
182 p.add_vertex(Point(0, -8));
183 p.add_vertex(Point(6, -9));
184 p.add_vertex(Point(12, -7));
185 p.add_vertex(Point(14, 2));
186 p.add_vertex(Point(12, 8));
187 p.add_vertex(Point(6, 10));
188 p.add_vertex(Point(0, 9));
189 p.add_vertex(Point(-6, 10));
190 p.add_vertex(Point(-12, 9));
191 p.add_vertex(Point(-14, 2));
192 p.close();
193 return p;
194}
195
196// ---------------------------------------------------------------------------
197// Panel 9: polygon offset
198// ---------------------------------------------------------------------------
199
201{
202 Polygon p;
203 p.add_vertex(Point(-10, -8));
204 p.add_vertex(Point(10, -8));
205 p.add_vertex(Point(12, 0));
206 p.add_vertex(Point(10, 8));
207 p.add_vertex(Point(-10, 8));
208 p.close();
209 return p;
210}
211
212// ---------------------------------------------------------------------------
213// Panel 10: Chaikin smoothing
214// ---------------------------------------------------------------------------
215
217{
218 Polygon p; // a jagged five-pointed star
219 p.add_vertex(Point(0, 14));
220 p.add_vertex(Point(4, 3));
221 p.add_vertex(Point(13, 3));
222 p.add_vertex(Point(6, -4));
223 p.add_vertex(Point(8, -13));
224 p.add_vertex(Point(0, -7));
225 p.add_vertex(Point(-8, -13));
226 p.add_vertex(Point(-6, -4));
227 p.add_vertex(Point(-13, 3));
228 p.add_vertex(Point(-4, 3));
229 p.close();
230 return p;
231}
232
233// ---------------------------------------------------------------------------
234// Panel 11: visibility polygon
235// ---------------------------------------------------------------------------
236
238{
239 Polygon p; // an L-shaped room with a wall pier
240 p.add_vertex(Point(0, 0));
241 p.add_vertex(Point(24, 0));
242 p.add_vertex(Point(24, 10));
243 p.add_vertex(Point(14, 10));
244 p.add_vertex(Point(14, 20));
245 p.add_vertex(Point(0, 20));
246 p.close();
247 return p;
248}
249
250// ---------------------------------------------------------------------------
251// Panel 12: shortest path with funnel portals
252// ---------------------------------------------------------------------------
253
255{
256 Polygon p; // a bent corridor with a protruding obstacle
257 p.add_vertex(Point(0, 0));
258 p.add_vertex(Point(26, 0));
259 p.add_vertex(Point(26, 22));
260 p.add_vertex(Point(16, 22));
261 p.add_vertex(Point(16, 10));
262 p.add_vertex(Point(11, 10));
263 p.add_vertex(Point(11, 22));
264 p.add_vertex(Point(0, 22));
265 p.close();
266 return p;
267}
268
269// ---------------------------------------------------------------------------
270// Panel 13: trapezoidal map
271// ---------------------------------------------------------------------------
272
274{
275 Polygon p;
276 p.add_vertex(Point(-12, -8));
277 p.add_vertex(Point(8, -12));
278 p.add_vertex(Point(14, 0));
279 p.add_vertex(Point(4, 10));
280 p.add_vertex(Point(-10, 6));
281 p.close();
282 return p;
283}
284
285// ---------------------------------------------------------------------------
286// Panel 14: segment arrangement
287// ---------------------------------------------------------------------------
288
290{
292 segs.append(Segment(Point(-16, 0), Point(16, 0)));
293 segs.append(Segment(Point(0, -14), Point(0, 14)));
294 segs.append(Segment(Point(-14, -10), Point(14, 10)));
295 segs.append(Segment(Point(-14, 10), Point(14, -10)));
296 segs.append(Segment(Point(-10, -14), Point(10, 14)));
297 return segs;
298}
299
300// ---------------------------------------------------------------------------
301// Panel 15: Bentley-Ottmann line sweep
302// ---------------------------------------------------------------------------
303
305{
307 segs.append(Segment(Point(-16, -6), Point(16, 8)));
308 segs.append(Segment(Point(-14, 9), Point(15, -7)));
309 segs.append(Segment(Point(-16, 3), Point(16, 3)));
310 segs.append(Segment(Point(-6, -12), Point(-6, 12)));
311 segs.append(Segment(Point(8, -12), Point(8, 12)));
312 return segs;
313}
314
315// ---------------------------------------------------------------------------
316// Panel 16: Minkowski sum
317// ---------------------------------------------------------------------------
318
320{
321 Polygon p;
322 p.add_vertex(Point(-6, -3));
323 p.add_vertex(Point(5, -4));
324 p.add_vertex(Point(3, 5));
325 p.close();
326 return p;
327}
328
330{
331 Polygon p;
332 p.add_vertex(Point(-3, -2));
333 p.add_vertex(Point(4, -2));
334 p.add_vertex(Point(0, 5));
335 p.close();
336 return p;
337}
338
339// ---------------------------------------------------------------------------
340// Panel 17: half-plane intersection
341// ---------------------------------------------------------------------------
342
344{
347 hps.append(HP(Point(0, 1), Point(0, 0))); // x >= 0
348 hps.append(HP(Point(0, 0), Point(1, 0))); // y >= 0
349 hps.append(HP(Point(10, 0), Point(10, 1))); // x <= 10
350 hps.append(HP(Point(1, 10), Point(0, 10))); // y <= 10
351 hps.append(HP(Point(10, 0), Point(0, 10))); // x + y <= 10
352 return hps;
353}
354
355// ---------------------------------------------------------------------------
356// Panel 18: rotating calipers
357// ---------------------------------------------------------------------------
358
360{
361 Polygon p;
362 p.add_vertex(Point(-14, -4));
363 p.add_vertex(Point(-4, -12));
364 p.add_vertex(Point(10, -8));
365 p.add_vertex(Point(16, 4));
366 p.add_vertex(Point(6, 14));
367 p.add_vertex(Point(-10, 10));
368 p.close();
369 return p;
370}
371
372// ---------------------------------------------------------------------------
373// Panel 19: alpha shape
374// ---------------------------------------------------------------------------
375
377{
379 pts.append(Point(-16, -8));
380 pts.append(Point(-12, 10));
381 pts.append(Point(-2, 15));
382 pts.append(Point(8, 13));
383 pts.append(Point(15, 6));
384 pts.append(Point(17, -6));
385 pts.append(Point(8, -14));
386 pts.append(Point(-4, -16));
387 pts.append(Point(2, 2));
388 pts.append(Point(-5, 3));
389 return pts;
390}
391
392// ---------------------------------------------------------------------------
393// Panel 20: power diagram (weighted Voronoi)
394// ---------------------------------------------------------------------------
395
397{
398 // A ring of boundary sites plus two interior sites: only sites strictly
399 // inside the convex hull of the input can have a *bounded* power cell (a
400 // hull site's cell is always unbounded, exactly as in a plain Voronoi
401 // diagram), so the two interior sites are what make the filled cells
402 // visible here.
404 sites.append({Point(-16, -10), Geom_Number(2)});
405 sites.append({Point(16, -10), Geom_Number(3)});
406 sites.append({Point(20, 8), Geom_Number(2)});
407 sites.append({Point(0, 18), Geom_Number(4)});
408 sites.append({Point(-20, 8), Geom_Number(3)});
409 sites.append({Point(-6, 3), Geom_Number(5)});
410 sites.append({Point(6, -2), Geom_Number(2)});
411 return sites;
412}
413
414void add_caption(Tikz_Plane & plane, const Point & at, const std::string & text)
415{
416 put_in_plane(plane, Text(at, text), make_tikz_draw_style("black"),
418}
419
420} // namespace
421
422int main(int argc, char * argv[])
423{
424 const std::string output_path =
425 argc > 1 ? argv[1] : "tikz_computational_geometry_gallery_example.tex";
426
427 std::ofstream out(output_path);
428 if (not out)
429 {
430 std::cerr << "Cannot open output file: " << output_path << '\n';
431 return 1;
432 }
433
435 auto & p = panels; // shorthand
436
437 // 1. Primitives & polygons showcase.
438 p.append(Tikz_Plane(190, 120, 6, 6));
439 {
440 Tikz_Plane & plane = p.get_last();
441 plane.put_cartesian_axis();
442 put_in_plane(plane, Segment(Point(-24, -12), Point(-14, 4)), tikz_wire_style("blue"));
443 put_in_plane(plane, Triangle(Point(-8, -14), Point(2, -14), Point(-3, -4)),
444 tikz_area_style("teal", "teal!18", 0.4));
445 put_in_plane(plane, Ellipse(Point(12, -8), Geom_Number(6), Geom_Number(3)),
446 tikz_wire_style("purple"));
448 Geom_Number(3, 5), Geom_Number(4, 5)),
449 tikz_wire_style("magenta"));
450 put_in_plane(plane, Regular_Polygon(Point(-14, 12), 5.0, 6),
451 tikz_area_style("orange!80!black", "orange!20", 0.4));
453 put_in_plane(plane, Point(0, 0), tikz_points_style("red"));
454 add_caption(plane, Point(-24, 20), "Primitives: segment, triangle, ellipse, "
455 "rotated ellipse, regular hexagon, irregular polygon, point");
456 }
457
458 // 2. Convex hull (Andrew monotone chain).
459 p.append(Tikz_Plane(180, 110, 6, 6));
460 {
461 Tikz_Plane & plane = p.get_last();
462 plane.put_cartesian_axis();
463 plane.set_point_radius_mm(0.7);
466 add_caption(plane, Point(-22, 20),
467 "Convex Hull (Andrew): h=" + std::to_string(hull.size()));
468 }
469
470 // 3. Delaunay triangulation + Voronoi overlay.
471 p.append(Tikz_Plane(190, 115, 6, 6));
472 {
473 Tikz_Plane & plane = p.get_last();
474 plane.put_cartesian_axis();
475 plane.set_point_radius_mm(0.75);
476 const DynList<Point> sites = make_voronoi_sites();
478 const auto dt = dt_algo(sites);
479 put_delaunay_result(plane, dt, tikz_wire_style("blue!70"), false);
480 visualize_voronoi(plane, sites, VoronoiDiagram(), false,
481 tikz_area_style("gray!50!black", "gray!15", 0.25),
482 tikz_wire_style("black"),
483 tikz_wire_style("black", true, true),
484 tikz_points_style("red"), Geom_Number(60));
485 add_caption(plane, Point(-25, 24),
486 "Delaunay + Voronoi: sites=" + std::to_string(dt.sites.size()) +
487 ", triangles=" + std::to_string(dt.triangles.size()));
488 }
489
490 // 4. Constrained Delaunay triangulation.
491 p.append(Tikz_Plane(180, 105, 5, 5));
492 {
493 Tikz_Plane & plane = p.get_last();
494 plane.put_cartesian_axis();
495 const auto cdt = visualize_cdt(plane, make_cdt_points(), make_cdt_constraints());
496 add_caption(plane, Point(-18, 13),
497 "CDT: triangles=" + std::to_string(cdt.triangles.size()) +
498 ", constraints=" + std::to_string(cdt.constrained_edges.size()));
499 }
500
501 // 5. Minimum enclosing circle + closest pair (same point set).
502 p.append(Tikz_Plane(180, 110, 6, 6));
503 {
504 Tikz_Plane & plane = p.get_last();
505 plane.put_cartesian_axis();
507 const auto circle = visualize_mec(plane, pts);
508 const auto [first, second, distance_squared] = visualize_closest_pair(plane, pts);
509 add_caption(plane, Point(-18, 20),
510 "MEC r=" + std::to_string(geom_number_to_double(circle.radius())) +
511 " + closest pair d^2=" +
512 std::to_string(geom_number_to_double(distance_squared)));
513 }
514
515 // 6. Convex decomposition (six-pointed star).
516 p.append(Tikz_Plane(170, 115, 6, 6));
517 {
518 Tikz_Plane & plane = p.get_last();
519 plane.put_cartesian_axis();
520 const Array<Polygon> parts =
522 add_caption(plane, Point(-16, 19),
523 "Convex Decomposition: parts=" + std::to_string(parts.size()));
524 }
525
526 // 7. Boolean intersection of two overlapping rectangles.
527 p.append(Tikz_Plane(170, 110, 6, 6));
528 {
529 Tikz_Plane & plane = p.get_last();
530 plane.put_cartesian_axis();
531 const auto result = visualize_boolean_operation(
532 plane, make_boolean_a(), make_boolean_b(),
533 BooleanPolygonOperations::Op::INTERSECTION);
534 add_caption(plane, Point(-16, 19),
535 "Boolean Intersection: parts=" + std::to_string(result.size()));
536 }
537
538 // 8. Douglas-Peucker simplification.
539 p.append(Tikz_Plane(180, 110, 6, 6));
540 {
541 Tikz_Plane & plane = p.get_last();
542 plane.put_cartesian_axis();
543 const Polygon simplified =
545 add_caption(plane, Point(-18, 14),
546 "Douglas-Peucker: original=" +
547 std::to_string(make_noisy_polygon().size()) +
548 ", simplified=" + std::to_string(simplified.size()));
549 }
550
551 // 9. Polygon offset (inward).
552 p.append(Tikz_Plane(160, 100, 6, 6));
553 {
554 Tikz_Plane & plane = p.get_last();
555 plane.put_cartesian_axis();
556 const auto result = visualize_polygon_offset(plane, make_offset_polygon(), Geom_Number(-3));
557 add_caption(plane, Point(-13, 12),
558 "Polygon Offset (-3): polygons=" + std::to_string(result.polygons.size()));
559 }
560
561 // 10. Chaikin smoothing.
562 p.append(Tikz_Plane(160, 105, 6, 6));
563 {
564 Tikz_Plane & plane = p.get_last();
565 plane.put_cartesian_axis();
566 const Polygon smoothed =
568 add_caption(plane, Point(-14, 16),
569 "Chaikin Smoothing (3 iters): vertices=" + std::to_string(smoothed.size()));
570 }
571
572 // 11. Visibility polygon.
573 p.append(Tikz_Plane(170, 110, 6, 6));
574 {
575 Tikz_Plane & plane = p.get_last();
576 plane.put_cartesian_axis();
577 const Point query(3, 3);
579 add_caption(plane, Point(-1, 24),
580 "Visibility Polygon: vertices=" + std::to_string(vis.size()));
581 }
582
583 // 12. Shortest path with funnel portals.
584 p.append(Tikz_Plane(190, 115, 6, 6));
585 {
586 Tikz_Plane & plane = p.get_last();
587 plane.put_cartesian_axis();
588 const Point source(3, 3);
589 const Point target(20, 18);
591 plane, make_corridor_polygon(), source, target, ShortestPathInPolygon());
592 size_t path_nodes = 0;
593 for (DynList<Point>::Iterator it(debug.path); it.has_curr(); it.next_ne())
594 ++path_nodes;
595 add_caption(plane, Point(-1, 26),
596 "Shortest Path + Portals: path nodes=" + std::to_string(path_nodes) +
597 ", portals=" + std::to_string(debug.portals.size()));
598 }
599
600 // 13. Trapezoidal map point location.
601 p.append(Tikz_Plane(170, 110, 6, 6));
602 {
603 Tikz_Plane & plane = p.get_last();
604 plane.put_cartesian_axis();
606 add_caption(plane, Point(-15, 14),
607 "Trapezoidal Map: input segments=" + std::to_string(res.num_input_segments));
608 }
609
610 // 14. Segment arrangement.
611 p.append(Tikz_Plane(170, 110, 6, 6));
612 {
613 Tikz_Plane & plane = p.get_last();
614 plane.put_cartesian_axis();
617 true, true, false,
618 tikz_area_style("teal!60!black", "teal!12", 0.35),
619 tikz_wire_style("teal!70!black"),
620 tikz_points_style("teal!80!black"), true);
621 add_caption(plane, Point(-18, 18),
622 "Segment Arrangement: V=" + std::to_string(arrangement.vertices.size()) +
623 ", E=" + std::to_string(arrangement.edges.size()));
624 }
625
626 // 15. Bentley-Ottmann line sweep.
627 p.append(Tikz_Plane(170, 110, 6, 6));
628 {
629 Tikz_Plane & plane = p.get_last();
630 plane.put_cartesian_axis();
631 plane.set_point_radius_mm(0.7);
633 add_caption(plane, Point(-18, 15),
634 "Line Sweep intersections=" + std::to_string(intersections.size()));
635 }
636
637 // 16. Minkowski sum.
638 p.append(Tikz_Plane(160, 100, 6, 6));
639 {
640 Tikz_Plane & plane = p.get_last();
641 plane.put_cartesian_axis();
643 add_caption(plane, Point(-9, 10), "Minkowski Sum: vertices=" + std::to_string(sum.size()));
644 }
645
646 // 17. Half-plane intersection.
647 p.append(Tikz_Plane(150, 100, 6, 6));
648 {
649 Tikz_Plane & plane = p.get_last();
650 plane.put_cartesian_axis();
652 add_caption(plane, Point(-1, 12),
653 "Half-Plane Intersection: vertices=" + std::to_string(feasible.size()));
654 }
655
656 // 18. Rotating calipers (diameter + minimum width).
657 p.append(Tikz_Plane(170, 110, 6, 6));
658 {
659 Tikz_Plane & plane = p.get_last();
660 plane.put_cartesian_axis();
662 add_caption(plane, Point(-16, 18),
663 "Rotating Calipers: diameter^2=" +
664 std::to_string(geom_number_to_double(rc.diameter.distance_squared)));
665 }
666
667 // 19. Alpha shape.
668 p.append(Tikz_Plane(180, 115, 6, 6));
669 {
670 Tikz_Plane & plane = p.get_last();
671 plane.put_cartesian_axis();
672 plane.set_point_radius_mm(0.75);
673 const auto alpha = visualize_alpha_shape(plane, make_alpha_points(), Geom_Number(180));
674 add_caption(plane, Point(-19, 20),
675 "Alpha Shape: boundary edges=" + std::to_string(alpha.boundary_edges.size()));
676 }
677
678 // 20. Power diagram (weighted Voronoi).
679 p.append(Tikz_Plane(200, 115, 6, 6));
680 {
681 Tikz_Plane & plane = p.get_last();
682 plane.put_cartesian_axis();
683 plane.set_point_radius_mm(0.75);
684 // draw_cells=false: PowerDiagram's bounded-cell vertex lists are not
685 // reliably in simple cyclic order around their site, so building a
686 // filled cell polygon can throw "closing causes an intersection"
687 // (reproduced with this exact site data; see the geometry review notes).
688 // Only edges/sites are drawn until that ordering bug is fixed upstream.
690 tikz_area_style("violet", "violet!18", 0.35),
691 tikz_wire_style("violet"), tikz_points_style("purple"));
692 add_caption(plane, Point(-26, 23), "Power Diagram (Weighted Voronoi)");
693 }
694
695 out << "\\documentclass[tikz,border=8pt]{standalone}\n"
696 << "\\usepackage{tikz}\n"
697 << "\\begin{document}\n\n";
698
699 for (size_t i = 0; i < panels.size(); ++i)
700 {
701 panels[i].draw(out, true);
702 if (i + 1 < panels.size())
703 out << "\n\\vspace{4mm}\n\n";
704 }
705
706 out << "\n\\end{document}\n";
707
708 out.close();
709 if (not out)
710 {
711 std::cerr << "Failed writing output file: " << output_path << '\n';
712 return 1;
713 }
714
715 std::cout << "Generated " << output_path << " (" << panels.size() << " panels)\n";
716 std::cout << "Compile with: pdflatex " << output_path << '\n';
717 return 0;
718}
int main()
size_t size_t int32_t * out
Definition ca-c-api.h:120
Andrew's monotonic chain convex hull algorithm.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:250
O(n log n) expected-time Delaunay's triangulation.
Iterator on the items of list.
Definition htlist.H:1420
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
An axis-aligned ellipse.
Definition point.H:2076
Represents a point with rectangular coordinates in a 2D plane.
Definition point.H:221
A general (irregular) 2D polygon defined by a sequence of vertices.
Definition polygon.H:247
void append(const Point &point)
Append a vertex (Aleph container protocol).
Definition polygon.H:765
void add_vertex(const Point &point)
Add a vertex to the polygon.
Definition polygon.H:678
void close()
Close the polygon.
Definition polygon.H:843
const size_t & size() const
Get the number of vertices.
Definition polygon.H:478
Power diagram (weighted Voronoi diagram).
A regular polygon defined by center, side length, and vertex count.
Definition polygon.H:1135
An ellipse with arbitrary rotation.
Definition point.H:2473
Compute the full planar subdivision induced by a set of segments.
Represents a line segment between two points.
Definition point.H:837
Compute the shortest Euclidean path between two points inside a simple polygon.
Represents a text string positioned at a 2D point.
Definition point.H:2817
2D TikZ canvas storing geometry objects and emitting LaTeX output.
Definition tikzgeom.H:200
void put_cartesian_axis()
Enable Cartesian axes drawing (only when 0 lies in range).
Definition tikzgeom.H:1330
void set_point_radius_mm(const double &radius_mm)
Configure point marker radius.
Definition tikzgeom.H:1314
static constexpr int Layer_Overlay
Definition tikzgeom.H:205
A non-degenerate triangle defined by three points.
Definition point.H:1512
O(n log n) Voronoi diagram construction.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
AlphaShape::Result visualize_alpha_shape(Tikz_Plane &plane, const DynList< Point > &points, const Geom_Number &alpha_squared, const AlphaShape &algorithm={}, const bool draw_kept_triangles=false, const Tikz_Style &triangle_style=tikz_wire_style("gray!55"), const Tikz_Style &boundary_style=tikz_path_style("orange!90!black"), const bool draw_sites=true, const Tikz_Style &site_style=tikz_points_style("black"))
Compute and insert alpha-shape for input points.
PolygonOffset::Result visualize_polygon_offset(Tikz_Plane &plane, const Polygon &poly, const Geom_Number &distance, const PolygonOffset &algorithm={}, PolygonOffset::JoinType join=PolygonOffset::JoinType::Miter, const Geom_Number &miter_limit=Geom_Number(2), const Tikz_Style &original_style=tikz_wire_style("gray!50"), const Tikz_Style &offset_style=tikz_bold_wire_style("blue!80"), const bool draw_vertices=true, const Tikz_Style &vertex_style=tikz_points_style("red"))
Offset a polygon and draw the result.
size_t size(Node *root) noexcept
MinimumEnclosingCircle::Circle visualize_mec(Tikz_Plane &plane, const DynList< Point > &points, const MinimumEnclosingCircle &algorithm={}, const Tikz_Style &circle_style=tikz_wire_style("blue!70"), const bool draw_sites=true, const Tikz_Style &site_style=tikz_points_style("black"))
Compute minimum enclosing circle and insert into plane.
PowerDiagram::Result visualize_power_diagram(Tikz_Plane &plane, const Array< PowerDiagram::WeightedSite > &sites, const PowerDiagram &algorithm={}, const bool draw_cells=true, const Tikz_Style &cell_style=tikz_area_style("violet", "violet!18", 0.35), const Tikz_Style &edge_style=tikz_wire_style("violet"), const Tikz_Style &site_style=tikz_points_style("purple"))
Compute and insert Power diagram for weighted sites.
VoronoiDiagram::Result visualize_voronoi(Tikz_Plane &plane, const DynList< Point > &sites, const VoronoiDiagram &algorithm={}, const bool draw_cells=false, const Tikz_Style &cell_style=tikz_area_style("gray!50!black", "gray!15", 0.35), const Tikz_Style &edge_style=tikz_wire_style("black"), const Tikz_Style &unbounded_edge_style=tikz_wire_style("black", true, true), const Tikz_Style &site_style=tikz_points_style("red"), const Geom_Number &unbounded_ray_length=Geom_Number(50))
Compute and insert Voronoi diagram for input sites.
Polygon visualize_half_plane_intersection(Tikz_Plane &plane, const Array< HalfPlaneIntersection::HalfPlane > &halfplanes, const HalfPlaneIntersection &algorithm={}, const Tikz_Style &boundary_style=tikz_wire_style("gray!60", true, true), const Tikz_Style &result_style=tikz_area_style("red", "red!25", 0.50))
Compute and draw bounded half-plane intersection.
TrapezoidalMapPointLocation::Result visualize_trapezoidal_map(Tikz_Plane &plane, const Array< Segment > &segments, const Tikz_Style &segment_style=tikz_path_style("red"), const Tikz_Style &extension_style=tikz_wire_style("gray!60", true), const bool draw_trapezoids=true, const double trapezoid_opacity=0.3)
Build a trapezoidal map and draw it.
void put_in_plane(Tikz_Plane &plane, const Geom &geom_obj)
Insert any supported geometry type in a Tikz_Plane.
Definition tikzgeom.H:1511
Polygon visualize_visibility_polygon(Tikz_Plane &plane, const Polygon &polygon, const Point &query_point, const VisibilityPolygon &algorithm={}, const Tikz_Style &polygon_style=tikz_wire_style("black"), const Tikz_Style &visibility_style=tikz_area_style("orange!90!black", "orange!25", 0.50), const Tikz_Style &query_style=tikz_points_style("red"))
Compute and draw visibility polygon from a query point.
ShortestPathDebugResult visualize_shortest_path_with_portals(Tikz_Plane &plane, const Polygon &polygon, const Point &source, const Point &target, const ShortestPathInPolygon &algorithm={}, const Tikz_Style &polygon_style=tikz_area_style("black", "gray!15", 0.25), const Tikz_Style &source_style=tikz_points_style("green!50!black"), const Tikz_Style &target_style=tikz_points_style("blue"), const Tikz_Style &portal_style=tikz_wire_style("purple", true), const Tikz_Style &path_style=tikz_path_style("red"), const bool draw_waypoints=true, const Tikz_Style &waypoint_style=tikz_points_style("red"), const int polygon_layer=Tikz_Plane::Layer_Default, const int portal_layer=Tikz_Plane::Layer_Foreground, const int path_layer=Tikz_Plane::Layer_Overlay)
Visualize the shortest path plus funnel portals.
double geom_number_to_double(const Geom_Number &n)
Converts a Geom_Number to its double precision representation.
Definition point.H:120
Array< SweepLineSegmentIntersection::Intersection > visualize_line_sweep(Tikz_Plane &plane, const Array< Segment > &segments, const SweepLineSegmentIntersection &algorithm={}, const Tikz_Style &segment_style=tikz_wire_style("blue!60"), const Tikz_Style &intersection_style=tikz_points_style("red"))
Compute and draw Bentley-Ottmann line-sweep intersections.
mpq_class Geom_Number
Numeric type used by the geometry module.
Definition point.H:113
ClosestPairDivideAndConquer::Result visualize_closest_pair(Tikz_Plane &plane, const DynList< Point > &points, const ClosestPairDivideAndConquer &algorithm={}, const Tikz_Style &points_style=tikz_points_style("black"), const Tikz_Style &pair_style=tikz_path_style("red"), const Tikz_Style &pair_points_style=tikz_points_style("red"))
Compute and draw the closest pair from an input point set.
RotatingCalipersResult visualize_rotating_calipers(Tikz_Plane &plane, const Polygon &polygon, const Tikz_Style &polygon_style=tikz_wire_style("gray!55"), const Tikz_Style &diameter_style=tikz_path_style("red"), const Tikz_Style &width_style=tikz_path_style("blue"), const Tikz_Style &witness_style=tikz_points_style("orange!90!black"))
Compute and draw rotating-calipers diameter and minimum width.
Tikz_Style make_tikz_draw_style(const std::string &draw_color)
Create a basic draw style with a custom color.
Definition tikzgeom.H:172
Polygon visualize_chaikin_smoothing(Tikz_Plane &plane, const Polygon &poly, const size_t iterations, const Geom_Number &ratio=Geom_Number(1, 4), const Tikz_Style &original_style=tikz_wire_style("gray!50"), const Tikz_Style &smoothed_style=tikz_bold_wire_style("violet!80"), const bool draw_vertices=true, const Tikz_Style &vertex_style=tikz_points_style("red"))
Smooth a polygon with Chaikin subdivision and draw the result.
Tikz_Style tikz_wire_style(const std::string &color="black", const bool dashed=false, const bool with_arrow=false)
Creates a style optimized for wireframe segments and polygons.
ConstrainedDelaunayTriangulation::Result visualize_cdt(Tikz_Plane &plane, const DynList< Point > &points, const DynList< Segment > &constraints, const ConstrainedDelaunayTriangulation &algorithm={}, const Tikz_Style &triangle_style=tikz_wire_style("blue!60"), const Tikz_Style &constraint_style=tikz_path_style("red"), const bool draw_sites=true, const Tikz_Style &site_style=tikz_points_style("black"))
Compute and insert constrained Delaunay triangulation.
SegmentArrangement::Result visualize_segment_arrangement(Tikz_Plane &plane, const Array< Segment > &segments, const SegmentArrangement &algorithm={}, const bool draw_faces=true, const bool draw_vertices=true, const bool draw_unbounded_face=false, const Tikz_Style &face_style=tikz_area_style("teal!60!black", "teal!12", 0.30), const Tikz_Style &edge_style=tikz_wire_style("teal!70!black"), const Tikz_Style &vertex_style=tikz_points_style("teal!70!black"), const bool color_faces_by_index=false)
Compute and insert arrangement for input segments.
Polygon visualize_minkowski_sum(Tikz_Plane &plane, const Polygon &first, const Polygon &second, const MinkowskiSumConvex &algorithm={}, const Tikz_Style &first_style=tikz_area_style("blue", "blue!14", 0.30), const Tikz_Style &second_style=tikz_area_style("green!60!black", "green!16", 0.30), const Tikz_Style &result_style=tikz_area_style("red", "red!26", 0.60))
Compute and draw Minkowski sum of two convex polygons.
Array< Polygon > visualize_boolean_operation(Tikz_Plane &plane, const Polygon &a, const Polygon &b, const BooleanPolygonOperations::Op op, const BooleanPolygonOperations &bop={}, const Tikz_Style &a_style=tikz_area_style("blue", "blue!15", 0.35), const Tikz_Style &b_style=tikz_area_style("green!60!black", "green!20", 0.35), const Tikz_Style &result_style=tikz_area_style("red", "red!35", 0.65), const int input_layer=Tikz_Plane::Layer_Default, const int result_layer=Tikz_Plane::Layer_Foreground)
Visualizes a boolean operation (union, intersection, difference) on two polygons.
Polygon visualize_douglas_peucker(Tikz_Plane &plane, const Polygon &poly, const Geom_Number &epsilon, const DouglasPeuckerSimplification &algorithm={}, const Tikz_Style &original_style=tikz_wire_style("gray!50"), const Tikz_Style &simplified_style=tikz_bold_wire_style("blue!80"), const bool draw_vertices=true, const Tikz_Style &vertex_style=tikz_points_style("red"))
Simplify a polygon with Douglas-Peucker and draw the result.
Tikz_Style tikz_area_style(const std::string &draw_color="black", const std::string &fill_color="gray!25", const double opacity=0.6)
Creates a style for drawing filled polygons.
Polygon visualize_convex_hull(Tikz_Plane &plane, const DynList< Point > &points, const HullAlgorithm &hull_algorithm, const Tikz_Style &point_style=tikz_points_style("black", 0.6), const Tikz_Style &hull_style=tikz_wire_style("red"), const Tikz_Style &hull_vertex_style=tikz_points_style("red"), const int point_layer=Tikz_Plane::Layer_Default, const int hull_layer=Tikz_Plane::Layer_Foreground, const bool draw_hull_vertices=true)
Runs a convex hull algorithm and visualizes the result.
void put_delaunay_result(Tikz_Plane &plane, const DelaunayTriangulationBowyerWatson::Result &dt, const Tikz_Style &triangle_style=tikz_wire_style("blue"), const bool draw_sites=true, const Tikz_Style &site_style=tikz_points_style("black"), const int triangle_layer=Tikz_Plane::Layer_Default, const int site_layer=Tikz_Plane::Layer_Foreground)
Insert Delaunay triangulation as triangle outlines.
Tikz_Style tikz_points_style(const std::string &color="black", const double opacity=-1.0)
Creates a style optimized for point clouds.
Array< Polygon > visualize_convex_decomposition(Tikz_Plane &plane, const Polygon &polygon, const ConvexPolygonDecomposition &algorithm={}, const bool draw_input_polygon=true, const Tikz_Style &input_style=tikz_wire_style("black", true), const bool color_parts_by_index=true, const Tikz_Style &part_style=tikz_area_style("blue!60!black", "blue!15", 0.40), const int input_layer=Tikz_Plane::Layer_Default, const int part_layer=Tikz_Plane::Layer_Foreground)
Compute and insert convex decomposition for a polygon.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Helpers to visualize computational-geometry algorithm results in TikZ.