Polygon inclusion algorithm based on the winding number.
The module provides a class, PolygonRegion
, that implements the winding-number count, based on the algorithm description by Dan Sunday. [SUN]
(Taken from the class docstring.)
A simple polygon with 4 vertices.
>>> import numpy as np >>> np.set_printoptions(formatter={"bool": str, "int": str}) >>> points = np.array(((1.0, -1.0, -1.0, 1.0), ... (1.0, 1.0, -1.0, -1.0))) >>> poly = PolygonRegion(points) >>> print(poly.winding_number(np.array((0.0, 0.0)))) 1 >>> print(poly.winding_number(np.array(((0.5, 1.5, 0.9), ... (0.5, 0.5, -0.1))))) ... # doctest: +NORMALIZE_WHITESPACE [1 0 1]
A self-intersecting polygon.
>>> points = np.array(((1.0, -2.0, -2.0, 2.0, 2.0, -1.0, -1.0, 1.0), ... (2.0, 2.0, -2.0, -2.0, 1.0, 1.0, -1.0, -1.0))) >>> poly = PolygonRegion(points) >>> print(poly.winding_number(np.array((0.0, 0.0)))) 2 >>> print(poly.contains(np.array(((0.0, 1.5), ... (0.0, 1.5))))) ... # doctest: +NORMALIZE_WHITESPACE [True False]
Reversing the orientation of the polygon.
>>> points = points[::-1, :] >>> poly = PolygonRegion(points) >>> print(poly.winding_number(np.array((0.0, 0.0)))) -2
A polygon with a simple hole inside.
>>> points = np.array(((2.0, -2.0, -2.0, 2.0, 1.0, 1.0, -1.0, -1.0), ... (2.0, 2.0, -2.0, -2.0, 1.0, -1.0, -1.0, 1.0))) >>> poly = PolygonRegion(points) >>> print(poly.winding_number(np.array((0.0, 0.0)))) 0
The current implementation is a pure-Python one utilizing numpy
. The winding_number()
method does not use the if
(branch) statement, which is costly in the Python code. The implementation should work reasonably well for the usage pattern where the polygon region is fixed but the number of points to be tested for inclusion is large.
In the context of SVG files, the definition for a point being "inside" the polygon based on the winding number corresponds to the nonzero
option for the fill-rule
attribute of <polygon>
(and similar) elements. [MDN] The other rule, evenodd
, is equivalent to the "crossing number" rule described as an alternative definition in [SUN].