triangulate_polygon
triangulate_polygon(V, F=None, a=0.0, q=np.pi / 8.0, steiner=True)
Triangulates a two-dimensional polygon
Computes a constrained Delaunay triangulation of the region bounded by a given polygon, optionally refined to satisfy a maximum area and a minimum angle constraint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
V
|
numpy double array
|
Matrix of polygon vertex coordinates (must be two-dimensional) |
required |
F
|
numpy int array, optional (default None)
|
Matrix of polygon edge indices into V. If None, the convex hull of V is triangulated. Holes are detected automatically: a closed loop nested inside another one is a hole, a closed loop nested inside a hole is filled again, and so on |
None
|
a
|
double, optional (default 0.0)
|
Maximum area of any output triangle. If 0., there is no maximum area constraint. A maximum area also sets the resolution of the boundary: the edges of F are cut into pieces no longer than sqrt(a) before the polygon is triangulated, so a small a adds vertices along the boundary as well as inside |
0.0
|
q
|
double, optional (default np.pi/8)
|
Minimum angle of any output triangle, in radians |
pi / 8.0
|
steiner
|
bool, optional (default True)
|
Whether the insertion of Steiner points on the polygon boundary is allowed. Without them the edges of F are all edges of the output, and a and q hold wherever they can be met without splitting one. This is not enforced by CDT, but by our own hack. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
V2 |
numpy double array
|
Matrix of triangle mesh vertex coordinates (two-dimensional) |
F2 |
numpy int array
|
Matrix of triangle mesh indices into V2 |
Notes
This uses Artem Amirkhanov's (artem-ogre) CDT library,
https://github.com/artem-ogre/CDT.
The syntax is inspired by libigl's triangulate.h,
https://github.com/libigl/libigl/blob/main/include/igl/triangle/triangulate.h.
The area and angle constraints are enforced by CDT's Delaunay refinement
with some modifications to make the area constraints work, and to make
both constraints work at the same time.
The vertices in V must be distinct, and the edges in F must not cross each other except at their endpoints, so a closed polyline whose last vertex repeats its first must have that repeat removed.
Every vertex of V ends up in the output, used by its triangles, including the vertices that no edge of F refers to. Appending unreferenced points to V is how you force the triangulation to contain points of your choosing. They have to lie inside the polygon: a vertex outside it, or inside one of its holes, is an error. A vertex close enough to a hole's boundary counts as lying on the boundary, and is included.
Both limits can be asked for at once, and the refinement alternates between them until neither has anything left to do.
Refinement to ensure a and q limits hold stops after 100 passes or 1000000 vertices, whichever comes first.
Examples:
# Triangulate the unit square
V = np.array([[0.,0.],[1.,0.],[1.,1.],[0.,1.]])
F = np.array([[0,1],[1,2],[2,3],[3,0]])
V2,F2 = gpytoolbox.triangulate_polygon(V,F,a=0.01)
Source code in src/gpytoolbox/triangulate_polygon.py
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 105 106 107 108 109 110 111 112 | |