Skip to content

Commit 4abcb69

Browse files
authored
Merge pull request #151 from csiro-coasts/optimise-triangulation
Generate a fan triangulation for convex polygons
2 parents 2d2248c + c8b9fcb commit 4abcb69

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

docs/releases/development.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ Next release (in development)
44

55
* Fix invalid geometry being generated for 'river' cells
66
in CFGrid2D datasets with no cell bounds (:pr:`154`).
7+
* Improved speed of triangulation for convex polygons
8+
(:pr:`151`).

src/emsarray/operations/triangulate.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
from typing import cast
55

6+
import numpy
67
import xarray
78
from shapely.geometry import LineString, MultiPoint, Polygon
89

@@ -149,6 +150,19 @@ def _triangulate_polygon(polygon: Polygon) -> list[tuple[Vertex, Vertex, Vertex]
149150
if not polygon.is_simple:
150151
raise ValueError("_triangulate_polygon only supports simple polygons")
151152

153+
# The 'ear clipping' method used below is correct for all polygons, but not
154+
# performant. If the polygon is convex we can use a shortcut method.
155+
if polygon.equals(polygon.convex_hull):
156+
# Make a fan triangulation. For a polygon with n vertices the triangles
157+
# will have vertices:
158+
# (1, 2, 3), (1, 3, 4), (1, 4, 5), ... (1, n-1, n)
159+
exterior_vertices = numpy.array(polygon.exterior.coords)[:-1]
160+
num_triangles = len(exterior_vertices) - 2
161+
v0 = numpy.broadcast_to(exterior_vertices[0], (num_triangles, 2))
162+
v1 = exterior_vertices[1:-1]
163+
v2 = exterior_vertices[2:]
164+
return list(zip(map(tuple, v0), map(tuple, v1), map(tuple, v2)))
165+
152166
# This is the 'ear clipping' method of polygon triangulation.
153167
# In any simple polygon, there is guaranteed to be at least two 'ears'
154168
# - three neighbouring vertices whos diagonal is inside the polygon.

0 commit comments

Comments
 (0)