|
| 1 | +# Examples |
| 2 | + |
| 3 | +One complete, self-contained example for each algorithm in the library. Every |
| 4 | +snippet runs as-is: it builds the input, runs the algorithm, inspects the |
| 5 | +result, and draws it with the matching visualization helper. The `# ->` comments |
| 6 | +show the actual output, and each example is followed by the figure it produces. |
| 7 | + |
| 8 | +## Convex hull |
| 9 | + |
| 10 | +The smallest convex polygon enclosing a set of points (Gift Wrapping / Jarvis |
| 11 | +march). |
| 12 | + |
| 13 | +```python |
| 14 | +from cgeom.algorithms import ConvexHull |
| 15 | +from cgeom.visualization import plot_convex_hull |
| 16 | + |
| 17 | +points = [(326, 237), (373, 209), (378, 265), (443, 241), |
| 18 | + (396, 231), (416, 270), (361, 335), (324, 297)] |
| 19 | + |
| 20 | +hull = ConvexHull(points) |
| 21 | + |
| 22 | +hull.convex_hull() # ordered hull vertices, [[x, y], ...] |
| 23 | +hull.get_indexes() # -> [1, 3, 6, 7, 0] (indices into `points`) |
| 24 | + |
| 25 | +plot_convex_hull(hull) |
| 26 | +``` |
| 27 | + |
| 28 | +```{image} ../public/examples/convex_hull.png |
| 29 | +:alt: Convex hull of a point set |
| 30 | +:align: center |
| 31 | +:width: 70% |
| 32 | +``` |
| 33 | + |
| 34 | +## Minimum enclosing circle |
| 35 | + |
| 36 | +The smallest circle that contains every point. |
| 37 | + |
| 38 | +```python |
| 39 | +import numpy as np |
| 40 | +from cgeom import Circle |
| 41 | +from cgeom.algorithms import MinimumCircle |
| 42 | +from cgeom.visualization import plot_min_circle |
| 43 | + |
| 44 | +points = [(0, 0), (1, 0), (0, 1), (1, 1), (0.5, 0.5)] |
| 45 | + |
| 46 | +mc = MinimumCircle() |
| 47 | +center, radius = mc.minimum_circle(points) # -> [0.5, 0.5], 0.70710678... |
| 48 | + |
| 49 | +# the raw [[cx, cy], radius] result drops straight into a Circle primitive |
| 50 | +circle = Circle(mc.minimum_circle(points)) |
| 51 | +circle.area # 1.5707... |
| 52 | + |
| 53 | +plot_min_circle(mc, np.array(points)) |
| 54 | +``` |
| 55 | + |
| 56 | +```{image} ../public/examples/min_circle.png |
| 57 | +:alt: Exact and heuristic minimum enclosing circle |
| 58 | +:align: center |
| 59 | +:width: 100% |
| 60 | +``` |
| 61 | + |
| 62 | +## Delaunay triangulation |
| 63 | + |
| 64 | +A triangulation that maximizes the minimum angle — no point lies inside any |
| 65 | +triangle's circumcircle. |
| 66 | + |
| 67 | +```python |
| 68 | +from cgeom.algorithms import DelaunayTriangulation |
| 69 | +from cgeom.visualization import plot_delaunay |
| 70 | + |
| 71 | +points = [(0, 0), (4, 0), (4, 4), (0, 4), (2, 2)] |
| 72 | + |
| 73 | +dt = DelaunayTriangulation(points) |
| 74 | + |
| 75 | +dt.triangulate() # -> [[0, 1, 4], [0, 3, 4], [1, 2, 4], [2, 3, 4]] |
| 76 | +len(dt.get_edges()) # -> 8 |
| 77 | +len(dt.get_circumcircles()) # -> 4 |
| 78 | + |
| 79 | +plot_delaunay(dt, show_circumcircles=True) |
| 80 | +``` |
| 81 | + |
| 82 | +```{image} ../public/examples/delaunay.png |
| 83 | +:alt: Delaunay triangulation with circumcircles |
| 84 | +:align: center |
| 85 | +:width: 70% |
| 86 | +``` |
| 87 | + |
| 88 | +## Voronoi diagram |
| 89 | + |
| 90 | +Partitions the plane into cells, one per site, containing everything closest to |
| 91 | +that site — the dual of the Delaunay triangulation. |
| 92 | + |
| 93 | +```python |
| 94 | +import numpy as np |
| 95 | +from cgeom.algorithms import VoronoiDiagram |
| 96 | +from cgeom.visualization import plot_voronoi |
| 97 | + |
| 98 | +points = np.loadtxt("examples/points1.txt") # 27 sites |
| 99 | + |
| 100 | +voronoi = VoronoiDiagram(points) |
| 101 | +cells = voronoi.build_voronoi_diagram() # one cell per site |
| 102 | +len(cells) # -> 27 |
| 103 | + |
| 104 | +plot_voronoi(voronoi, cells) |
| 105 | +``` |
| 106 | + |
| 107 | +```{image} ../public/examples/voronoi.png |
| 108 | +:alt: Voronoi diagram of 27 sites |
| 109 | +:align: center |
| 110 | +:width: 70% |
| 111 | +``` |
| 112 | + |
| 113 | +## Polygon triangulation |
| 114 | + |
| 115 | +Decomposes a simple polygon into triangles by ear clipping. The polygon is |
| 116 | +triangulated on construction; the diagonals are available immediately. |
| 117 | + |
| 118 | +```python |
| 119 | +from cgeom.algorithms import PolygonTriangulation |
| 120 | +from cgeom.visualization import plot_triangulation |
| 121 | + |
| 122 | +# a non-convex pentagon, vertices counter-clockwise |
| 123 | +poly = [[0, 0], [4, 0], [4, 4], [2, 2], [0, 4]] |
| 124 | + |
| 125 | +pt = PolygonTriangulation(poly) |
| 126 | + |
| 127 | +pt.diagonals # the added diagonals, [[[x1, y1], [x2, y2]], ...] |
| 128 | +pt.get_diag_vertexes() # -> [[4, 1], [1, 3]] (vertex-index pairs) |
| 129 | + |
| 130 | +plot_triangulation(pt) |
| 131 | +``` |
| 132 | + |
| 133 | +```{image} ../public/examples/triangulation.png |
| 134 | +:alt: Ear-clipping triangulation of a non-convex polygon |
| 135 | +:align: center |
| 136 | +:width: 70% |
| 137 | +``` |
| 138 | + |
| 139 | +## Segment intersection |
| 140 | + |
| 141 | +Reports every pairwise crossing of a set of segments using the Bentley–Ottmann |
| 142 | +sweep line, with a brute-force method for verification. |
| 143 | + |
| 144 | +```python |
| 145 | +from cgeom.algorithms import SegmentIntersection |
| 146 | +from cgeom.visualization import plot_intersections |
| 147 | + |
| 148 | +segments = [ |
| 149 | + [[0, 0], [4, 4]], # diagonal / |
| 150 | + [[0, 4], [4, 0]], # diagonal \ |
| 151 | + [[0, 2], [4, 2]], # horizontal |
| 152 | + [[2, 0], [2, 4]], # vertical |
| 153 | +] |
| 154 | + |
| 155 | +si = SegmentIntersection(segments) |
| 156 | + |
| 157 | +si.find_intersections() # sweep line -> [[2.0, 2.0]] |
| 158 | +si.find_intersections_brute_force() # cross-check -> [[2.0, 2.0]] |
| 159 | +si.get_intersection_pairs() # (i, j, point) for each crossing pair |
| 160 | + |
| 161 | +plot_intersections(si) |
| 162 | +``` |
| 163 | + |
| 164 | +```{image} ../public/examples/intersection.png |
| 165 | +:alt: Segment intersections found by the sweep line |
| 166 | +:align: center |
| 167 | +:width: 70% |
| 168 | +``` |
| 169 | + |
| 170 | +See the [User guide](guide/algorithms) for the full method-by-method reference, |
| 171 | +or the [API reference](api/index) for complete signatures. The figures above are |
| 172 | +regenerated by `docs/generate_example_figures.py`. |
0 commit comments