How to intersect multiple polygons? - algorithm

I am looking for an algorithm with the following input and output:
Input: A set of polygons in a plane. E.g. P1...Pn and S. (P1...Pn might be concave, S is convex.)
Output: The area of theset of polygons in this plane that equals the difference of S and the union of P1...Pn.
I found algorithms to intersect or merge TWO polygons. But since each of those operations might produce several polygons I createt tons of polygons if I did it naively.
So: How to handle the intersection of multiple polygons?
It would be ok, if all polygons are connected together since only the area is what I am after. My thought was to use directed polygons to simulate holes but then I again have the problem to find out if I have a "minimal representation" as n could blow up. [Do you understand what I am talking about? It's quite strange...)

You could throw all edges together into a sweep line algorithm. It may not be optimal (?) but at least you will get the minimal representation you are looking for.

One solution is to convert each polygon into a bunch of triangles. Once you do that it is fairly easy to find union/intersection/difference between a set of areas since you can perform the same functions trivially on a triangle (result on two triangles may include up to 6 triangles).

The most straightforward approach would be decomposing your concave polygons into convex ones. Then intersecting two convex polygons is almost trivial.

Related

calculating bounded polygon from intersecting linestrings

I am using boost geometry and I am trying to calculate a "bounded" polygon (see image below) from intersecting polylines (linestrings 2d in Boost geometry). Currently, my approach is i) to get all the intersection points between these lines and then ii) "split" each line at the intersection points. However, this algorithm is a little bit exhaustive. Does anyone know if boost geometry has something more efficient for this?
Moreover, how could I get the segment (or vector of points) for each linestring that lie withing two intersection points? For example, for the green linestring, if I have the two red intersection points, how can I get the linestring between these two points (vector of points containing the two red intersection points and the two interior blue points)? Is there any "split"-like functionality in boost geometry?
Any suggestion is much appreciated. Thanks a lot in advance.
From the given description, it seems that the (poly)lines intersect in pairs to form a single loop, so that the inner polygon is well defined. If this is not true, the solution is not unique.
As the number of lines is small, exhaustive search for the pairwise intersections will not be a big sin. For 5 (poly)lines, there are 10 pairs to be tried, while you expect 5 intersections. Forming the loop from the intersections is not a big deal.
What matters most is if Boost Geometry uses an efficient algorithm to intersect polylines. Unsure if this is documented. For moderate numbers of vertices (say below 100), this is not so important.
If the number of points is truly large, you can resort to an efficient line segment intersection algorithm, which lowers the complexity from O(n²+k) down to O((n+k) log n). See https://en.wikipedia.org/wiki/Bentley%E2%80%93Ottmann_algorithm. You can process all polylines in a single go.
If your polylines have specific properties, they can be exploited to ease the task.

Method to detect intersection between a rectangle and a polygon?

What is the best method to detect whether the red rectangle overlaps the black polygon? Please refer to this image:
There are four cases.
Rect is outside of Poly
Rect intersects Poly
Rect is inside of Poly
Poly is inside of Rect
First: check an arbitrary point in your Rect against the Poly (see Point in Polygon). If it's inside you are done, because it's either case 3 or 2.
If it's outside case 3 is ruled out.
Second: check an arbitrary point of your Poly against the Rect to validate/rule out case 4.
Third: check the lines of your Rect against the Poly for intersection to validate/rule out case 2.
This should also work for Polygon vs. Polygon (convex and concave) but this way it's more readable.
If your polygon is not convex, you can use tessellation to subdivide it into convex subparts. Since you are looking for methods to detect a possible collision, I think you could have a look at the GJK algorithm too. Even if you do not need something that powerful (it provides information on the minimum distance between two convex shapes and the associated witness points), it could prove to be useful if you decide to handle more different convex shapes.
Christer Ericson made a nice Powerpoint presentation if you want to know more about this algorithm. You could also take a look at his book, Real-Time Collision Detection, which is both complete and accessible for anyone discovering collision detection algorithms.
If you know for a fact that the red rectangle is always axis-aligned and that the black region consists of several axis-aligned rectangles (I'm not sure if this is just a coincidence or if it's inherent to the problem), then you can use the rectangle-on-rectangle intersection algorithm to very efficiently compute whether the two shapes overlap and, if so, where they overlap.
If you use axis-aligned rectangles and polygons consist of rectangles only, templatetypedef's answer is what you need.
If you use arbitrary polygons, it's a much more complex problem.
First, you need to subdivide polygons into convex parts, then perform collision detection using, for example, the SAT algorithm
Simply to find whether there is an intersection, I think you may be able to combine two algorithms.
1) The ray casting algorithm. Using the vertices of each polygon, determine if one of the vertices is in the other. Assuming you aren't worried about the actual intersection region, but just the existence of it. http://en.wikipedia.org/wiki/Point_in_polygon
2) Line intersection. If step 1 produces nothing, check line intersection.
I'm not certain this is 100% correct or optimal.
If you actually need to determine the region of the intersection, that is more complex, see previous SO answer:
A simple algorithm for polygon intersection

Efficient Packing Algorithm for Regular Polygons

I'm looking for a packing algorithm which will reduce a regular polygon into rectangles and right triangles. The algorithm should attempt to use as few such shapes as possible and should be relatively easy to implement (given the difficulty of the challenge).
If possible, the answer to this question should explain the general heuristics used in the suggested algorithm.
I think the answer is fairly simple for regular polygons.
Find an axis of symmetry, and draw a line between each vertex and its mirror. This divides the polygon into trapezoids. Each trapezoid can be turned into a rectangle and two right triangles.
It's not specifically rectangles + right triangles, but a good research point for looking into tesselating polygons is Voronoi Diagrams and Delaunay Triangulations and here and here.
In fact, if "just right triangles" is good enough, these are guaranteed to triangulate for you, and you can always split any triangle into two right triangles, if you really need those. Or you can chop off "tips" of triangles to make more right triangles and some rectangles out of the right-triangles.
You can also try ear-clipping, either by sweeping radially, if you know you have fairly regular polygons, or by "clipping the biggest convex chunk" off. Then, split each remaining triangle into two to create right triangles.
(source: eruciform.com)
You could try to make less breaks by sweeping one way and then the other to make a trapezoid and split it differently, but you then have to do a check to make sure that your sweep-line hasn't crossed another line someplace. You can always ear-clip, even with something practically fractal.
However, this sometimes creates very slim triangles. You can perform heuristics, like "take the biggest", instead of clipping continuously along the edge, but that takes more time, approaching O(n^2). Delaunay/Vornoi will do it more quickly in most cases, with less slim triangles.
You can try "cuting out" the largest rectangle that can fit in the polygon, leaving behind some leftovers. Keep repeating the cutting out of rectangles on the leftovers, until you end up with triangular pieces. Then, you can split them into two right triangles if necessary. I do not know if this will always yield solutions that will give you the least amount rectangles and right triangles.

Efficient Packing Algorithm for Irregular Polygons

I'm looking for a packing algorithm which will reduce an irregular polygon into rectangles and right triangles. The algorithm should attempt to use as few such shapes as possible and should be relatively easy to implement (given the difficulty of the challenge). It should also prefer rectangles over triangles where possible.
If possible, the answer to this question should explain the general heuristics used in the suggested algorithm.
This should run in deterministic time for irregular polygons with less than 100 vertices.
The goal is to produce a "sensible" breakdown of the irregular polygon for a layman.
The first heuristic applied to the solution will determine if the polygon is regular or irregular. In the case of a regular polygon, we will use the approach outlined in my similar post about regular polys: Efficient Packing Algorithm for Regular Polygons
alt text http://img401.imageshack.us/img401/6551/samplebj.jpg
I don't know if this would give the optimal answer, but it would at least give an answer:
Compute a Delaunay triangulation for the given polygon. There are standard algorithms to do this which will run very quickly for 100 vertices or fewer (see, for example, this library here.) Using a Delaunay triangulation should ensure that you don't have too many long, thin triangles.
Divide any non-right triangles into two right triangles by dropping an altitude from the largest angle to the opposite side.
Search for triangles that you can combine into rectangles: any two congruent right triangles (not mirror images) which share a hypotenuse. I suspect there won't be too many of these in the general case unless your irregular polygon had a lot of right angles to begin with.
I realize that's a lot of detail to fill in, but I think starting with a Delaunay triangulation is probably the way to go. Delaunay triangulations in the plane can be computed efficiently and they generally look quite "natural".
EDITED TO ADD: since we're in ad-hoc heuristicville, in addition to the greedy algorithms being discussed in other answers you should also consider some kind of divide and conquer strategy. If the shape is non-convex like your example, divide it into convex shapes by repeatedly cutting from a reflex vertex to another vertex in a way that comes as close to bisecting the reflex angle as possible. Once you've divided the shape into convex pieces, I'd consider next dividing the convex pieces into pieces with nice "bases", pieces with at least one side having two acute or right angles at its ends. If any piece doesn't have such a "base" you should be able to divide it in two along a diameter of the piece, and get two new pieces which each have a "base" (I think). This should reduce the problem to dealing with convex polygons which are kinda-sorta trapezoidal, and from there a greedy algorithm should do well. I think this algorithm will subdivide the original shape in a fairly natural way until you get to the kinda-sorta trapezoidal pieces.
I wish I had time to play with this, because it sounds like a really fun problem!
My first thought (from looking at your diagram above) would be to look for 2 adjacent right angles turning the same direction. I'm sure that won't catch every case where a rectangle will help, but from a user's point of view, it's an obvious case (square corners on the outside = this ought to be a rectangle).
Once you've found an adjacent pair of right angles, take the length of the shorter leg, and there's one rectangle. Subtract this from the polygon left to tile, and repeat. When there's no more obvious external rectangles to remove, then do your normal tiling thing (Peter's answer sounds great) on that.
Disclaimer: I'm no expert on this, and I haven't even tried it...

Polygon packing 2D

I have problem of packing 2 arbitrary polygons. I.e. we have 2 arbitrary polygons. We are to find such placement of this polygons (we could make rotations and movements), when rectangle, which circumscribes this polygons has minimal area.
I know, that this is a NP-complete problem. I want to choose an efficient algorithm for solving this problem. I' looking for No-Fit-Polygon approach. But I could't find anywhere the simple and clear algorithm for finding the NFP of two arbitrary polygons.
The parameter space does not seem too big and testing it is not too bad either. If you fix one polygon, the other ploygon can be shifted along x-axis by X, and shifted along y-axis by Y and rotated by r.
The interesting region for X and Y can be determined by finding some bounding box for for the polygons. r of course is between and 360 degrees.
So how about you tried a set of a set of equally spaced intervals in the interesting range for X,Y and r. Perhaps, once you found the interesting points in these dimensions, you can do more finer grained search.
If its NP-complete then you need heuristics, not algorithms. I'd try putting each possible pair of sides together and then sliding one against the other to minimise area, constrained by possible overlap if they are concave of course.
There is an implementation of a robust and comprehensive no-fit polygon generation in a C++ library using an orbiting approach: https://github.com/kallaballa/libnfporb
(I am the author of libnfporb)

Resources