Question

The only difference in these two tests is 84.55808f vs 84.5f in the width of the two inner rectangles.

Yet contains ends up being false while contains2 ends up being true. Wow.

Using the Xamarin.iOS C# (Monotouch) environment and the Xamarin IDE on a Mac

Can anybody verify this? And if so can anybody identify the problem?

Thanks!

RectangleF r1 = new RectangleF (119.221f, -122.9433f, 646f, 646f); 
RectangleF r2 = new RectangleF (238.4419f, 0f, 84.55808f, 77.11342f);
bool contains = r1.Contains (r2); 

RectangleF r3 = new RectangleF (119.221f, -122.9433f, 646f, 646f); 
RectangleF r4 = new RectangleF (238.4419f, 0f, 84.5f, 77.11342f); 
bool contains2 = r3.Contains (r4);
Was it helpful?

Solution

Calling Intersect(r1,r2) returns {{X=238.4419,Y=0,Width=84.55807,Height=77.11342}}. The Width is != 84.55808 and therefore the comparison in Contains "Is the intersection rectangle the same as the rect argument?" fails.

So ultimately, this comes down to 323 - 238.4419. If you do that with paper-and-pencil, you'll get 84.5581 but with floating point, 323f - 238.4419f = 84.55811f (N.B.: extra 0.00001).

I've submitted this as a bug: https://bugzilla.xamarin.com/show_bug.cgi?id=15518

OTHER TIPS

this is not an answer, but it's too long for a comment.

I can confirm this behavior on Xamarin.iOS. Here's the implementation of Contains and other helpful methods:

public bool Contains (RectangleF rect)
{
    return rect == RectangleF.Intersect (this, rect);
}

public static RectangleF Intersect (RectangleF a, RectangleF b)
{
    if (!a.IntersectsWithInclusive (b))
    {
        return RectangleF.Empty;
    }
    return RectangleF.FromLTRB (Math.Max (a.Left, b.Left), Math.Max (a.Top, b.Top), Math.Min (a.Right, b.Right), Math.Min (a.Bottom, b.Bottom));
}

private bool IntersectsWithInclusive (RectangleF r)
{
    return this.Left <= r.Right && this.Right >= r.Left && this.Top <= r.Bottom && this.Bottom >= r.Top;
}


public static RectangleF FromLTRB (float left, float top, float right, float bottom)
{
    return new RectangleF (left, top, right - left, bottom - top);
}

I don't feel like checking the math on Saturday evening...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top