7

Assume I have the following overlapping rectangles ("a" and "b"):

aaaaaaaa
aaaaccccbbbbb
aaaaccccbbbbb
aaaaccccbbbbb
    bbbbbbbbb
    bbbbbbbbb

I've seen lots of ideas on how to calculate the area of the inner rectangle ("c"), but how would I go about getting the actual top/left/bottom/right coordinates for it?

scunliffe
  • 62,582
  • 25
  • 126
  • 161
Chris
  • 27,596
  • 25
  • 124
  • 225

5 Answers5

13

Call Rectangle.Intersect.

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
9

The X coordinates of the overlap area of two rectangles can be found according to the following logic.

To find the Y coordinates, substitute Y for X in the last of the four assumptions, as well as in all of the three cases.


Assumptions:

  • A and B are rectangles (with their sides aligned along the X and Y axes),

  • each of the rectangles is defined by two points   (xmin / ymin) – (xmax / ymax)

  • where xmin < xmax   and   ymin < ymax  .

  • A.xmin < B.xmin


Case 1 — No overlap:

+--------+
|A       |    
|        |    +----+
|        |    |B   |
|        |    +----+
|        |
+--------+

A.xmin < A.xmax < B.xmin < B.xmax   ⇒   No overlap.


Case 2 — Some overlap:

+--------+
|A       |
|     +--+-+
|     |B | |
|     +--+-+
|        |
+--------+

A.xmin < B.xmin < A.xmax < B.xmax   ⇒   Overlap X coordinates: B.xminA.xmax


Case 3 — Complete overlap:

+--------+
|A       |
| +----+ |
| |B   | |
| +----+ |
|        |
+--------+

A.xmin < B.xmin < B.xmax < A.xmax   ⇒   Overlap X coordinates: B.xminB.xmax


P.S.: You can actually further simplify this algorithm. The overlap X coordinates are always:

max(A.xmin, B.xmin) – min(A.xmax, B.xmax)

except when the second value is less than the first; that means that there is no overlap.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
4
static internal Rectangle intersect(Rectangle lhs, Rectangle rhs)
{
    Dimension lhsLeft = lhs.Location.X;
    Dimension rhsLeft = rhs.Location.X;
    Dimension lhsTop = lhs.Location.Y;
    Dimension rhsTop = rhs.Location.Y;
    Dimension lhsRight = lhs.Right;
    Dimension rhsRight = rhs.Right;
    Dimension lhsBottom = lhs.Bottom;
    Dimension rhsBottom = rhs.Bottom;

    Dimension left = Dimension.max(lhsLeft, rhsLeft);
    Dimension top = Dimension.max(lhsTop, rhsTop);
    Dimension right = Dimension.min(lhsRight, rhsRight);
    Dimension bottom = Dimension.min(lhsBottom, rhsBottom);
    Point location = new Point(left, top);
    Dimension width = (right > left) ? (right - left) : new Dimension(0);
    Dimension height = (bottom > top) ? (bottom - top) : new Dimension(0);

    return new Rectangle(location, new Size(width, height));
}
ChrisW
  • 54,973
  • 13
  • 116
  • 224
  • ...provided the coordinate system has right and downwards as positive directions. – Pontus Gagge Jul 03 '10 at 22:18
  • @ChrisW: To Check if they intersect: In all cases where they do not NOT intersect, they intersect. They do not intersect if neither StartA > EndB (a completely after B) or EndA < StartB ( A Completely Before B). Now de morgan: Not (A Or B) <=> Not A And Not B ==> (StartA <= EndB) and (EndA >= StartB), in any other case, return the (0,0,0,0) rectangle or NULL. – Stefan Steiger Oct 08 '14 at 13:37
1

Assume:

Points of   rectangle R1: R1.A(x,y), R1.B(x,y), R1.C(x,y), R1.D(x,y)   
Points of   rectangle R2: R2.A(x,y), R2.B(x,y), R2.C(x,y), R2.D(x,y)   
Overlapping rectangle RO: RO.A(x,y), RO.B(x,y), RO.C(x,y), RO.D(x,y)    
Standard cartesian coordinates (positive is right and upwards).

Overlapping rectangle RO computes as follows with C#:

RO.A.x = Math.Min(R1.A.x, R2.A.x);
RO.A.y = Math.Max(R1.A.y, R2.A.y);
RO.C.x = Math.Max(R1.C.x, R2.C.x);
RO.C.y = Math.Min(R1.C.y, R2.C.y);
RO.B(x,y) and RO.D(x,y) = ....

Inner rectangle RI:

Swap Min and Max in above solution for overlapping rectangle RO.

user319785
  • 31
  • 1
  • 4
0

I used an abstract validator for my project and to check if some layout controls where overlapping I created rectangles out of the layout figures:

RuleFor(p => DoControlsIntersect(p.PageControls.Select(x => new Rectangle(x.Row, x.Column, x.Width, x.Height)).ToList())).Equal(false).WithMessage(OverlappingFields);

private bool DoControlsIntersect(List<Rectangle> rectangles)
        {
            return rectangles.Any(rect => rectangles.Where(r => !r.Equals(rect)).Any(r => r.IntersectsWith(rect)));
        }
Monolithcode
  • 598
  • 8
  • 19