# How do I calculate distance from a point to a rectangle?

I have a 2D rectangle with x, y position, height and width, and a randomly positioned point nearby.

Is there a way to check if this point might collide with the rectangle if it is closer than a certain distance? Imagine an invisible radius outside of that point colliding with said rectangle. I have problems with this simply because it is not a square, it would be so much easier this way!

-

You must use circle-rectangle collisions for this. There's a similar question on Stack Overflow.

Your circle's center would be the point in question, and the radius would be the distance you want to check.

-

The squared distance from a point `(px,py)` to the rectangle's border can be computed this way:

``````dx = max(abs(px - x) - width / 2, 0);
dy = max(abs(py - y) - height / 2, 0);
return dx * dx + dy * dy;
``````

If that squared distance is zero, it means the point touches or is inside the rectangle.

-

If you want to see if the point is within say 10 units if the grey rectangle in the image below, you check if the point is in any one of

1. red rectangle
2. Blue rectangle
3. any one of the green circles (radius 10)

``````inside=false;

bluerect.x=oldrect.x-10;
bluerect.y=oldrect.y;
bluerect.width=oldrect.width;
bluerect.height=oldrect.height+20;

if(  point.x >=bluerect && point.x <=redrect.x+bluerect.width &&
point.y >=bluerect && point.y <=redrect.y+bluerect.height){
//now point is side the blue rectangle
inside=true;
}

redrect.x=oldrect.x;
redrect.y=oldrect.y-10;
redrect.width=oldrect.width+20;
redrect.height=oldrect.height;

if(  point.x >=redrect&& point.x <=redrect.x+redrect.width &&
point.y >=redrect&& point.y <=redrect.y+redrect.height){
//now point is side the redrectangle
inside=true;
}

d1= distance(point, new point(oldrect.x, oldrect.y)) //calculate distance between point and (oldrect.x, oldrect.y)
d2= distance(point, new point(oldrect.x+10, oldrect.y))
d3= distance(point, new point(oldrect.x, oldrect.y+10))
d4= distance(point, new point(oldrect.x+10, oldrect.y+10))
if (d1 < 10 || d2 <10 || d3 < 10 || d4 <10){
inside=true;
}

//inside is now true if the point is within 10 units of rectangle
``````

This approach is a little inelegant. A similar method which avoids having to test all 4 corners by using rectangle symmetry is documented here on stackoverflow

-
 In the diagonal direction this will give a false positive to points that are eg. 11 units away. – Eric B Nov 26 '12 at 15:56 The updated picture is blatantly wrong, in fact it actually illustrates the error case and makes it appear correct. That green point could easily be more than 10 units away and be inside that outer rectangle. – Eric B Nov 26 '12 at 16:15 Hey @EricB, I've fixed the error you pointed out, how about undoing your downvote? – Ken Nov 26 '12 at 17:37 Your answer will no longer give strictly incorrect results, so I removed the downvote, but it is also not the best way at all. Why not just test to see if the center is within the rectangle, and if the four line segments intersect the circle? The construction of these new rectangles and circles is just not necessary. Your answer also does not provide the actual distance from the point to the rectangle. – Eric B Nov 26 '12 at 17:52 This answer is honestly awful. 12 additions, 4 object constructions, 12 tests, 4 square roots for a task that actually requires 3 lines of code? – Sam Hocevar Nov 28 '12 at 12:12
show 1 more comment

I assume your rectangle is Axis-Aligned.

You just have to "clamp" the point into rectangle and then compute the distance from clamped point.

Point = (px, py), Rectangle = (rx, ry, rwidth, rheight) // (top left corner, dimensions)

``````function pointRectDist (px, py, rx, ry, rwidth, rheight)
{
var cx = Math.max(Math.min(px, rx+rwidth ), rx);
var cy = Math.max(Math.min(py, ry+rheight), ry);
return Math.sqrt( (px-cx)*(px-cx) + (py-cy)*(py-cy) );
}
``````
-

Knowing the x and y coords and the width and height, you can calculate the position of the center and of the first and last corners.

a=corner1 b=corner2 c=corner3 d=corner4

a----------b

|,,,,,,,,,,,,,,|

|,,,,,,,,,,,,,,|

|,,,,,,,,,,,,,,|

c----------d

``````c1x=corner1x;c1y=corner1y;
c4x=corner4x;c4y=corner4y;
px=pointx;py=pointy;
if((px>c1x&&px<c4x)&&(py>c1y&&py<c4y))
//point is inside the rectangle
else
//point is not inside the rectangle
``````
-
He didn't ask for the distance to the center. He wants to detect a collision, and just the distance to the center of the rectangle is not enough information to detect one. – Eric B Nov 26 '12 at 16:02

You could use something like this:

-
 This method seems unnecessarily complicated. Finding x1 and y1 is not necessary to solve this problem. – Eric B Nov 26 '12 at 15:59 In fact, this doesn't even satisfy the requirement of finding a collision within a given distance. It's just a bad way of detecting if the point is within the rectangle. – Eric B Nov 26 '12 at 16:06 A measure of distance is already implicitly there. if (d2<10*10) {/*within 10 units of measure*/} – AlexanderBrevig Nov 27 '12 at 12:04