I have a set of simple (no holes, no self-intersections) polygons, and I need to check that they don't intersect each other (one can be entirely contained in another; that is okay). I can check this by simply checking the per-vertex inside-ness of one polygon versus other polygons.
I also need to determine the containment tree, which is the set of relationships that say which polygon contains any given polygon. Since no polygon can intersect any other, then any contained polygon has a unique container; the "next-bigger" one. In other words, if A contains B contains C, then A is the parent of B, and B is the parent of C, and we don't consider A the parent of C.
The question: How do I efficiently determine the containment relationships and check the non-intersection criterion? I ask this as one question because maybe a combined algorithm is more efficient than solving each problem separately. The algorithm should take as input a list of polygons, given by a list of their vertices. It should produce a boolean B indicating if none of the polygons intersect any other polygon, and also if B = true, a list of pairs (P, C) where polygon P is the parent of child C.
This is not homework. This is for a hobby project I am working on.
To be able to decide whether two convex polygons are intersecting (touching each other) we can use the Separating Axis Theorem. Essentially: If two convex polygons are not intersecting, there exists a line that passes between them. Such a line only exists if one of the sides of one of the polygons forms such a line.
Line crosses the polygon if and only if it crosses one of its edges (ignoring for a second the cases when it passes through a vertex). So, in your case you just need to test all edges of your polygon against your line and see if there's an intersection. and then calculate the value Ax + By + C for points a and b .
What is the point of intersection of two sides of a polygon? Hi Tyler. Formally, mathematicians call them vertices (plural for vertex). But more casually, we just call them corners.
A point is inside the polygon if either count of intersections is odd or point lies on an edge of polygon. If none of the conditions is true, then point lies outside.
First, your algorithm for testing containment does not test for intersection correctly. Imagine two rectangles like this:
+--+
+--+--+--+
| | | |
+--+--+--+
+--+
Vertices would be at (1, 2) (1,3) (4,2) (4,3) and (2,1) (3,1) (2,4) (3,4) -- no vertex lies inside any polygon, but the polygons do in fact intersect.
To test for this kind of intersection, it is necessary to determine whether any of the polygons' edges intersect. For your purposes, if edges intersect but one polygon is not contained within the other, then you know they overlap in a non-permitted fashion.
As for determining the containment tree, one way to do that is to sort the polygons from smallest to largest by area. Provided the polygons don't overlap-without-containment, then any polygon's parent in the tree will be the first containing polygon coming after it in the list.
Edit: Oh, also, I advise writing a fast bounding-box or bounding-circle overlap routine, and using that to avoid having to do all the line intersection and vertex containment tests. If that still isn't fast enough, you probably want to build a quad or BSP tree; that will complicate things quite a bit but will also eliminate a lot of the intersection checks entirely.
Determining whether none of the polygons intersect can be done in O(n*log(n))
by applying the Shamos-Hoey algorithm. Depending on what the Shamos-Hoey algorithm returns, a polygon Pi contains polygon Pj if any vertex from Pj is inside Pi which is done in O(n)
for two polygons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With