-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_example_figures.py
More file actions
104 lines (82 loc) · 2.85 KB
/
Copy pathgenerate_example_figures.py
File metadata and controls
104 lines (82 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
"""Regenerate the figures embedded in ``docs/examples.md``.
Each visualization helper ends in ``plt.show()``; here we patch ``show`` to save
the current figure instead, so the rendered output matches the documented code.
Run from the repository root::
.venv/bin/python docs/generate_example_figures.py
"""
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt # noqa: E402
import numpy as np # noqa: E402
from cgeom.algorithms import ( # noqa: E402
ConvexHull,
DelaunayTriangulation,
MinimumCircle,
PolygonTriangulation,
SegmentIntersection,
VoronoiDiagram,
)
from cgeom.visualization import ( # noqa: E402
plot_convex_hull,
plot_delaunay,
plot_intersections,
plot_min_circle,
plot_triangulation,
plot_voronoi,
)
OUT_DIR = "public/examples"
os.makedirs(OUT_DIR, exist_ok=True)
_saved = set()
_current = {"name": None}
def _save_show():
"""Stand-in for ``plt.show`` that saves the first figure per example."""
name = _current["name"]
if name and name not in _saved:
fig = plt.gcf()
fig.savefig(
os.path.join(OUT_DIR, f"{name}.png"),
dpi=150,
facecolor=fig.get_facecolor(),
bbox_inches="tight",
)
_saved.add(name)
plt.close("all")
plt.show = _save_show
def render(name, fn):
_current["name"] = name
fn()
print(f"saved {OUT_DIR}/{name}.png")
# --- Convex hull -----------------------------------------------------------
hull = ConvexHull(
[
(326, 237),
(373, 209),
(378, 265),
(443, 241),
(396, 231),
(416, 270),
(361, 335),
(324, 297),
]
)
render("convex_hull", lambda: plot_convex_hull(hull))
# --- Minimum enclosing circle ---------------------------------------------
mc_points = np.array([(0, 0), (1, 0), (0, 1), (1, 1), (0.5, 0.5)])
render("min_circle", lambda: plot_min_circle(MinimumCircle(), mc_points, show=True))
# --- Delaunay triangulation ------------------------------------------------
dt = DelaunayTriangulation([(0, 0), (4, 0), (4, 4), (0, 4), (2, 2)])
dt.triangulate()
render("delaunay", lambda: plot_delaunay(dt, show_circumcircles=True))
# --- Voronoi diagram -------------------------------------------------------
voronoi = VoronoiDiagram(np.loadtxt("examples/points1.txt"))
cells = voronoi.build_voronoi_diagram()
render("voronoi", lambda: plot_voronoi(voronoi, cells))
# --- Polygon triangulation -------------------------------------------------
pt = PolygonTriangulation([[0, 0], [4, 0], [4, 4], [2, 2], [0, 4]])
render("triangulation", lambda: plot_triangulation(pt))
# --- Segment intersection --------------------------------------------------
si = SegmentIntersection(
[[[0, 0], [4, 4]], [[0, 4], [4, 0]], [[0, 2], [4, 2]], [[2, 0], [2, 4]]]
)
render("intersection", lambda: plot_intersections(si))