(For my purposes "polygons" do not included self-intersecting polygons or polygons with holes - just simple (concave or convex) polygons.)
I have found various suggestions for this problem, which are mainly based around the following:
If there are no intersections between the edges of Polygon1 and the edges of Polygon2, and at least one vertex of Polygon2 is "inside" Polygon1, then Polygon1 contains Polygon2.
(eg see the accepted answer here)
However, the devil is in the detail:
Does "inside" Polygon1 include "on an edge of" Polygon1? Clearly it must, otherwise in diagram F (see the image linked below) Polygon2 (red) would have no vertex "inside" Polygon1 (blue) and so fail the above test, when it should pass.
Does an "intersection" of two edges include a point at the end of one of the edges (ie a vertex)? If "yes", then diagrams A and E below have intersections and so fail the test when they should pass. But if "no", then diagrams B, C and D have no intersections and so pass the test when they should fail.
(NB diagrams A, B and C have vertices of Polygon2 on edges of Polygon1, diagrams D and E vice versa.)
I can't work out a condition to test which distinguishes correctly between these various cases. I'd be grateful for any pointers?
The sweepline algorithm (as nearly always) gives us the most robust and efficient solution.
In its simplest form, sweepline finds all line segment intersections. It is trivial to extend it to check polygon containment. You just keep track which line or point belong to each polygon. At any step of the algorithm, the intersection of the sweeping line and the interior of each polygon is a finite set of vertical segments. You have these cases:
This takes care of all edge cases. If you want to classify your cases A, E and F as "inside", test only intersection of segment interiors (i.e. segments (0,1) and (1,2) are not intersecting, and (0,1) is inside of (0,2)). Otherwise, just treat the above cases as proper intersections.
If at some step there are two edges that are collinear and parallel to the sweep line and they intersect, it could be a bit hard to decide. However all edge cases can be resolved by calculating sweepline-polygon intersection not at vertices (as is normal to the sweepline algorithm) but between vertices (say at a midpoint between the current vertex and the next). This way only polygon interiors (not boundaries) are ever considered.
In effect the algorithm breaks up our polygons into a bunch of little trapezoids, sandwiched between parallel (say vertical) lines drawn through each vertex. It's very easy to check whether these trapezoids are intersecting, or disjoint, or completely contain one another. An illustration can be found here.
Edit: clarified some wording. Edit 2: found an edge case ;)
If we're trying to check whether polygon B is inside polygon A:
Like mentioned in the answer you linked to, start off doing a line intersection test for each pair of edges, one from each polygon. If any edges intersect (excluding vertices that lie on edges and common vertices), B is not inside A.
If a vertex V of one polygon lies on an edge of the other, treat that edge instead as 2 edges, with the vertex V as a new vertex for that polygon.
Now we only have to think about common vertices.
For each common vertex V:
Use this to determine which edges are adjacent.
If EB1 and EB2 are not adjacent, B is not within A.
If EB2 lies on A (that is, EB2 lies on EA2, i.e. they have an equal gradient), we don't yet know whether B is in A.
In this case, we'll need to keep track of on which side EB1 was and move on to the adjacent vertex VB (the other vertex of EB2), and check whether EB3, the edge after EB2, is on the same side as EB1. If they're on the different sides, B is not inside A.
If EB3 is also on A, we need to check EB4, and so on, until we find one that isn't.
If both EB1 is on EA1 and EB2 is on EA2, we need to move in both directions to determine on which side we need to be. If all edges of B lie on A, A is equal to B.
(Note: if, for example, EB2 lies on EA1 instead of EA2, you can simply rename them to fulfill the above condition)
All of this is assuming we don't allow polygons that intersect with themselves - allowing that will probably break this.
There may be some non-trivial details here, but this should be a decent starting point.
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