Area of Intersection of Two Rotated Rectangles - algorithm

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

Related

How to compute the set of polygons from a set of overlapping circles?

This question is an extension on some computation details of this question.
Suppose one has a set of (potentially overlapping) circles, and one wishes to compute the area this set of circles covers. (For simplicity, one can assume some precomputation steps have been made, such as getting rid of circles included entirely in other circles, as well as that the circles induce one connected component.)
One way to do this is mentioned in Ants Aasma's and Timothy's Shields' answers, being that the area of overlapping circles is just a collection of circle slices and polygons, both of which the area is easy to compute.
The trouble I'm encountering however is the computation of these polygons. The nodes of the polygons (consisting of circle centers and "outer" intersection points) are easy enough to compute:
And at first I thought a simple algorithm of picking a random node and visiting neighbors in clockwise order would be sufficient, but this can result in the following "outer" polygon to be constructed, which is not part of the correct polygons.
So I thought of different approaches. A Breadth First Search to compute minimal cycles, but I think the previous counterexample can easily be modified so that this approach results in the "inner" polygon containing the hole (and which is thus not a correct polygon).
I was thinking of maybe running a Las Vegas style algorithm, taking random points and if said point is in an intersection of circles, try to compute the corresponding polygon. If such a polygon exists, remove circle centers and intersection points composing said polygon. Repeat until no circle centers or intersection points remain.
This would avoid ending up computing the "outer" polygon or the "inner" polygon, but would introduce new problems (outside of the potentially high running time) e.g. more than 2 circles intersecting in a single intersection point could remove said intersection point when computing one polygon, but would be necessary still for the next.
Ultimately, my question is: How to compute such polygons?
PS: As a bonus question for after having computed the polygons, how to know which angle to consider when computing the area of some circle slice, between theta and 2PI - theta?
Once we have the points of the polygons in the right order, computing the area is a not too difficult.
The way to achieve that is by exploiting planar duality. See the Wikipedia article on the doubly connected edge list representation for diagrams, but the gist is, given an oriented edge whose right face is inside a polygon, the next oriented edge in that polygon is the reverse direction of the previous oriented edge with the same head in clockwise order.
Hence we've reduced the problem to finding the oriented edges of the polygonal union and determining the correct order with respect to each head. We actually solve the latter problem first. Each intersection of disks gives rise to a quadrilateral. Let's call the centers C and D and the intersections A and B. Assume without loss of generality that the disk centered at C is not smaller than the disk centered at D. The interior angle formed by A→C←B is less than 180 degrees, so the signed area of that triangle is negative if and only if A→C precedes B→C in clockwise order around C, in turn if and only if B→D precedes A→D in clockwise order around D.
Now we determine which edges are actually polygon boundaries. For a particular disk, we have a bunch of angle intervals around its center from before (each sweeping out the clockwise sector from the first endpoint to the second). What we need amounts to a more complicated version of the common interview question of computing the union of segments. The usual sweep line algorithm that increases the cover count whenever it scans an opening endpoint and decreases the cover count whenever it scans a closing endpoint can be made to work here, with the adjustment that we need to initialize the count not to 0 but to the proper cover count of the starting angle.
There's a way to do all of this with no trigonometry, just subtraction and determinants and comparisons.

Minimum bounding rectangle of polygon

Let's say we have a class/struct Point
class Point
{
int x;
int y;
}
and a class Polygon that contains list of Points
class Polygon
{
List<Point> points;
Path(List<Point> points)
{
//some implementation
}
}
I am interested in finding the Minimal bounding rectangle points of the Polygon(https://en.wikipedia.org/wiki/Minimum_bounding_rectangle). The found minimal bounding rectangle sides might not be parallel to both axis , so I am trying to find an algorithm written in Java,C#,C++ .Can anyone propose or link such a solution, thanks!
It is possible to construct minimal bounding box (both min-area and min-perimeter) using Rotating Calipers approach.
You can find description at this wayback archive page
The minimum area rectangle enclosing a convex polygon P has a side
collinear with an edge of the polygon.
The above result dramatically restricts the range of possible
rectangles. Not only is it not necessary to check all directions, but
only as many as the polygon's number of edges.
Illustrating the above result: the four lines of support (red), with
one coinciding with an edge, determine the enclosing rectangle (blue).
A simple algorithm would be to compute for each edge the corresponding
rectangle collinear with it. But the construction of this rectangle
would imply computing the polygon's extreme points for each edge, a
process that takes O(n) time (for n edges). The entire algorithm would
then have quadratic time complexity.
A much more efficient algorithm can be found. Instead of recomputing
the extreme points, it is possible to update them in constant time,
using the Rotating Calipers. Indeed, consider a convex polygon, with a
two pair of lines of support through all four usual extreme points in
the x and y directions. The four lines already determine an enclosing
rectangle for the polygon. But unless the polygon has a horizontal or
vertical edge, this rectangle is not a candidate for the minimum area.
However, the lines can be rotated until the above condition is
satisfied. This procedure is at the heart of the following algorithm.
The input is assumed to be a convex polygon with n vertices given in
clockwise order.
Compute all four extreme points for the polygon, and call them xminP,
xmaxP, yminP ymaxP.
Construct four lines of support for P through all four points. These
determine two sets of "calipers".
If one (or more) lines coincide with an edge, then compute the area of
the rectangle determined by the four lines, and keep as minimum.
Otherwise, consider the current minimum area to be infinite.
Rotate the lines clockwise until one of them coincides with an edge of
its polygon.
Compute the area of the new rectangle, and compare it to the current
minimum area. Update the minimum if necessary, keeping track of the
rectangle determining the minimum.
Repeat steps 4 and 5, until the lines have been rotated an angle
greater than 90 degrees. Output the minimum area enclosing rectangle.
Because two pairs of "calipers" determine an enclosing rectangle, this
algorithm considers all possible rectangles that could have the
minimum area. Furthermore, aside from the initialization, there are
only as many steps in the algorithm's main loop as there are vertices.
Thus the algorithm has linear time complexity.
You can do this as follows:
Find the convex hull of the polygon points. A popular method is the Graham scan.
For each edge of the convex hull, find the minimum bounding rectangle that must have one side overlapping with that edge, so that the convex hull's edge is a subsegment of that rectangle's side.
Find the two perpendicular sides of the rectangle by walking along the convex hull vertices, and projecting the vertex to the first side, retaining the two that have all other projections between them. The final opposite side can be found in a similar manner. The vertices that lie on the rectangle, should be the starting point for when this step is executed again for the next edge on the convex hull (step 2).
Calculate the size of these rectangles, and retain the minimal one.
The complexity of this algorithm is determined by the first step, which is O(nlogn). The second step is O(n), as you have a selection of one edge and 3 vertices that rotates around the convex hull, visiting each edge once, and each vertex 3 times.

Can one polygon be transformed into another using only parallel translation and proportional scaling?

At the entrance, two polygons are given (the coordinates of the vertices of these polygons are listed in the order of their traversal; however, the traversal order for different polygon angles can be chosen different). Can one polygon be transformed into another using only parallel translation and proportional scaling?
I have following idea
So, find some common peak for two polygons and make the transfer of one polygon so that these vertices lie on one point then Scaling so that the neighboring point matches the corresponding point of another polygon, but I think it's wrong , at least I can't write it in code
Is there some special formula or theorem for this problem?
I would solve it like this.
Find the necessary parallel transport.
Find the necessary scaling.
See if they are the same polygon now.
So to start take the vertex that it farthest to the left, and if there is a tie, the one that is farthest down. Find that for both polygons. Use parallel transport to put that vertex at the origin for both.
Now take the vertex that is farthest to the right, and if there is a tie, the one that is farthest up. Find that for both polygons. If it is not at the same slope, then they are different. If it is, then scale one so that the points match.
Now see if all of the points match. If not, they are different. Otherwise the answer is yes.
Compute the axis-aligned bounding boxes of the two polygons.
If the aspect ratios do not match, the answer is negative. Otherwise the ratio of corresponding sides is your scaling factor. The translation is obtained by linking the top left corners and the transformation equations are
X = s.(x - xtl) + Xtl
Y = s.(y - ytl) + Ytl
where s is the scaling factor and (xtl, ytl), (Xtl, Ytl) are the corners.
Now choose a vertex of the first polygon, predict the coordinates in the other and find the matching vertex. If you can't, the answer is negative. Otherwise, you can compare the remaining vertices*.
*I assume that the polygons do not have overlapping vertices. If they can have arbitrary self-overlaps, I guess that you have to try matching all vertices, with all cyclic permutations.

How to approximate a polygon with n rectangles?

Is there any algorithm that can approximate the given polygon with n non overlapping rectangles that gives the maximum coverage? By maximum coverage I mean, the sum of the rectangle areas are maximized. Rectangles are not necessarily equal sized.
The polygons I am dealing are convex. If exact solution is hard/expensive to find (which I am expecting it to be), simple good heuristics are welcome too.
Edit I always thought of approximating the polygon with rectangles inside polygon, but solutions with rectangles not totally inside polygons are also fine. If that is the case, maximization of the area becomes minimization of the area.
Edit 2 I forgot to mention that these rectangles are orthogonal rectangles, i.e. aligned with axises.
One approach would be to create a (in the general case rectangular) bounding box for your polygon. Calculate the difference between the area of the bounding box and the area of the polygon. If the difference is small enough, you're done, if not, continue ...
Divide the box into 4 equal-sized rectangles, 2x2. Figure out which of these rectangles is entirely inside the polygon. Calculate the difference between the total area of the rectangles inside the polygon and of the polygon. If the difference is small enough you're done, if not continue ...
Divide each of the 4 rectangles into 4 sub-rectangles ... if at any stage you find that a rectangle is either fully inside or fully outside your polygon you can remove it from the list of rectangles to subdivide at the next iteration.
In other words, use a quadtree to divide the space containing your polygon and develop it to the extent necessary to meet your accuracy criteria.
Create a queue of polygons, Q, to be processed
Add the initial polygon to Q
Remove a polygon P from Q
Find the longest side A of P
Rotate P so that A is on the X-axis
If P is a triangle, split it with a perpendicular line in the centre of A:
Add the two halves G and H to Q and goto 3
(Now, P has 4 or more sides)
If X and/or Y are acute:
10 . Take the next longest side of P, A, and goto 5
11 . Project a red rectangle up from A. Find the 2 points where it intersects P, B and C:
12 . Choose the longer(B) and finalise the green rectangle
13 . Add the remaining figures (D, E and F) to Q
14 . Goto 3
I realize this is a really old question but I recently stumbled across a similar problem where I had to try to approximate a polygon with rectangles. Using some of the ideas presented here and elsewhere, I started with an inscribed rectangle and generated rectangles around the inscribed rectangle to provide the general shape of the polygon.
This approach works well for convex polygons and reasonable well for some concave polygons - especially if you take an iterative approach (e.g. feed output rectangles as inputs to another iteration).
For extremely concave shapes, you might consider breaking up the polygon into convex hulls and then applying the technique I described above. The Bayazit implementation looks very promising.
In case anyone is interested, I have posted my implementation using inscribed rectangles here:
https://github.com/pborissow/Poly2Rect
A first idea, maybe others can improve on it.
place a squaresomewhere inside the polygon, as far as possible away from any edges.
iteratively
1.) grow it,
2.) move it and turn it to maximize its distance from edges. until you can't grow it any more
start from the beginning, while considering edges of placed rectangles as edges of the polygon.

Finding a stable placement of an irregular (non-convex) shape

Given an image of a 2-dimensional irregular (non-convex) shape, how would I able to compute all the ways in which it could lie stable on a flat surface? For example, if the shape is a perfect square rectangle, then it will surely have 4 ways in which it is stable. A circle on the other hand either has no stable orientation or every point is a stable orientation.
EDIT: There's this nice little game called Splitter (Beware, addictive game ahead) that seems close to what I want. Noticed that you cut a piece of the wood out it would fall to the ground and lay in a stable manner.
EDIT: In the end, the approach I took is to compute center of mass (of the shape) and compute the convex hull (using OpenCV), and then loop through every pair of vertices. If the center of mass falls on top of the line formed by the 2 vertices, it is deemed stable, else, no.
First find its center of mass (CM). A stable position is one in which the CM will be higher if you make a slight rotation. Now look at the hull, the smallest convex region that encloses the shape:
(source: walkytalky.net)
If the hull is a polygon, then a stable position is one in which the shape is resting on one of the sides, and the CM is directly over that side (not necessarily over the midpoint of the side, just somewhere over it.
If the hull has curves (that is, if the shape has curves which touch the hull), they must be give special treatment. The shape will be stable when resting on a curved edge iff the CM is directly above the lowest point of the curve, and the radius of the curve at that point is greater than the height of the CM.
Examples:
A rectangle. The hull is simply the rectangle, and the CM is at the center. The shape is stable on each of the four sides.
A rectangle with the sides hollowed, but the corners still intact. The hull is still the original rectangle, and the CM is close to where it used to be. All four sides of the hull are still stable (that is, you can still rest the shape on any two corners).
A circle. The CM is in the center, the hull is the circle. There are no stable positions, since the radius of the curve is always equal to the height of the CM. Give it a slight touch, and it will roll.
An ellipse. The CM is at the center, the hull is the shape. Now there are two stable positions.
A semicircle. The CM is somewhere on the axis of symmetry, the hull is the shape. Two stable positions.
A narrow semicircular crescent. The hull is a semicircle, the CM is outside the shape (but inside the hull). Two stable positions.
(source: walkytalky.net)
(The ellipse position marked with an X is unstable, because the curvature is smaller than the distance to the centre of mass.)
note: this answer assumes your shape is a proper polygon.
For our purposes, we'll define an equilibrium position as one where the Center of Mass is directly above a point that is between the leftmost and rightmost ground-contact points of the object (assuming the ground is a flat surface perpendicular to the force of gravity). This will work in all cases, for all shapes.
Note that, this is actually the physical definition of rotational equilibrium, as a consequence of Newtonian Rotational Kinematics.
For a proper polygon, if we eliminate cases where they stand on a sole vertex, this definition is equivalent to a stable position.
So, if you have a straight downward gravity, first find the left-most and right-most parts of it that are touching the ground.
Then, calculate your Center of Mass. For a polygon with known vertices and uniform density, this problem is reduced to finding the Centroid (relevant section).
Afterwards, drop a line from your CoM; if the intersection of the CoM and the ground is between those two x values, it's at equilibrium.
If your leftmost point and rightmost point match (ie, in a round object), this will still hold; just remember to be careful with your floating point comparisms.
Note that this can also be used to measure "how stable" an object is -- this measure is the maximum y-distance the Center of Mass can move before it is no longer within the range of the two contact points.
EDIT: nifty diagram made hastily
So, how can you use this to find all the ways it can sit on a table? See:
EDIT
The programmable approach
Instead of the computationally expensive task of rotating the shape, try this instead.
Your shape's representation in your program should probably have a list of all vertices.
Find the vertices of your shape's convex hull (basically, your shape, but with all concave vertices -- vertices that are "pushed in" -- eliminated).
Then Iterate through each of pair of adjacent vertices on your convex hull (ie, if I had vertices A, B, C, D, I'd iterate through AB, BC, CD, DA)
Do this test:
Draw a line A through the two vertices being tested
Draw a line perpendicular to A, going through CoM C.
Find the intersection of the two lines (simple algebra)
If the intersection's y value is in between the y value of the two vertices, it stable. If the y values are all equal, compare the x values.
That should do the trick.
Here is an example of the test being running on one pair of vertices:
If your shape is not represented by its vertices in your data structure, then you should try to convert them. If it's something like a circle or an ellipse, you may use heuristics to guess the answer (a circle has infinite equilibrium positions; an ellipse 4, albeit only two "stable" points). If it's a curved wobbly irregular shape, you're going to have to supply your data structure for me be able to help in a program-related way, instead of just providing case-by-case heuristics.
I'm sure this is not the most efficient algorithm, but it's an idea.
If you can order the verticles of the polygon (assuming it has a finite number of vertices), then just iterate over adjacent pairs of vertices and record the angle it rests at through some form of simulation. There will be duplicate orientations for it to sit on in the case of weird shapes, like stars, but you can accomodate for that by keeping track of the resting rotation.

Resources