Reputation: 369
I need an algorithm to solve this problem: Given 2 rectangles intersecting or overlapping together in any corner, how do I determine the total area for the two rectangles without the overlapped (intersection) area? Meaning the area of intersection has to be calculated once, either with the first rectangle, or with second one.
Upvotes: 36
Views: 51857
Reputation: 3619
A Swift-version solution with analysis and LeetCode test results.
/**
Calculate the area of intersection of two given rectilinear rectangles.
- Author:
Cong Liu <congliu0704 at gmail dot com>
- Returns:
The area of intersection of two given rectilinear rectangles.
- Parameters:
- K: The x coordinate of the lower left point of rectangle A
- L: The y coordinate of the lower left point of rectangle A
- M: The x coordinate of the upper right point of rectangle A
- N: The y coordinate of the upper right point of rectangle A
- P: The x coordinate of the lower left point of rectangle B
- Q: The y coordinate of the lower left point of rectangle B
- R: The x coordinate of the upper right point of rectangle B
- S: The y coordinate of the upper right point of rectangle B
- Assumptions:
All the eight given coordinates (K, L, M, N, P, Q, R and S) are integers
within the range [-2147483648...2147483647], that is, Int32-compatible.
K < M, L < N, P < R, Q < S
- Analysis:
The area of intersected is dyIntersected * dxIntersected.
To find out dyIntersected, consider how y coordinates of two rectangles relate
to each other, by moving rectangle A from above rectangle B down.
Case 1: when N > L >= S > Q, dyIntersected = 0
Case 2: when N >= S > L >= Q, dyIntersected = S - L
Case 3: when S > N > L >= Q, dyIntersected = N - L
Case 4: when S >= N >= Q > L, dyIntersected = N - Q
Case 5: when N > S > Q > L, dyIntersected = S - Q
Cases 2 and 3 can be merged as Case B:
when L >= Q, dyIntersected = min(N, S) - L
Cases 4 and 5 can be merged as Case C:
when Q > L, dyIntersected = min(N, S) - Q
Cases B and C can be merged as Case D:
when S > L , dyIntersected = min(N, S) - max(L, Q)
Likewise, x coordinates of two rectangles relate similarly to each other:
Case 1: when R > P >= M > K, dxIntersected = 0
Case 2: when M > P , dxIntersected = min(R, M) - max(P, K)
- Submission Date:
Sat 20 Jan 2018 CST at 23:28 pm
- Performance:
https://leetcode.com/problems/rectangle-area/description/
Status: Accepted
3081 / 3081 test cases passed.
Runtime: 78 ms
*/
class Solution {
public static func computeArea(_ K: Int, _ L: Int, _ M: Int, _ N: Int, _ P: Int, _ Q: Int, _ R: Int, _ S: Int) -> Int {
let areaA : Int = Int((M - K) * (N - L))
let areaB : Int = Int((R - P) * (S - Q))
var xIntersection : Int = 0
var yIntersection : Int = 0
var areaIntersection : Int = 0
if ((min(M, R) - max(K, P)) > 0) {
xIntersection = Int(min(M, R) - max(K, P))
}
if ((min(N, S) - max(L, Q)) > 0) {
yIntersection = Int(min(N, S) - max(L, Q))
}
if ((xIntersection == 0) || (yIntersection == 0)) {
areaIntersection = 0
} else {
areaIntersection = Int(xIntersection * yIntersection)
}
return (areaA + areaB - areaIntersection)
}
}
// A simple test
Solution.computeArea(-4, 1, 2, 6, 0, -1, 4, 3) // returns 42
Upvotes: 1
Reputation: 68006
That's easy. First compute coordinates of intersection, which is also a rectangle.
left = max(r1.left, r2.left)
right = min(r1.right, r2.right)
bottom = max(r1.bottom, r2.bottom)
top = min(r1.top, r2.top)
Then, if intersection is not empty (left < right && bottom < top
), subtract it from the common area of two rectangles: r1.area + r2.area - intersection.area
.
PS:
bottom = min(r1.bottom, r2.bottom)
top = max(r1.top, r2.top)
Upvotes: 85
Reputation: 602
I saw this question wasn't answered so I wrote a small java program to try the equation out that @VicJordan and @NikitaRybak has talked about in previous answers. Hope this helps.
/**
* This function tries to see how much of the smallest rectangle intersects
* the with the larger one. In this case we call the rectangles a and b and we
* give them both two points x1,y1 and x2, y2.
*
* First we check for the rightmost left coordinate. Then the leftmost right
* coordinate and so on. When we have iLeft,iRight,iTop,iBottom we try to get the
* intersection points lenght's right - left and bottom - top.
* These lenght's we multiply to get the intersection area.
*
* Lastly we return the result of what we get when we add the two areas
* and remove the intersection area.
*
* @param xa1 left x coordinate A
* @param ya1 top y coordinate A
* @param xa2 right x coordinate A
* @param ya2 bottom y coordinate A
* @param xb1 left x coordinate B
* @param yb1 top y coordinate B
* @param xb2 right x coordinate B
* @param yb2 bottom y coordinate B
* @return Total area without the extra intersection area.
*/
public static float mostlyIntersects(float xa1, float ya1, float xa2, float ya2, float xb1, float yb1, float xb2, float yb2) {
float iLeft = Math.max(xa1, xb1);
float iRight = Math.min(xa2, xb2);
float iTop = Math.max(ya1, yb1);
float iBottom = Math.min(ya2, yb2);
float si = Math.max(0, iRight - iLeft) * Math.max(0, iBottom - iTop);
float sa = (xa2 - xa1) * (ya2 - ya1);
float sb = (xb2 - xb1) * (yb2 - yb1);
return sa + sb - si;
}
Upvotes: 5
Reputation: 2857
Sorry to come to the party late. I dont know if you are looking language specific : But on iOS its pretty easy :
CGRectIntersection
It would give you CGrect that is overlappring by given two rects. if they are not intersecting is would return CGRectIsNull.
hope this help at least someone. Happy coding
Upvotes: 0
Reputation: 21766
Here is complete solution for this algorithm using Java:
public static int solution(int K, int L, int M, int N, int P, int Q, int R,
int S) {
int left = Math.max(K, P);
int right = Math.min(M, R);
int bottom = Math.max(L, Q);
int top = Math.min(N, S);
if (left < right && bottom < top) {
int interSection = (right - left) * (top - bottom);
int unionArea = ((M - K) * (N - L)) + ((R - P) * (S - Q))
- interSection;
return unionArea;
}
return 0;
}
Upvotes: 14
Reputation: 31
The coordinates of intersection are correct if the origin (0,0) is placed at the bottom-left of the reference system.
In image processing, where the origin (0,0) is usually placed at the top-left of the reference system, the coordinates bottom and top of intersection would be:
bottom = min(r1.bottom, r2.bottom)
top = max(r1.top, r2.top)
Upvotes: 3