Cover a Concave Polygon with a minimum number of rectangles - computational-geometry

I am tyring to cover a simple concave polygon with a minimum rectangles. My rectangles can be any length, but they have maximum widths, and the polygon will never have an acute angle.
I thought about trying to decompose my concave polygon into triangles that produce a set of minimumally overlapping rectangles minimally bounding each triangle and then merging those rectangles into larger ones. However, I don't think this will work for small notches in the edges of the polygon. The triangles created by the reflex vertices on those notches will create the wrong rectangles. I am looking for rectangles that will span/ignore notches.
I don't really know anything about computational geometry, so I'm not really sure on how to begin asking the question.
I found other posts that were similar, but not what I need:
split polygon into minimum amount of rectangles and triangles
Covering an arbitrary polygon with minimum number of squares
Find $k$ rectangles so that they cover the maximum number of points
Algorithm for finding the fewest rectangles to cover a set of rectangles
Some examples: Black is the input. Red is the acceptable output.
Another exmaple: The second output is prefered. However, generating both outputs and using another factor to determine preference is probably necessary and not the responsibility of this algorithm.
Polygons that mimic curves are extremely rare. In this scenario much of the area of the rectangles is wasted. However, this is acceptable because each rectangle obeys the max width constraint.
Also, I found this article to be close to what I need:
Covering with rectangular pieces by Paul Iacob, Daniela Marinescu, and Cristina Luca
Maybe a better question is "How can I identify rectangular-like portions of a concave polygon?"
Here is an image showing the desired implementation:
The green is the actual material usage. The red rectangles are the layouts. The blue is the MBR of the entire polygon. I am thinking I should try to get little MBRs and fill them in. The 2-3 green rectangles in the upper left corner that terminate into the middle of the polygon are expensive. That is what I want to minimize. The green rectangles have a min and max width and height, but I can use as many rows and columns necessary to cover a region. Again, I must minimize the number of rectangles that do not span across the input. I can also modify the shape of the green rectangle to fit in small places that is also very expensive. In other words, getting as many rectangles as possible to span as much as possible is ideal.
Maybe I should simply be trying to identify rectangular regions like this:
Or, perhaps a better approach would be using largest-inscribed rectangles instead of MBRs. I could continually cut my polygon down using rectangles until I am left with regions were the largest-inscribed rectangle is not sharing an edge with the original polygon. The remaining regions would have to be handled with a heuristic approach.
I've been working with the engineering and manufacturing departments at my company to bring more clarificaiton to this problem. I am still waiting to confirm, but I am now thinking an algorithm that would return sets of largest inscribed rectangles would work. While it does not completely cover the shape, it would give preference to the orthognal regions while leaving the non-orthogonal regions to some heuristics. The only trick is to maxamize those orthogonal regions.

Related

Filling a polygon with rectangles

I have a fairly smooth polygon, say an ellipse with bulges and dents converted to polygon straight lines. I wish to fill this polygon with as few rectangles as possible, but as many as to maintain accuracy in small corners in the polygon. The rectangles may be any size, and of any amount.
The reason for this is doing a hit test on a web page on the polygon. The only practical way is to fill it with divs and do hit tests on all the divs.
Of course there will be a minimum square size for any rectangle, lest we more than just approximate the polygon and recreate it with pixel size rectangles.
In the general case, if you want to exactly represent a digital shape with rectangles, you will need at least as many rectangles as there are pixels on the outline forming corners. If you think of a digital straight edge at 45°, that means one rectangle per pixel. This is a serious limitation. (And don't even think of non-digital shapes.)
This said, you accept to approximate the shape with a certain error, and I suggest that you first shrink the shape by a constant factor, up to you: you will overlay a grid on the shape an decide whether every tile belongs to the shape or not. Doing this, you turn your shape in a binary image with "big pixels", and the challenge is now to decompose this image in rectangles (exactly this time).
I suggest a simple greedy strategy such that you try to find a large rectangle that fits entirely, and then repeat with the parts that remain.
If you apply a morphological erosion operation with a larger and larger rectangular structuring element, you will find the largest rectangle the fits in the shape image. In theory, you should try all combinations of width and height and keep the largest area or perimeter; this is a large amount of work. I would recommend to try with growing squares first, and when you found the largest square to continue in the direction that allows it.
After you have found a large rectangle, erase it from the shape image and start again, until you completely erase it.

algorithm for optimal subdivision (i.e. tessellation / partitioning) of 2d polygons into smaller polygons?

I've got some 2D polygons, each as a list of clockwise coordinates. The polygons are
simple (i.e. they may be concave but they don't intersect themselves) and they don't overlap eachother.
I need to subdivide these polygons into smaller polygons to fit a size constraint. Just like the original polygons, the smaller ones should be simple (non-self-intersecting) and the constraint is they should each fit within one 'unit square' (which, for sake of simplicity, I can assume to be 1x1).
The thing is, I need to do this as efficiently as possible, where 'efficient' means the lowest number of resulting (small) polygons possible. Computation time is not important.
Is there some smart algorithm for this? At first I thought about recursively subdividing each polygon (splitting it in half, either horizontally or vertically whichever direction is larger) which works, but I don't seem to get very optimal results with this. Any ideas?
Draw a circle with a center of one of the initial points of initial polygon and radius of your desired length constraint.
The circle will intersect at least two lines at two points. Now you have your first triangle by the biggest as possible. Then choose those intersections as next target. Do until there is no initial points left outside. You have your triangles as large as possible(so as few as possible)
Do not account the already-created triangle edges as an intersection point.
Resulting polygons are not always triangle, they can be quads too. Maybe larger point-numbers too!
They all just nearly equal to the desired size.
Fine-tuning the interior parts would need some calculation.
I suggest you use the following:
Triangulate the polygon, e.g. using a sweep line algorithm.
Make sure all the triangles do not violate the constraint. If one violates the constraint, first try edge-flips to fix it, otherwise subdivide on the longest edge.
Use dynamic programming to join the triangles, while maintaining the constraint and only joining adjacent polygons.

Area of Intersection of Two Rotated Rectangles

I have two 2D rectangles, defined as an origin (x,y) a size (height, width) and an angle of rotation (0-360°). I can guarantee that both rectangles are the same size.
I need to calculate the approximate area of intersection of these two rectangles.
The calculation does not need to be exact, although it can be. I will be comparing the result with other areas of intersection to determine the largest area of intersection in a set of rectangles, so it only needs to be accurate relative to other computations of the same algorithm.
I thought about using the area of the bounding box of the intersected region, but I'm having trouble getting the vertices of the intersected region because of all of the different possible cases:
I'm writing this program in Objective-C in the Cocoa framework, for what it's worth, so if anyone knows any shortcuts using NSBezierPath or something you're welcome to suggest that too.
To supplement the other answers, your problem is an instance of line clipping, a topic heavily studied in computer graphics, and for which there are many algorithms available.
If you rotate your coordinate system so that one rectangle has a horizontal edge, then the problem is exactly line clipping from there on.
You could start at the Wikipedia article on the topic, and investigate from there.
A simple algorithm that will give an approximate answer is sampling.
Divide one of your rectangles up into grids of small squares. For each intersection point, check if that point is inside the other rectangle. The number of points that lie inside the other rectangle will be a fairly good approximation to the area of the overlapping region. Increasing the density of points will increase the accuracy of the calculation, at the cost of performance.
In any case, computing the exact intersection polygon of two convex polygons is an easy task, since any convex polygon can be seen as an intersection of half-planes. "Sequential cutting" does the job.
Choose one rectangle (any) as the cutting rectangle. Iterate through the sides of the cutting rectangle, one by one. Cut the second rectangle by the line that contains the current side of the cutting rectangle and discard everything that lies in the "outer" half-plane.
Once you finish iterating through all cutting sides, what remains of the other rectangle is the result.
You can actually compute the exact area.
Make one polygon out of the two rectangles. See this question (especially this answer), or use the gpc library.
Find the area of this polygon. See here.
The shared area is
area of rectangle 1 + area of rectangle 2 - area of aggregated polygon
Take each line segment of each rectangle and see if they intersect. There will be several possibilities:
If none intersect - shared area is zero - unless all points of one are inside the other. In that case the shared area is the area of the smaller one.
a If two consecutive edges of one rectactangle intersect with a single edge of another rectangle, this forms a triangle. Compute its area.
b. If the edges are not consequtive, this forms a quadrilateral. Compute a line from two opposite corners of the quadrilateral, this makes two triangles. Compute the area of each and sum.
If two edges of one intersect with two edges of another, then you will have a quadrilateral. Compute as in 2b.
If each edge of one intersects with each edge of the other, you will have an octagon. Break it up into triangles ( e.g. draw a ray from one vertex to each other vertex to make 4 triangles )
#edit: I have a more general solution.
Check the special case in 1.
Then start with any intersecting vertex, and follow the edges from there to any other intersection point until you are back to the first intersecting vertex. This forms a convex polygon. draw a ray from the first vertex to each opposite vetex ( e.g. skip the vertex to the left and right. ) This will divide it into a bunch of triangles. compute the area for each and sum.
A brute-force-ish way:
take all points from the set of [corners of
rectangles] + [points of intersection of edges]
remove the points that are not inside or on the edge of both rectangles.
Now You have corners of intersection. Note that the intersection is convex.
sort the remaining points by angle between arbitrary point from the set, arbitrary other point, and the given point.
Now You have the points of intersection in order.
calculate area the usual way (by cross product)
.

How to calculate the area of multiple polygons?

I posted some days ago this question: How to intersect multiple polygons?. Now I implemented a sweep line algorithm as recommended (concrete the one from Martinez, Rueda and Feito).
The result is a set of polygons that do not overlap. But these polygons can contain each other (holes) or touch the boundaries (being a hole or an island polygon).
A picture of what I mean:
I think this should cover all the special cases; intersections are handled by the sweep line algorithm.
Now I need the area of the polygons (marked gray). My first idea was to add polygon by polygon and to check if they contain each other and use some intelligent selection mechanism to only select the needed polygons. But this generates some O(n^2) algorithm: For each polygon to process, every edge has to be compared to every edge that is already processed.
Not that good. Can you give me a hint how to calculate the total area?
The standard vertex order is counterclockwise for polygons and clockwise for holes. If you store your data using this convention, just compute the area with the standard polygon area calculation method. Areas of the holes will be negative.
If you have them in some other order, then you have a problem. Better fix it now.

Find Minimum Number of Edge-Aligned, Overlapping Rectangles in a Non-Intersecting, Concave Polygon

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.)

Resources