Предполагая, что прямоугольник 2 содержится в прямоугольнике 1 (если нет, используйте пересечение обоих прямоугольников в качестве прямоугольника 2):
-------------------------
| rectangle 1 |
| |
| ------------- |
| |rectangle 2| |
| ------------- |
| |
| |
-------------------------
Если вы вычесть прямоугольник 2 из прямоугольника 1, вы получите областьс отверстием:
-------------------------
| |
| |
| ------------- |
| | hole | |
| ------------- |
| |
| |
-------------------------
Эта область может быть разбита на 4 прямоугольника:
-------------------------
| A |
| |
|-----------------------|
| B | hole | C |
|-----------------------|
| |
| D |
-------------------------
Если прямоугольник 1 и прямоугольник 2 совпадают с трех сторон, вы получите 1 прямоугольник из вычтенногоплощадь (в вашем случае).В общем случае вы получите не более 4 прямоугольников.
Реализация в target-c (извините, на данный момент у вас нет Visual Studio):
// returns the rectangles which are part of rect1 but not part of rect2
NSArray* rectSubtract(CGRect rect1, CGRect rect2)
{
if (CGRectIsEmpty(rect1)) {
return @[];
}
CGRect intersectedRect = CGRectIntersection(rect1, rect2);
// No intersection
if (CGRectIsEmpty(intersectedRect)) {
return @[[NSValue valueWithCGRect:rect1]];
}
NSMutableArray* results = [NSMutableArray new];
CGRect remainder;
CGRect subtractedArea;
subtractedArea = rectBetween(rect1, intersectedRect, &remainder, CGRectMaxYEdge);
if (!CGRectIsEmpty(subtractedArea)) {
[results addObject:[NSValue valueWithCGRect:subtractedArea]];
}
subtractedArea = rectBetween(remainder, intersectedRect, &remainder, CGRectMinYEdge);
if (!CGRectIsEmpty(subtractedArea)) {
[results addObject:[NSValue valueWithCGRect:subtractedArea]];
}
subtractedArea = rectBetween(remainder, intersectedRect, &remainder, CGRectMaxXEdge);
if (!CGRectIsEmpty(subtractedArea)) {
[results addObject:[NSValue valueWithCGRect:subtractedArea]];
}
subtractedArea = rectBetween(remainder, intersectedRect, &remainder, CGRectMinXEdge);
if (!CGRectIsEmpty(subtractedArea)) {
[results addObject:[NSValue valueWithCGRect:subtractedArea]];
}
return results;
}
// returns the area between rect1 and rect2 along the edge
CGRect rectBetween(CGRect rect1, CGRect rect2, CGRect* remainder, CGRectEdge edge)
{
CGRect intersectedRect = CGRectIntersection(rect1, rect2);
if (CGRectIsEmpty(intersectedRect)) {
return CGRectNull;
}
CGRect rect3;
float chopAmount = 0;
switch (edge) {
case CGRectMaxYEdge:
chopAmount = rect1.size.height - (intersectedRect.origin.y - rect1.origin.y);
if (chopAmount > rect1.size.height) { chopAmount = rect1.size.height; }
break;
case CGRectMinYEdge:
chopAmount = rect1.size.height - (CGRectGetMaxY(rect1) - CGRectGetMaxY(intersectedRect));
if (chopAmount > rect1.size.height) { chopAmount = rect1.size.height; }
break;
case CGRectMaxXEdge:
chopAmount = rect1.size.width - (intersectedRect.origin.x - rect1.origin.x);
if (chopAmount > rect1.size.width) { chopAmount = rect1.size.width; }
break;
case CGRectMinXEdge:
chopAmount = rect1.size.width - (CGRectGetMaxX(rect1) - CGRectGetMaxX(intersectedRect));
if (chopAmount > rect1.size.width) { chopAmount = rect1.size.width; }
break;
default:
break;
}
CGRectDivide(rect1, remainder, &rect3, chopAmount, edge);
return rect3;
}