Given a general polygon P (might contain holes) and a number of rectangles K, I want to find K rectangles {r1,r2,...,rk} such that the polygon is contained in the union of these rectangles. Also, I want to minimize the area of the union of the rectangles.
Note that the rectangles may overlap each other. Also, they're axis-aligned.
As an example, for K=1, the algorithm should report the minimum bounding box.
I've read some papers on the subject, namely "A linear-time approximation algorithm for minimum rectangular covering" and "Covering a polygonal region by rectangles".
The first article approaches the problem by dividing the polygon into simpler polygons, but it considers only rectangles that are within the polygon.
The second article assumes that the rectangles dimension are fixed and simply translates them around and tries to cover the polygon with the minimum number of rectangles.
I know that there is an article named "covering a polygon with few rectangles" that has what I believe to be exactly what I'm looking for, but I would have to pay in order to have access to it and I'd like to dig depeer before spending any money.
Since this is an np-complete or np-hard (not sure) problem, i'm not expecting fast exact algorithms, therefore approximations are also relevant.
Does anyone have knowledge of previous work on this particular problem? Any work that might relate is also welcome. Also, if you have ideas on how to address the problem it would be great!
Thanks in advance.
Related
I am looking for an algorithm or alogirthms I can emply to take a non-intersecting, concave polygon and find a minimum set of edge aligned rectangles partitioning the polygon. The rectangles can overlap (preferably minimally).
I was considering using ear-clipping to find the minimum triangles. I could build rectangles from those triangles. I guess each triangle could have a set of rectangles. Then I examine the rectangles and merge with other, collinear-ish rectangles. I don't know if that is a good approach or not.
I imagine the problem sounds a bit subjective, but I still think there is a good approach for solving this problem with known algorithms and a bit of heuristics.
*EDIT: More with heuristics, I can expect axis-aligned rectangles to be, incidentally, a common occurence.
**EDIT: I can also expect zero of the convex angles to be less than 90 degrees.
Fair warning, I have no background in computation geometry, so I'm basically just making things up. This would be my initial approach to the problem.
Figure out if the polygon is convex. If so, cover it with one rectangle aligned with an edge. To do this, I'd say just try all of the edges and see which one gives the rectangle with the smallest area. There may be a better way to determine which edge to use, but again, no background in this stuff.
If the polygon is concave, let's call an edge a "concave edge" if it's not on the convex hull of the polygon. Find a concave edge in the polygon, and extend it to cut the polygon into two or more new, smaller polygons. Recurse on each of the child polygons.
If the polygon has few enough edges, I think that an exhaustive search would be reasonable, and just pick the matching which covers your heuristic best (fewest rectangles, least amount of space not within the polygon covered, amount of overlap, some function of the previous factors, etc.)
This question already has answers here:
Algorithm for finding the fewest rectangles to cover a set of rectangles without overlapping
(2 answers)
Closed 5 years ago.
Simplified, I have to solve the following problem:
You have a 2-dimensional array filled with 0s and 1s. Find the minimum number of rectangles such that they cover all 1s. Rectangles should not overlap.
The function signature might look like:
List<Rectangle> FindCoveringRectangles(bool[,] array)
I already have a solution that is "good enough" but doesn't always find the minimum number of rectangles. I'd like to know if there is some well known and efficient algorithm that can be applied to solve this problem?
Example:
An input array of:
..........
.1.....11.
.......11.
...111....
...111....
...111....
....1111..
....1111..
......11..
..........
(0s replaced by dots for readability)
Might result in the following rectangles:
(2,2,2,2),
(2,8,3,9),
(4,4,6,6),
(7,5,8,8),
(9,7,9,8)
(top, left, bottom, right), 1-based
There can be more than one solution, but one is enough.
This is a matching problem of a kind, that could easily have shown NP-hard. However it seems there is actually a very fast solution!
Using a bfs flood-fill you can find each connected component, O(n). Hence wlog we can assume that we just have to fill one connected area.
If the area doesn't have holes in it, you can use the algorithm described in this paper (or here on google scholar.)
An O(n log log n) algorithm is proposed for minimally rectangular partitioning a simple rectilinear polygon. For any simple rectilinear polygon P, a vertex-edge visible pair is a vertex and an edge that can be connected by a horizontal or vertical line segment that lies entirely inside P. It is shown that, if the vertex-edge visible pairs are found, the maximum matching and the maximum independent set of the bipartite graph derived from the chords of a simple rectilinear polygon can be found in linear time without constructing the bipartite graph. Using this algorithm, the minimum partition problem for convex rectilinear polygons and vertically (horizontally) convex rectilinear polygons can be solved in O(n) time
Some of the papers referred to also cover the case of an area with holes. These run in O(n^(3/2)logn) though, but they still seam pretty good.
Alternatively, one thing you might do is solving the problem without holes, solving the problem for each hole, and then subtract. This might not give an optimal solution though, but would keep the runtime.
You could also try and split the shape in its different topological parts, but that would likely run exponentially in the number of holes.
Thirdly you could try to adapt the proposed algorithm for the more general case, but it might be hard.
I have a detailed 2D polygon (representing a geographic area) that is defined by a very large set of vertices. I'm looking for an algorithm that will simplify and smooth the polygon, (reducing the number of vertices) with the constraint that the area of the resulting polygon must contain all the vertices of the detailed polygon.
For context, here's an example of the edge of one complex polygon:
My research:
I found the Ramer–Douglas–Peucker algorithm which will reduce the number of vertices - but the resulting polygon will not contain all of the original polygon's vertices. See this article Ramer-Douglas-Peucker on Wikipedia
I considered expanding the polygon (I believe this is also known as outward polygon offsetting). I found these questions: Expanding a polygon (convex only) and Inflating a polygon. But I don't think this will substantially reduce the detail of my polygon.
Thanks for any advice you can give me!
Edit
As of 2013, most links below are not functional anymore. However, I've found the cited paper, algorithm included, still available at this (very slow) server.
Here you can find a project dealing exactly with your issues. Although it works primarily with an area "filled" by points, you can set it to work with a "perimeter" type definition as yours.
It uses a k-nearest neighbors approach for calculating the region.
Samples:
Here you can request a copy of the paper.
Seemingly they planned to offer an online service for requesting calculations, but I didn't test it, and probably it isn't running.
HTH!
I think Visvalingam’s algorithm can be adapted for this purpose - by skipping removal of triangles that would reduce the area.
I had a very similar problem : I needed an inflating simplification of polygons.
I did a simple algorithm, by removing concav point (this will increase the polygon size) or removing convex edge (between 2 convex points) and prolongating adjacent edges. In any case, doing one of those 2 possibilities will remove one point on the polygon.
I choosed to removed the point or the edge that leads to smallest area variation. You can repeat this process, until the simplification is ok for you (for example no more than 200 points).
The 2 main difficulties were to obtain fast algorithm (by avoiding to compute vertex/edge removal variation twice and maintaining possibilities sorted) and to avoid inserting self-intersection in the process (not very easy to do and to explain but possible with limited computational complexity).
In fact, after looking more closely it is a similar idea than the one of Visvalingam with adaptation for edge removal.
That's an interesting problem! I never tried anything like this, but here's an idea off the top of my head... apologies if it makes no sense or wouldn't work :)
Calculate a convex hull, that might be way too big / imprecise
Divide the hull into N slices, for example joining each one of the hull's vertices to the center
Calculate the intersection of your object with each slice
Repeat recursively for each intersection (calculating the intersection's hull, etc)
Each level of recursion should give a better approximation.... when you reached a satisfying level, merge all the hulls from that level to get the final polygon.
Does that sound like it could do the job?
To some degree I'm not sure what you are trying to do but it seems you have two very good answers. One is Ramer–Douglas–Peucker (DP) and the other is computing the alpha shape (also called a Concave Hull, non-convex hull, etc.). I found a more recent paper describing alpha shapes and linked it below.
I personally think DP with polygon expansion is the way to go. I'm not sure why you think it won't substantially reduce the number of vertices. With DP you supply a factor and you can make it anything you want to the point where you end up with a triangle no matter what your input. Picking this factor can be hard but in your case I think it's the best method. You should be able to determine the factor based on the size of the largest bit of detail you want to go away. You can do this with direct testing or by calculating it from your source data.
http://www.it.uu.se/edu/course/homepage/projektTDB/ht13/project10/Project-10-report.pdf
I've written a simple modification of Douglas-Peucker that might be helpful to anyone having this problem in the future: https://github.com/prakol16/rdp-expansion-only
It's identical to DP except that it pushes a line segment outwards a bit if the points that it would remove are outside the polygon. This guarantees that the resulting simplified polygon contains all the original polygon, but it has almost the same number of line segments as the original DP algorithm and is usually reasonably good at approximating the original shape.
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...
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)