TRect.Intersect和TRect.IntersectsWith Inconsistencies

Gra*_*ter 9 delphi delphi-xe4

我希望我在某种程度上感到困惑.我TRect.Intersect和and 有一些不一致的行为TRect.IntersectsWith.这是一些演示此问题的代码.

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.
Run Code Online (Sandbox Code Playgroud)

提出了第二个例外.TRect.IntersectsWith指示rects相交但是当我调用TRect.Intersect以获取新的相交rect时,它返回一个空的rect.

IntersectsWith中的代码(编写得非常清楚)在第二种情况下返回true,因为Self.BottomRight.Y = R.TopLeft.Y(100).

function TRect.IntersectsWith(const R: TRect): Boolean;
begin
  Result := not ( (Self.BottomRight.X < R.TopLeft.X) or
                  (Self.BottomRight.Y < R.TopLeft.Y) or
                  (R.BottomRight.X < Self.TopLeft.X) or
                  (R.BottomRight.Y < Self.TopLeft.Y) );
end;
Run Code Online (Sandbox Code Playgroud)

问题是IsRectEmpty通过Intersect检查调用以查看rect的顶部和底部或rect的左侧和右侧是否具有相同的值,以及何时通过Intersect将结果设置为空rect.

function IsRectEmpty(const Rect: TRect): Boolean;
begin
  Result := (Rect.Right <= Rect.Left) or (Rect.Bottom <= Rect.Top);
end;
Run Code Online (Sandbox Code Playgroud)

这是预期的行为,如果不是应该改变的.我的理解是TRects排除了底部和右边的"边缘",如果是这样的话不应该TRect.IntersectsWith看起来像这样吗?

function TRect.IntersectsWith(const R: TRect): Boolean;
begin
  Result := not ( (Self.BottomRight.X <= R.TopLeft.X) or
                  (Self.BottomRight.Y <= R.TopLeft.Y) or
                  (R.BottomRight.X <= Self.TopLeft.X) or
                  (R.BottomRight.Y <= Self.TopLeft.Y) );
end;
Run Code Online (Sandbox Code Playgroud)

Ser*_*yuz 6

这是一个错误; 这不是预期的行为.在当前的实现中,RTL认为两个空的rects可以相交(例如(0,0,0,0),(0,0,0,0)或者一个非空的rect与空的一个),这没有任何意义.

Assert(Rect(0, 0, 0, 0).IntersectsWith(Rect(0, 0, 0, 0)));
Run Code Online (Sandbox Code Playgroud)

上述断言不会失败.

此外,它不适用于Windows API.以下断言失败:winapi认为(0,0,200,100)并且(0,100,200,200)不相交.

Assert(winapi.windows.IntersectRect(OutRect, Rect(0,0,200,100), Rect(0,100,200,200)));
Run Code Online (Sandbox Code Playgroud)

System.Types.IntersectRect()返回boolean 的重载同样被破坏.