Details
To fragment polygons p1 and p2, we join their combined edge and vertex sets, adding new vertices wherever an edge of p1 crosses an edge of p2. The new set of edges and vertices bounds a finite set of simple polygons (i.e. topological disks), also called “fragments” of p1 and p2.
Fragments are extracted and returned in two classes. One class contains the intersection(s) and union of p1 and p2, while the other contains the pairwise complements between p1 and p2.
If the vertices of
p1 and
p2, have the same circularity (or handedness), then the intersection/union class falls under the
True key, while differences fall under the
False key.
If the circularity of
p1 and
p2 are opposite, then the
True/
False keys are transposed.
There are several polygon clipping algorithms. Transposition for opposite-handedness is consistent with set operations when considering circularity as the determining measure of whether the polygon's filled area is either interior or exterior to the boundary. Such a convention is relatively common in high-power clipping algorithms, and it is also a feature of the wedge product in symplectic geometry.
If the combination of
p1 and
p2 encloses a polygonal hole, it will become a fragment in the same class as the intersection(s). In this case the union needs a more complicated form,
Polygon[
frag1→
frag2], where
frag1 and
frag2 are outer and inner boundaries respectively. Considering the outer boundary as enclosing the figure's exterior (including the point at infinity), the union of all fragments should be an exact cover of the entire plane.
ResourceFunction["PlanarPolygonFragmentation"] takes one option "BinCount" →
n, with default value
n = 1. When
n is set to a positive integer greater than 1, the input vertices and edges are discretized into approximately
n2 bins, which allows intersections to be solved locally. For polygons with many edge segments, this saves considerable time by avoiding unnecessary, brute force calculation via
Outer. This improves speed, but in pathological cases can lead to incorrect results.
Even in cases where discretization is necessary, a law of diminishing returns applies. There is usually a best choice for "BinCount", which may require experimentation or heuristics to find. In the case of inputs with few edges, setting "BinCount" greater than 1 is not necessary.
Self-intersecting polygons and polygons with holes are not valid inputs. Should one desire, they can be broken up into lists of simple polygons, which can then be folded through the fragmentation process.
ResourceFunction["PlanarPolygonFragmentation"] can be used to solve planar clipping problems. Our algorithm is already more powerful and can be faster than the numerical standard Greiner-Hormann. In utilizing discrete methods,
ResourceFunction["PlanarPolygonFragmentation"] goes below the naive order
O(n*m) complexity limit, which was carried through the subsequent work "Clipping simple polygons with degenerate intersections" (see references below).