1import numpy as np
2
3
4def compare(plt, A, B, figsize=(6, 3)):
5    plt.figure(figsize=figsize)
6    ax1 = plt.subplot(121)
7    plot(ax1, **A)
8    lim = ax1.axis()
9    ax2 = plt.subplot(122, sharey=ax1)
10    plot(ax2, **B)
11    ax2.axis(lim)
12    plt.tight_layout()
13
14
15def comparev(plt, A, B, figsize=(3, 6)):
16    plt.figure(figsize=figsize)
17    ax1 = plt.subplot(211)
18    plot(ax1, **A)
19    lim = ax1.axis()
20    ax2 = plt.subplot(212, sharex=ax1)
21    plot(ax2, **B)
22    ax2.axis(lim)
23    plt.tight_layout()
24
25
26def plot(ax, **kw):
27    ax.axes.set_aspect('equal')
28    vertices(ax, **kw)
29    if 'segments' in kw:
30        segments(ax, **kw)
31    if 'triangles' in kw:
32        triangles(ax, **kw)
33    if 'holes' in kw:
34        holes(ax, **kw)
35    if 'edges' in kw:
36        edges(ax, **kw)
37    if 'regions' in kw:
38        regions(ax, **kw)
39    if 'triangle_attributes' in kw:
40        triangle_attributes(ax, **kw)
41
42    ax.get_xaxis().set_visible(False)
43    ax.get_yaxis().set_visible(False)
44
45
46def vertices(ax, **kw):
47    verts = np.array(kw['vertices'])
48    ax.scatter(*verts.T, color='k')
49    if 'labels' in kw:
50        for i in range(verts.shape[0]):
51            ax.text(verts[i, 0], verts[i, 1], str(i))
52    if 'markers' in kw:
53        vm = kw['vertex_markers']
54        for i in range(verts.shape[0]):
55            ax.text(verts[i, 0], verts[i, 1], str(vm[i]))
56
57
58def segments(ax, **kw):
59    verts = np.array(kw['vertices'])
60    segs = np.array(kw['segments'])
61    for beg, end in segs:
62        x0, y0 = verts[beg, :]
63        x1, y1 = verts[end, :]
64        ax.fill(
65            [x0, x1],
66            [y0, y1],
67            facecolor='none',
68            edgecolor='r',
69            linewidth=3,
70            zorder=0,
71        )
72
73
74def triangles(ax, **kw):
75    verts = np.array(kw['vertices'])
76    ax.triplot(verts[:, 0], verts[:, 1], kw['triangles'], 'ko-')
77
78
79def holes(ax, **kw):
80    holes = np.array(kw['holes'])
81    ax.scatter(*holes.T, marker='x', color='r')
82
83
84def edges(ax, **kw):
85    """
86    Plot regular edges and rays (edges whose one endpoint is at infinity)
87    """
88    verts = kw['vertices']
89    edges = kw['edges']
90    for beg, end in edges:
91        x0, y0 = verts[beg, :]
92        x1, y1 = verts[end, :]
93        ax.fill(
94            [x0, x1],
95            [y0, y1],
96            facecolor='none',
97            edgecolor='k',
98            linewidth=.5,
99        )
100
101    if ('ray_origins' not in kw) or ('ray_directions' not in kw):
102        return
103
104    lim = ax.axis()
105    ray_origin = kw['ray_origins']
106    ray_direct = kw['ray_directions']
107    for (beg, (vx, vy)) in zip(ray_origin.flatten(), ray_direct):
108        x0, y0 = verts[beg, :]
109        scale = 100.0  # some large number
110        x1, y1 = x0 + scale * vx, y0 + scale * vy
111        ax.fill(
112            [x0, x1],
113            [y0, y1],
114            facecolor='none',
115            edgecolor='k',
116            linewidth=.5,
117        )
118    ax.axis(lim)  # make sure figure is not rescaled by ifinite ray
119
120
121def regions(ax, **kw):
122    """
123    Plot regions labeled by region
124    """
125    regions = np.array(kw['regions'])
126    ax.scatter(regions[:, 0], regions[:, 1], marker='*', color='b')
127    for x, y, r, _ in regions:
128        ax.text(x, y, ' {:g}'.format(r), color='b', va='center')
129
130
131def triangle_attributes(ax, **kw):
132    """
133    Plot triangle attributes labeled by region
134    """
135    verts = np.array(kw['vertices'])
136    tris = np.array(kw['triangles'])
137    attrs = np.array(kw['triangle_attributes']).flatten()
138    centroids = verts[tris].mean(axis=1)
139    ax.scatter(
140        centroids[:, 0],
141        centroids[:, 1],
142        marker='.',
143        color='m',
144        zorder=1,
145    )
146    for (x, y), r in zip(centroids, attrs):
147        ax.text(x, y, ' {:g}'.format(r), color='m', zorder=1, va='center')
148