Rectangle intersects detection issue

Let’s say i make a moving rectangle A overlapping another rectangle B (not moving).
Usually, when A meets the very 1st pixel of B, we can detects this situation by using the Rectangle.Intersects method.

As :
if (A.Intersects(B))
{
//Do things
}

But, i noticed, that depending on the size (width and Height) of A, the Intersects method doesn’t work.
Anyone know this issue or know how to solve it ?

I’ve made a lot of test and if the rectangle is too small (like 30 x 30) intersects don’t work but if i use a bigger one (like 100 * 100) it is working. And i’m sure they’re overlapping.

I will continue to dig in my code to be sure that a condition is not responsible of that but i don’t think that’s the case.

what exactly doesn’t work. Does it get an intersect when it shouldn’t or does it not register an intersect?

You are sure they are overlapping? So i assume you debug at the intersect point and look at the points and you see them overlapping, but the intersect is wrong? Strange.

You can look into the MonoGame implementation of Rectangle here: https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/Rectangle.cs

and look at the intersect function. To me it looks like it behaves exactly the way it should, maybe you can debug through and tell us exactly when it fails?

How fast is the rectangle moving? It sounds like it might be moving fast enough that at small sizes it steps over the target rectangle. That is, on frame A it is on the left of the target and on frame B it is on the right. It moved so far in that one frame that skipped completely over the target rectangle and thus never intersected.

1 Like

Fyi as a rule the motion of your players or enemys cannot be more the smalles collision rectangles width or height or you can pass them thru each other with contains methods of almost all types in 2d unless your doing something advanced that can happen
make your rectangles bigger or slow down your players or enemys ect…
Otherwise you have to make a more complex time steped collision.

Right couple of those methods look bogus.
Well you could do it all sorts of ways.
Its not like you have to use the rectangle version.

cwh = (a + b) *.5;
dxy = (a - b) *.5;
if(dx < 0){dx = -dx;}
if(dy < 0){dy = -dy;}
if(dx < cw && dy < ch)
return true;
else
return false;

wonder how fast swapping is well these are structs so this might be a little slower.

Rectangles a and b
Vector2 c = a.Location - b.Location;
Rectangle t;
if(c > 0){t = b; b = a; a = t;}
if(b.Left < a.Right && b.Top < b.Bottom)
{ return true;}
else
{return false;}

In all honesty doing something like this below is probably fastest.
Even though it looks fat and bloated. there is only one subtraction and 3 conditionals
You escape faster exclusion is almost always faster then verification.
// if c.x is negative, c.x < 0 then a is on the left of b
// the sign of course tells you which is on which side of the other
// you could sort but thats kinda a waste just run straight down the if else chain
// you only really need the signs

Vector2 c = b.Location - a.Location;
if(c.X < 0)
{
if(c.Y < 0)
{
// - -
}
else
{
// - +
}
}
else
{
if(c.Y < 0)
{
// + -
}
else
{
// ++
if(a.Right > b.Left && a.Bottom > b.Top){return true;}else{ return false;}
}
}

The center difference of either to the others center point must be within the combined sum of half the width and height of both rectangles at the least or it cannot be within the other.

   didn't actually test these but i put it in my class anyways lol

    /// <summary>
    /// this takes a virtual position in relation to a virtrectangle
    /// requisite that the width and height of both virtual rectangles is non negative
    /// not a problem for regular rectangles but this is not a regular rectangle
    /// </summary>
    public bool HasWithin(VirtualRectangle v)
    {
        Vector2 d = this.Center - v.Center;
        if (d.x < 0) { d.x = -d.x; }
        if (d.y < 0) { d.y = -d.y; }
        d = (.5f * v.WidthHeight + this.WidthHeight * .5f) - d;
        if (d.x < 0 && d.y < 0)
            return true;
        else
            return false;
    }

you can also just check if just one is is in the other.
like just check if either b’s left or right is within a’s left or right
then do it for the y axis but that is pretty much the if else thing.

Does the ‘intersect’ also take into account the ‘contain’ aspect ? ie:disjoint :wink:

My bad, i solved my issue by looking further in my code. I had a 3rd rectangle getting the colliding of the method Intersects and it was messing with the result

To summarize, i need to ignore a Rectangle A’ (under rectangle A) before moving rectangle A in order to detect a collision with any other rectangle (like B) on the way…So, when A was colliding with B but without collidiing with A’ at the same time, B was ignored as well.

Sorry for that lame intervention then.

Thx for all your interventions.

@KonajuGames what you said was the best thing i can check before noticing the real issue.
@Alkher i don’t know i never used Contain because Intersects was enough for what i wanted. Is it useful to know if a rectangle colldie with nothing ?
@willmotil i already use somthing like this in another part of my code but is was to much work for waht i wanted. It’s way more simple with Rectangle.Intersects.

In 3D collision, intersect != contains.
A volume can be contained in another one without intersecting its border (a sphere A of 1 unit radius contained in a sphere B of 2000radius, A being at the center of B for ex).
So we use “disjoint” to check if there are no overlapping/intersection at all. I do not work with 2d so often so i don’t uese/know all the methods of Rectangle class.