Get the points of intersection from 2 rectangles

If the input rectangles are normalized, i.e. you already know that x1 < x2, y1 < y2 (and the same for the second rectangle), then all you need to do is calculate

int x5 = max(x1, x3);
int y5 = max(y1, y3);
int x6 = min(x2, x4);
int y6 = min(y2, y4);

and it will give you your intersection as rectangle (x5, y5)-(x6, y6). If the original rectangles do not intersect, the result will be a "degenerate" rectangle (with x5 >= x6 and/or y5 >= y6), which you can easily check for.

P.S. As usual, small details will depend on whether you have to consider touching rectangles as intersecting.


You can deal with the x and y direction separately.

Assume that x1 <= x3 (the first box is at least as far to the left as the second). Then, there is overlap if and only if x1 <= x3 <= x2.

Similarly, assume y1 <= y3 (the first box is at least as far to the bottom as the second). Then, there is overlap if and only if y1 <= y3 <= y2.

If there is overlap in both directions, there is a rectangle overlapping. You can find the coordinates by sorting the x and y coordinates and selecting the middle two.

In pseudocode:

if (((x1 <= x3 && x3 <= x2) || (x3 <= x1 && x1 <= x4)) // x-overlap
    &&
    ((y1 <= y3 && y3 <= y2) || (y3 <= y1 && y1 <= y4)) // y-overlap
) {
    int[] xs = {x1, x2, x3, x4};
    int[] ys = {y1, y2, y3, y4};
    sort(xs);
    sort(ys);

    // bottom-left: xs[1], ys[1]
    // top-right:   xs[2], ys[2]
}

To look for an intersection, you will have to do some simple comparison of the points:

two rectangles

So as we can see from the image if x3, y3 is greater or equal to x1, y1 and less than or equal to x2, y2 then it is inside the first rectangle, similarly you will need to check if x4, y4 falls inside the range of x1,y1 to x2,y2 as well.

if both conditions prove to be true then you can be sure that the second rectangle is totally encompassed by the first. intersectionrectangle 1 envelops rectangle 2

You will need to check the other way around as well, if finding out which is inside which is important to you.

You also have to have the rectangles be axis aligned, otherwise this will not work reliably.

Let me know if you need more detail, although I think a quick Google search will uncover much more detail for you very easily, but let me know and I can make a rectangle collision tutorial if you like.

In More Detail:

To find out if the rectangles have any intersections you can check the coordinates of their defining points, for our purposes we shall use top left and bottom right corner coordinates. We can utilise a class to make this easier for us, and to maximise on the usability of the code we can use a 2d Vector and a 2d Point: 2dVectorPoint.h

#include <cmath>

class Vector2D
{
    public:
        float   x;
        float   y;

        Vector2D() {}    
        Vector2D(float inX, float inY)
        {
            x = inX;
            y = inY;
        }

        Vector2D& Set(float inX, float inY)
        {
            x = inX;
            y = inY;
            return (*this);
        }

        float& operator [](long k)        {            return ((&x)[k]);        }

        const float& operator [](long k) const        {            return ((&x)[k]);        }

        Vector2D& operator +=(const Vector2D& v)
        {
            x += v.x;
            y += v.y;
            return (*this);
        }

        Vector2D& operator -=(const Vector2D& v)
        {
            x -= v.x;
            y -= v.y;
            return (*this);
        }

        Vector2D& operator *=(float t)
        {
            x *= t;
            y *= t;
            return (*this);
        }

        Vector2D& operator /=(float t)
        {
            float f = 1.0F / t;
            x *= f;
            y *= f;
            return (*this);
        }

        Vector2D& operator &=(const Vector2D& v)
        {
            x *= v.x;
            y *= v.y;
            return (*this);
        }

        Vector2D operator -(void) const        {            return (Vector2D(-x, -y));        }

        Vector2D operator +(const Vector2D& v) const        {            return (Vector2D(x + v.x, y + v.y));        }

        Vector2D operator -(const Vector2D& v) const        {  return (Vector2D(x - v.x, y - v.y));        }

        Vector2D operator *(float t) const        {            return (Vector2D(x * t, y * t));        }

        Vector2D operator /(float t) const        {     float f = 1.0F / t; return (Vector2D(x * , y * f));        }

        float operator *(const Vector2D& v) const        {            return (x * v.x + y * v.y);        }

        Vector2D operator &(const Vector2D& v) const     {            return (Vector2D(x * v.x, y * v.y));        }

        bool operator ==(const Vector2D& v) const        {            return ((x == v.x) && (y == v.y));        }

        bool operator !=(const Vector2D& v) const        {            return ((x != v.x) || (y != v.y));        }

        Vector2D& Normalize(void)                        {            return (*this /= sqrtf(x * x + y * y));        }

        Vector2D& Rotate(float angle);
};


class Point2D : public Vector2D
{
    public:

        Point2D() {}

        Point2D(float r, float s) : Vector2D(r, s) {}

        Point2D& operator =(const Vector2D& v)
        {
            x = v.x;
            y = v.y;
            return (*this);
        }

        Point2D& operator *=(float t)
        {
            x *= t;
            y *= t;
            return (*this);
        }

        Point2D& operator /=(float t)
        {
            float f = 1.0F / t;
            x *= f;
            y *= f;
            return (*this);
        }

        Point2D operator -(void) const{            return (Point2D(-x, -y));        }

        Point2D operator +(const Vector2D& v) const        {            return (Point2D(x + v.x, y + v.y));        }

        Point2D operator -(const Vector2D& v) const        {            return (Point2D(x - v.x, y - v.y));        }

        Vector2D operator -(const Point2D& p) const        {            return (Vector2D(x - p.x, y - p.y));        }

        Point2D operator *(float t) const        {            return (Point2D(x * t, y * t));        }

        Point2D operator /(float t) const
        {
            float f = 1.0F / t;
            return (Point2D(x * f, y * f));
        }
};


inline Vector2D operator *(float t, const Vector2D& v){    return (Vector2D(t * v.x, t * v.y));}

inline Point2D operator *(float t, const Point2D& p){    return (Point2D(t * p.x, t * p.y));}

inline float Dot(const Vector2D& v1, const Vector2D& v2){    return (v1 * v2);}

inline float Magnitude(const Vector2D& v){    return (sqrtf(v.x * v.x + v.y * v.y));}

inline float InverseMag(const Vector2D& v){    return (1.0F / sqrtf(v.x * v.x + v.y * v.y));}

inline float SquaredMag(const Vector2D& v){    return (v.x * v.x + v.y * v.y);}

struct Origin2D_
{
    const Point2D& operator +(const Vector2D& v)    {        return (static_cast<const Point2D&>(v));    }

    Point2D operator -(const Vector2D& v)    {        return (Point2D(-v.x, -v.y));    }
};

2dVectorPoint.cpp

#include "2dVectorPoint.h"

Origin2D_ Origin2D;

Vector2D& Vector2D::Rotate(float angle)
{
    float s = sinf(angle);
    float c = cosf(angle);

    float nx = c * x - s * y;
    float ny = s * x + c * y;

    x = nx;
    y = ny;

    return (*this);
}
extern Origin2D_ Origin2D;

Code used is adapted from here to save my fingers.

Then we can utilise this to easily compare: we can define rectangle 1 as having P1 and P2 as its bounds and rectangle 2 as having P3 and P4 as its bounds, giving us the following comparison:

if ( P2.y <= P3.y && P1.y >= P4.y && P2.x>= P3.x && P1.x <= P4.x )
{
    return true;
}

This will return a true value for any instance of intersection or for rectangle 1 encompassing rectangle 2 totally.

To only check for intersections just remove the equality check (take all the = out of the above equation), and you will be checking only for intersections. If you have an intersection you could then use linear algebra to evaluate the exact coordinates.


Let's say that a box has a radius X and radius Y (I know it has not but this term is useful here).

You will have:

rect1_x_radius = (x2-x1)/2
rect1_y_radius = (y2-y1)/2

and

rect2_x_radius = (x4-x3)/2
rect2_y_radius = (y4-y3)/2

Now if rect middle points are further away than sum of their radiuses in appropriate direction - they do not collide. Otherwise they do - this hint should suffice.

You should be now able to finish your assignment.

UPDATE:

OK - let's solve it for 1D - later you'll solve it for 2D. Look at this piece of ... art ;-)

enter image description here

You see 2 segments - now some calculations:

rA = (maxA-minA) / 2
rB = (maxB-minB) / 2

midA = minA + rA
midB = minB + rB

mid_dist = |midA - midB|

Now how to check if collision occurs? As I said if sum of 'radiuses' is less than segments' distance - there is no collision:

if ( mid_dist > fabs(rA+rB) )
{
    // no intersection
}
else
{
    // segments intersect
}

Now it is your work to calculate intersection / common part in 1D and 2D. It is up to you now (o ryou can read Andrey's answer).

Here is the same situation but in 2D - two 1D situations:

enter image description here