Polygon is not able to handle nested and overlapping contours correctly. This is because the underlying structures and functions of GPC have only a flat list of contours (solids and holes) without any hierarchy. A hole is not bound to a single solid but is valid for the whole Polygon. If your Polygon object contains more than one solid contour and at least one hole you may not get the results you expected.
One big problem is that it’s very easy to create such Polygon objects using standard operations! An example (thanks to Willie Maddox) illustrates this:
from Polygon import Polygon
poly3 = Polygon(((-3,-3),(-3,3),(3,3),(3,-3)))
poly2 = Polygon(((-2,-2),(-2,2),(2,2),(2,-2)))
poly1 = Polygon(((-1,-1),(-1,1),(1,1),(1,-1)))
p = poly3 - poly2 + poly1
p will be a square (poly3) with a hole (poly2) and a second solid contour (poly1) inside the hole:
Polygon: 0:Contour: [0:1.0, -1.0] [1:-1.0, -1.0] [2:-1.0, 1.0] [3:1.0, 1.0] 1:Hole : [0:2.0, 2.0] [1:-2.0, 2.0] [2:-2.0, -2.0] [3:2.0, -2.0] 2:Contour: [0:3.0, -3.0] [1:-3.0, -3.0] [2:-3.0, 3.0] [3:3.0, 3.0]
But the hole is not bound to the outer contour, it is valid for the inner contour as well and covers it completely. If you do further operations with this Polygon the results may be wrong. p.isInside(0,0) will return False because the point is inside a hole, even if it is inside a second solid contour.
You may use the method p.simplify() to make the Polygon p valid for further operations, but you may lose overlapping contours. The method first adds all solid contours and then substracts all holes. In the example above the inner solid contour is lost:
Polygon: 0:Hole : [0:2.0, 2.0] [1:-2.0, 2.0] [2:-2.0, -2.0] [3:2.0, -2.0] 1:Contour: [0:3.0, -3.0] [1:-3.0, -3.0] [2:-3.0, 3.0] [3:3.0, 3.0]
Unfortunately there is no easy way to change this behaviour. The main problem is located in the data structures of GPC, which is a core component of Polygon and can’t be replaced easily.
Hello, I have been struggeling with this when developing Blender CAM, because polygon is the only accessible python library that works easily on all platforms and with python 3.
I developed a set of functions to analyze hierarchy, so it kind of works now… if you want, you can peek in the blender CAM code on how I solved it, but it’s rather hack-ish 😉