intersection area of 3 or more rectangles

24 ビュー (過去 30 日間)
Tobias Eißler
Tobias Eißler 2021 年 3 月 5 日
回答済み: Matt J 2021 年 3 月 6 日
hi all, I have multiple rectangles defined by rectangle()- function. I now want to find the intersection area of 3 rectangles (I know that for 2 rectangles rectint works). Alternatively it might be an option to find the intersection area of the intersection (rectangle 1, rectangle 2) with the rectangle 3.
Is there a funtion or simple solution for this problem?
Thanks!

採用された回答

Adam Danz
Adam Danz 2021 年 3 月 5 日
編集済み: Adam Danz 2021 年 3 月 5 日
This approach is inspired by the even-odd rule for determining if a point is inside a polygon. If the max left-edge value is smaller than the min right-edge value and if the max bottom-edge value is smaller than the min top-edge value, then all rectangles overlap. This only works when rectangle edges are parallel to the axes (ie, not rotated beyond 90 deg intervals).
Input:
r: an array of handles of rectangle objects. Add as many as you'd like.
Output:
rectDim: 1x4 vector; contains the [left, bottom, width, height] of the overlapping rectangle. If there isn't an overlapp of all rectangles, it will be all NaN values.
Variations:
If you'd rather work with [left, bottom, right, top] values directly rather than working with rectangle objects, create an nx4 matrix of those values for n rectangles, name it LBRT and remove the first two sections of code.
If you'd rather work with [left, bottom, width, height] values directly rather than working with rectangle objects, create an nx4 matrix of those values for n rectangles and convert to bounds using the LBRT conversion in the second section of code.
% Generate n rectangels with random positions and sizes and
% store their handles in vector 'r'.
cla()
hold on
r(1) = rectangle('position',rand(1,4).*[1,1,2,2],'EdgeColor','g','LineWidth',3);
r(2) = rectangle('position',rand(1,4).*[1,1,2,2],'EdgeColor','m','LineWidth',3);
r(3) = rectangle('position',rand(1,4).*[1,1,2,2],'Edgecolor','b','LineWidth',3);
% r(n) = rectangel(....) add as many as you want!
%% Find overlap of all rectangles
% Convert nx4 matrix [left,bottom,width,height] -> [left,bottom,right,top]
LBRT = vertcat(r.Position);
LBRT(:,3) = sum(LBRT(:,[1,3]),2);
LBRT(:,4) = sum(LBRT(:,[2,4]),2);
% Test Left|Right edge intersections
[~,LRidx] = sort([LBRT(:,1);LBRT(:,3)]);
LRtest = max(LRidx(1:numel(LRidx)/2)) < min(LRidx(numel(LRidx)/2+1:end));
% Test Bottom|Top edge intersections
[~,BTidx] = sort([LBRT(:,2);LBRT(:,4)]);
BTtest = max(BTidx(1:numel(BTidx)/2)) < min(BTidx(numel(BTidx)/2+1:end));
if LRtest && BTtest
% All rectangles overlap. The overlap is defined by the max left side,
% min right side, same with bottom/top. Fill in overlap.
overlapPos = [max(LBRT(:,1)), max(LBRT(:,2)), min(LBRT(:,3)), min(LBRT(:,4))];
rectDim = [overlapPos(1:2), overlapPos(3:4)-overlapPos(1:2)];
rectangle('Position', rectDim, 'FaceColor',[.0 0 0 .3])
else
rectDim = nan(1,4);
end
  3 件のコメント
Adam Danz
Adam Danz 2021 年 3 月 5 日
I tried with 3, 4 and 5 rectangles and it works just as in the GIF image. It should work with any number of rectangles, I believe.
Tobias Eißler
Tobias Eißler 2021 年 3 月 5 日
yeah it works perfectly, thanks a lot!

サインインしてコメントする。

その他の回答 (2 件)

darova
darova 2021 年 3 月 5 日
Try polyxpoly with for loop
  2 件のコメント
Adam Danz
Adam Danz 2021 年 3 月 5 日
I didn't know about polyxpoly, thanks @darova! But it's immediately clear to me how that would be applied to finding the internal intersection of n rectanlges.
Tobias Eißler
Tobias Eißler 2021 年 3 月 5 日
thanks @darova, I am still quite new to MATLAB so I am not really sure how i would use it. So I think I will try @Adam Danz solution

サインインしてコメントする。


Matt J
Matt J 2021 年 3 月 6 日
If you put your rectangles in the form of a polyshape vector (I'll call it polyvec), then it is very easy:
Area = area(intersect(polyvec))

カテゴリ

Help Center および File ExchangeSurface and Mesh Plots についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by