Jump to content
Sign in to follow this  
Gustav Schubert

class operator TRectF.Add

Recommended Posts

Ha, here at home, today, I needed to do this test:
 

procedure Test;
var
  R1, R2, R3: TRectF;
begin
{
 TRectF from System.Types,
   when calling class operator TRectF.Add in 10.1 Berlin,
     will call class function TRectF.Union,
       which will call UnionRectF(Result, R1, R2),
         which will return Zero if result is Empty. <-- wrong ?

  The c++ code given in the docwiki does not do this. (please check)
 
  https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.Types.TRectF
}

  R1 := TRectF.Create(-1, 0, 1, 0);
  R2 := TRectF.Create(0, -1, 0, 1);
  R3 := R1 + R2; // (0, 0, 0, 0) unexpected

  R1 := TRectF.Create(-1, 0, 1, 0.1);
  R2 := TRectF.Create(0, -1, 0.1, 1);
  R3 := R1 + R2; // (-1, -1, 1, 1) // as expected
end;

 

Share this post


Link to post

System.Types, causes this, strange, TRectF not designed to handle negative numbers?:

 

function TRectF.IsEmpty: Boolean;
begin
  Result := (Right <= Left) or (Bottom <= Top);
end;

 

so the next one returns just an empty rect:

function UnionRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
var
  tmpRect: TRectF;
begin
  tmpRect := R1;
  if not R2.IsEmpty then
  begin
    if R2.Left < R1.Left then tmpRect.Left := R2.Left;
    if R2.Top < R1.Top then tmpRect.Top := R2.Top;
    if R2.Right > R1.Right then tmpRect.Right := R2.Right;
    if R2.Bottom > R1.Bottom then tmpRect.Bottom := R2.Bottom;
  end;
  Result := not tmpRect.IsEmpty;
  if not Result then
  begin
    tmpRect.Top :=0.0;
    tmpRect.Bottom := 0.0;
    tmpRect.Left := 0.0;
    tmpRect.Right := 0.0;
  end;
  Rect := tmpRect;
end;


 

Edited by mvanrijnen

Share this post


Link to post
5 minutes ago, mvanrijnen said:

TRectF not designed to handle negative numbers?:

That is not the case here. Negative numbers are allowed. In both cases the non-zero borders are ordered correctly.

 

The check for IsEmpty on both rectangles is a logical flaw. A Union of two empty rectangles can result in a non-empty rectangle.

 

@Gustav Schubert

Please file a bug report in QP.

Share this post


Link to post

Thanks for the two good comments above (code context and wording). QP tells me that I do not have permission to create a report, but here are the steps I prepared, please feel free to use them.
 

function Test: Boolean;
var
  P1, P2: TPointF;
  P3, P4: TPointF;
  R1, R2: TRectF;
  ActualResult: TRectF;
  ExpectedResult: TRectF;
begin
  P1 := TPointF.Create(-1, 0);
  P2 := TPointF.Create(1, 0);

  P3 := TPointF.Create(0, -1);
  P4 := TPointF.Create(0, 1);

  { imagine rectangles that hold the two points of a line }
  R1 := TRectF.Create(P1, P2); // horizontal line
  R2 := TRectF.Create(P3, P4); // vertical line

  ActualResult := R1 + R2;
  ExpectedResult := TRectF.Create(-1, -1, 1, 1);

  result := ActualResult = ExpectedResult;
end;

Title: TRect.Add and UnionF problem with Empty rectangles

Description: Class operator Add of TRectF has a problem with Emtpy operands. It will return Zero when it should not. It is understood that the actual problem is the implementation of UnionRectF.
 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×