0

I want to create a function which takes a rectangle and a circle returns a boolean as to whether or not they intersect. What's the most efficient and simple way of doing this? The function looks something like this:

bool intersect(rectX, rectY, rectWidth, rectHeight, circleX, circleY, radius) 
{
    bool intersect;
    //code I need
    return intersect;
}

Please help me find the code I need. Thanks!
Yaxlat
  • 665
  • 1
  • 10
  • 25

1 Answers1

0

Your answer is at last, but I also want to inform you/future viewer, the following.

When you are denoting a rectangle by one point AND height-width that is not specific rectangle on axis-system, that is general form of a rectangle can be draw anywhere.

So, In your case: Rectangle can be draw in any direction(to make it away from circle, eg: UP,LEFT,RIGHT,BOTTOM etc. side to rectX,rectY). That's why here two possibilities generates AND your possibility will depends on what you need:

[A] 100% assurance of intersection, no matter how you draw rectangle

[b] At least one way to draw the rectangle so that it will intersect with circle

Case A:

bool assuredIntersect(rectX, rectY, rectWidth, rectHeight, circleX, circleY, radius){
    bool intersect;
    float distance=((rectX-circleX)^2+(rectY-circleY)^2)^0.5;
    intersect=(radious>=distance);
    return intersect;
}

Case B:

bool canIntersect(rectX, rectY, rectWidth, rectHeight, circleX, circleY, radius){
    bool intersect;
    float distance=((rectX-circleX)^2+(rectY-circleY)^2)^0.5;
    float diagonal=((rectX+rectHeight)^2+(rectY-rectWidth)^2)^0.5;
    intersect=((radious+diagonal)<distance);
    return intersect;
}

But, if you are denoting rectangle by two-points-with-one-side (rectX1,rectY1 AND rectX2,rectY2 AND height or width). Then you can denote a rectangle specifically.

Note: If direction of rectangle is fixed(like shorter-side-from-point(rectX,rectY) is perpendicular-or-at-an-angle to x-axis) then also rectangle become specific as we can calculate (rectX2,rectY2). Eg: if angle is 90 then second point will be (rectX+rectHeight, rectY+rectWidth).

If we have function parameter like this:

#include <math.h>
#define PI 3.14159265

bool intersect(rX1, rY1, rX2, rY2, rAngle, cX, cY, cR){
//can be `intersect(rX1,rY1,rH,rW,rAngle, cX,cY, cR)`, and calculate rX2,rY2
//can be `intersect(rX1,rY1,rX2,rY2,rH, cX,cY, cR)`, and calculate rAngle
    bool intersect;
    //assume (rX1,rY1) as origin AND rectangle`s-side attached to this point is on both axis,
    //THEN we need to recalculate coordinates according to this assumption

    rAngle=rAngle*PI/180; //angle in radian
    //NOTE: if in place of rAngle, rHeight or rWidth is given then you can calculate rAngle by trigonometry.

    //moving rX1,xY1 to (0,0)
    cX=cX-rX1; cY=cY-rY1;
    rX2-=rX1; rY2-=rY1; rX1=rY1=0;

    //rotating axis, rectangle, circle...
    float cosA=cos(rAngle), sinA=sin(rAngle);
    float tempX= cosA*rX2 + sinA*rY2;
    float tempY= sinA*rX2 + cosA*rY2;
    rX2=tempX; rY2=tempY;
    tempX=cosA*cX + sinA*cY;
    tempY=sinA*cX + cosA*cY;
    cX=tempX; cY=tempY;

    rX1-=cR;rY1-=cR; //enlarging(creating) virtual rectangle around original; After this...
    rX2+=cR;rY2+=cR; //...if circle centre is inside this rectangle it will intersect with original rectangle
    intersect=(cX<=rX2 && cX>=rX1 && cY<=rY2 && cY>=rY1);
    return intersect;
}

point(x,y) rotation

# So, if you don't know angle then you can consider first two case.


[ANSWER] If rectangle is axis aligned then function will be:

bool intersect(rectX, rectY, rectWidth, rectHeight, circleX, circleY, radius){
    bool intersect;

    //calculating rX2,xY2
    rX2=rectX + rectWidth; rY2=rectY + rectHeight;

    rectX-=radius;rectY-=radius; //enlarging(creating) virtual rectangle around original; After this...
    rX2+=radius;rY2+=radius; //...if circle centre is inside this rectangle it will intersect with original rectangle ...
    intersect=(circleX<=rX2 && circleX>=rectX && circleY<=rY2 && circleY>=rectY);
    return intersect;
}
Adarsh Rajput
  • 1,246
  • 14
  • 24
  • The answer at the end is incomplete. This solution does not correctly account for circles at the corners of the rectangle. It's basically just checking if the rectangle and bounding box of the circle intersect. See [this answer to another question](https://stackoverflow.com/a/402010/3221383) for a complete solution. – pigi5 Mar 09 '21 at 02:38