title: TRect.Intersect and TRect.IntersectsWith Inconsistencies
body: <p>I am hoping that I am confused in some way. I am getting some inconsistent behavior with <code>TRect.Intersect</code> and <code>TRect.IntersectsWith</code>. Here is some code that demonstrates the problem.</p>
  
  <pre><code>program RectCheck;
  
  {$APPTYPE CONSOLE}
  
  {$R *.res}
  
  uses
    System.SysUtils,
    System.Types,
    Vcl.Dialogs;
  
  var
    rect1: TRect;
    rect2: TRect;
    combinedRect: TRect;
  begin
    Rect1 := Rect(0,0,200,101);
    Rect2 := Rect(0,100,200,200);
    if Rect1.IntersectsWith(Rect2) then
    begin
      // We have interesected, get the combined rect
      combinedRect := TRect.Intersect(Rect1, Rect2);
      if not combinedRect.IsEmpty then
        ShowMessage(Format('Our new rect (%d, %d), (%d, %d)',
            [combinedRect.Left, combinedRect.Top, combinedRect.Right, combinedRect.Bottom]))
      else
        raise Exception.Create('They were supposed to intersect!');
    end;
  
    Rect1 := Rect(0,0,200,100);
    Rect2 := Rect(0,100,200,200);
    if Rect1.IntersectsWith(Rect2) then
    begin
      // We have interesected, get the combined rect
      combinedRect := TRect.Intersect(Rect1, Rect2);
  
      if not combinedRect.IsEmpty then
        ShowMessage(Format('Our new rect (%d, %d), (%d, %d)',
            [combinedRect.Left, combinedRect.Top, combinedRect.Right, combinedRect.Bottom]))
      else
        raise Exception.Create('They were supposed to intersect!');
    end;
  end.
  </code></pre>
  
  <p>The second exception is raised. <code>TRect.IntersectsWith</code> indicates that the rects intersect but when I call <code>TRect.Intersect</code> to get the new intersected rect then it returns an empty rect.</p>
  
  <p>The code in IntersectsWith (which isn't written very clearly) is returning true in the second case because Self.BottomRight.Y = R.TopLeft.Y (100).</p>
  
  <pre><code>function TRect.IntersectsWith(const R: TRect): Boolean;
  begin
    Result := not ( (Self.BottomRight.X &lt; R.TopLeft.X) or
                    (Self.BottomRight.Y &lt; R.TopLeft.Y) or
                    (R.BottomRight.X &lt; Self.TopLeft.X) or
                    (R.BottomRight.Y &lt; Self.TopLeft.Y) );
  end;
  </code></pre>
  
  <p>The problem is that <code>IsRectEmpty</code> which is called by <code>Intersect</code> checks to see if either the top and bottom of the rect or the left and right of the rect have the same values and when that passes <code>Intersect</code> sets the result to an empty rect.</p>
  
  <pre><code>function IsRectEmpty(const Rect: TRect): Boolean;
  begin
    Result := (Rect.Right &lt;= Rect.Left) or (Rect.Bottom &lt;= Rect.Top);
  end;
  </code></pre>
  
  <p>Is this the expected behavior and if not what should be changed. My understanding is that TRects exclude the bottom and right "edges" and if that's the case shouldn't <code>TRect.IntersectsWith</code> look something like this?</p>
  
  <pre><code>function TRect.IntersectsWith(const R: TRect): Boolean;
  begin
    Result := not ( (Self.BottomRight.X &lt;= R.TopLeft.X) or
                    (Self.BottomRight.Y &lt;= R.TopLeft.Y) or
                    (R.BottomRight.X &lt;= Self.TopLeft.X) or
                    (R.BottomRight.Y &lt;= Self.TopLeft.Y) );
  end;
  </code></pre>