pyclipper
Pyclipper is a Cython wrapper that exposes the public functions and classes of the C++ translation of the Angus Johnson's Clipper library (version 6.4.2). It provides robust algorithms for 2D polygon clipping (intersection, union, difference, XOR) and offsetting (inflating/deflating). The library is actively maintained, with the latest version being 1.4.0, and releases occur as needed for updates or Python compatibility.
Warnings
- breaking The global `SCALING_FACTOR` variable was removed in version 1.0.0 (and its deprecated usage removed in 1.3.0). This change significantly impacted how floating-point coordinates were handled, as automatic scaling is no longer performed.
- gotcha The underlying Clipper library operates exclusively on integer coordinates to ensure numerical robustness. Providing floating-point coordinates directly can lead to precision issues or unexpected behavior.
- breaking Python 3.9 support was dropped, and Python 3.10 or newer is now required.
- gotcha When building `pyclipper` from source (e.g., from a Git clone or sdist), Cython is now always a mandatory dependency, even if pre-generated C++ sources are present in the sdist.
Install
-
pip install pyclipper
Imports
- pyclipper
import pyclipper
Quickstart
import pyclipper
# Subject polygon (a list of paths, where a path is a list of (x, y) tuples)
subj = (
((180, 200), (260, 200), (260, 150), (180, 150)),
((215, 160), (230, 190), (200, 190))
)
# Clip polygon
clip = ((190, 210), (240, 210), (240, 130), (190, 130))
# Initialize Clipper object
pc = pyclipper.Pyclipper()
# Add paths to the Clipper object
pc.AddPath(clip, pyclipper.PT_CLIP, True) # Clip path is a closed polygon
pc.AddPaths(subj, pyclipper.PT_SUBJECT, True) # Subject paths are closed polygons
# Execute the clipping operation (intersection in this case)
solution = pc.Execute(
pyclipper.CT_INTERSECTION,
pyclipper.PFT_EVENODD, # Fill type for subject polygons
pyclipper.PFT_EVENODD # Fill type for clip polygons
)
print(f"Intersection solution: {solution}")
# Example of offsetting
subj_offset = ((180, 200), (260, 200), (260, 150), (180, 150))
pco = pyclipper.PyclipperOffset()
pco.AddPath(subj_offset, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
solution_offset = pco.Execute(-7.0) # Offset by -7 units (inward)
print(f"Offset solution: {solution_offset}")