0
votes

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!
1
stackoverflow.com/questions/401847/… One of the answers has a C implementation...MuertoExcobito
That answer doesnt give a satisfactory solution, as I don't know how to implement the sub functionsYaxlat
I said one of the answers has a C implementation... above is from the one I was talking about.MuertoExcobito

1 Answers

0
votes

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;
}