점과 축 정렬 사각형 사이의 거리를 어떻게 계산합니까? 특정 거리보다 가까운 경우이 점이 사각형과 충돌하는지

x, y 위치, 높이 및 너비 및 임의로 위치가 지정된 2D 직사각형이 근처에 있습니다.

이 점이 특정 거리보다 가까운 경우이 점이 사각형과 충돌하는지 확인하는 방법이 있습니까? 해당 사각형의 바깥쪽에 보이지 않는 반경이 있다고 상상해보십시오. 사각형이 아니기 때문에 이것에 문제가 있습니다!



답변

(x,y)사각형의 중심 이면 점으로부터의 제곱 거리(px,py) 에서 사각형의 경계 계산할 수 있습니다.

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

이 제곱 거리가 0이면 점이 사각형에 닿거나 안에 있음을 의미합니다.


답변

직사각형이 축 정렬이라고 가정합니다.

점을 사각형에 “고정”한 다음 고정 점과의 거리를 계산하면됩니다.

Point = (px, py), Rectangle = (rx, ry, rwidth, rheight) // (왼쪽 상단, 치수)

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

답변

이를 위해 반드시 원-사각 충돌을 사용해야합니다. 있다 유사한스택 오버플로에 질문 .

원의 중심이 문제의 지점이되고 반경은 확인하려는 거리가됩니다.


답변

점에서 사각형의 가장자리까지의 거리를 알아 내려는 경우 사각형으로 만든 9 개의 영역 각각을 사용하는 것이 가장 빠른 방법 일 수 있습니다.

function pointRectangleDistance(x, y, x1, y1, x2, y2) {
    var dx, dy;
    if (x < x1) {
        dx = x1 - x;
        if (y < y1) {
            dy = y1 - y;
            return Math.sqrt(dx * dx + dy * dy);
        }
        else if (y > y2) {
            dy = y - y2;
            return Math.sqrt(dx * dx + dy * dy);
        }
        else {
            return dx;
        }
    }
    else if (x > x2) {
        dx = x - x2;
        if (y < y1) {
            dy = y1 - y;
            return Math.sqrt(dx * dx + dy * dy);
        }
        else if (y > y2) {
            dy = y - y2;
            return Math.sqrt(dx * dx + dy * dy);
        }
        else {
            return dx;
        }
    }
    else {
        if (y < y1) {
            return y1 - y;
        }
        else if (y > y2) {
            return y - y2;
        }
        else {
            return 0.0; // inside the rectangle or on the edge
        }
    }
}

답변

[댓글을 기반으로 수정 된 답변]

아래 이미지의 회색 사각형이 포인트가 10 단위 이내인지 확인하려면 포인트가 다음 중 하나에 있는지 확인하십시오.

  1. 빨간 사각형
  2. 파란색 사각형
  3. 녹색 원 중 하나 (반지름 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

이 접근법은 약간 우아하지 않습니다. 사각형 대칭을 사용하여 4 개의 모서리를 모두 테스트하지 않아도되는 비슷한 방법이 여기설명되어 있습니다 .


답변

다음과 같은 것을 사용할 수 있습니다.