두 직사각형이 서로 겹치는 지 확인 하시겠습니까?


337

높이, 너비, x-pos, y-pos와 같이 직사각형을 구성하기 위해 사용자의 다음 입력을 사용하는 C ++ 프로그램을 작성하려고합니다. 이 모든 직사각형은 x 및 y 축에 평행하게 존재합니다. 즉, 모든 모서리의 기울기는 0 또는 무한대입니다.

질문에 언급 된 것을 구현하려고 시도했지만 운이별로 없습니다.

내 현재 구현은 다음을 수행합니다.

// Gets all the vertices for Rectangle 1 and stores them in an array -> arrRect1
// point 1 x: arrRect1[0], point 1 y: arrRect1[1] and so on...
// Gets all the vertices for Rectangle 2 and stores them in an array -> arrRect2

// rotated edge of point a, rect 1
int rot_x, rot_y;
rot_x = -arrRect1[3];
rot_y = arrRect1[2];
// point on rotated edge
int pnt_x, pnt_y;
pnt_x = arrRect1[2]; 
pnt_y = arrRect1[3];
// test point, a from rect 2
int tst_x, tst_y;
tst_x = arrRect2[0];
tst_y = arrRect2[1];

int value;
value = (rot_x * (tst_x - pnt_x)) + (rot_y * (tst_y - pnt_y));
cout << "Value: " << value;  

그러나 (a) 내가 올바르게 연결된 알고리즘을 구현했는지, 아니면 이것을 정확하게 해석하는 방법을 수행했는지 확실하지 않습니다.

어떤 제안?


3
나는 당신의 문제에 대한 해결책은 포함되지 않습니다 생각 어떤 곱셈.
Scott Evernden

답변:


708
if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
     RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top ) 

또는 직교 좌표를 사용하여

(좌표계가 X1 인 상태에서 X2가 우측 좌표가 되고 왼쪽에서 오른쪽으로 증가 하고 Y1이 최고 좌표가되고 Y2가 최하위 좌표가 되고 아래에서 위로 증가 합니다. 좌표계가 아닌 경우 (예 : 대부분의 컴퓨터는 Y 방향이 바]], 아래 비교를 교환하십시오 ) ...

if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
    RectA.Y1 > RectB.Y2 && RectA.Y2 < RectB.Y1) 

Rect A와 Rect B가 있다고 가정하십시오. 증거는 모순입니다. 네 가지 조건 중 하나에 해당 하면 겹침이 존재하지 않습니다 .

  • 조건 1. A의 왼쪽 가장자리가 B의 오른쪽 가장자리 오른쪽에 있으면-A는 완전히 B의 오른쪽입니다
  • Cond2. A의 오른쪽 가장자리가 B의 왼쪽 가장자리 왼쪽에 있으면-A는 B의 왼쪽에 완전히 있습니다
  • Cond3. A의 상단 가장자리가 B의 하단 가장자리 아래에 있으면-A는 완전히 B 아래에 있습니다
  • Cond4. A의 아래쪽 가장자리가 B의 위쪽 가장자리 위에 있으면-A는 완전히 B 위에 있습니다

겹치지 않는 조건은

비-중첩 => Cond1 또는 Cond2 또는 Cond3 또는 Cond4

따라서 오버랩에 대한 충분한 조건은 반대입니다.

오버랩 => NOT (Cond1 또는 Cond2 또는 Cond3 또는 Cond4)

De Morgan의 법칙에 따르면 De Morgan을 사용
Not (A or B or C or D)하는 것과 동일합니다.Not A And Not B And Not C And Not D

Cond1 및 Cond2 및 Cond3 및 Cond4 아님

이것은 다음과 같습니다.

  • A의 왼쪽 가장자리-B의 오른쪽 가장자리 왼쪽, [ RectA.Left < RectB.Right] 및
  • A의 오른쪽 가장자리부터 B의 왼쪽 가장자리, [ RectA.Right > RectB.Left] 및
  • A는 B의 맨 위, [ RectA.Top > RectB.Bottom] 및
  • A의 하단 B의 상단 [ RectA.Bottom < RectB.Top]

참고 1 :이 동일한 원칙을 여러 차원으로 확장 할 수 있음이 명백합니다.
참고 2 : 단지 하나의 픽셀의 겹침을 세고 그 경계 의 <및 / >또는를 a <=또는 a로 변경하는 것도 분명해야 합니다 >=.
참고 3 :이 답변은 직교 좌표 (X, Y)를 사용할 때 표준 대수 직교 좌표를 기반으로합니다 (x는 왼쪽에서 오른쪽으로 증가하고 Y는 아래쪽에서 위쪽으로 증가합니다). 컴퓨터 시스템이 화면 좌표를 다르게 기계화 할 수있는 경우 (예 : Y를 위에서 아래로 또는 X를 오른쪽에서 왼쪽으로 증가) 구문을 적절하게 조정해야합니다.


489
왜 작동하는지 시각화하는 데 어려움을 겪고 있다면 silentmatt.com/intersection.html 에서 사각형을 드래그하고 비교를 볼 수 있는 예제 페이지를 만들었 습니다.
Matthew Crumley

4
어려운 제약 조건을 사용하고 있다고 생각하지 않습니까? 두 사각형이 서로 정확히 겹치면 어떻게해야합니까? <=,> = ??
Nawshad Farruque

6
귀하의 링크에서 A.Y1 <B.Y2 및 A.Y2> B.Y1의 @MatthewCrumley는 gt 및 lt 부호가 반대로되어서는 안됩니까?
NikT

15
나는 그것이 작동되도록하려면 마지막 두 comparisions 스왑 <와>에 있었다
DataGreed

17
아니요, 답변은 명시된대로 정확합니다. 표준 데카르트 좌표를 사용합니다. 다른 시스템을 사용하는 경우 (Y는 위에서 아래로 증가) 적절하게 조정하십시오.
Charles Bretana

115
struct rect
{
    int x;
    int y;
    int width;
    int height;
};

bool valueInRange(int value, int min, int max)
{ return (value >= min) && (value <= max); }

bool rectOverlap(rect A, rect B)
{
    bool xOverlap = valueInRange(A.x, B.x, B.x + B.width) ||
                    valueInRange(B.x, A.x, A.x + A.width);

    bool yOverlap = valueInRange(A.y, B.y, B.y + B.height) ||
                    valueInRange(B.y, A.y, A.y + A.height);

    return xOverlap && yOverlap;
}

15
가장 간단하고 깨끗한 답변.
ldog

1
@ e.James 나는 마지막을 생각 B.height해야한다A.height
mat_boy

'min'및 'max'는 <windows.h>에서 예약 된 키워드입니다. 당신은 수행하여 문제를 해결할 수 #undef min#undef max, 또는 다른 매개 변수 이름을 사용하여.
mchiasson

광범위하게 사용하는 경우 valueInRange를 다음과 같이 거래 할 수 있습니다.#define BETWEEN(value,min,max) \ (\ value > max ? max : ( value < min ? min : value )\ )
Ratata Tata

@Nemo 사실, 확인 xOverlap은 1 차원입니다. rectOverlap2 차원입니다. 루프를 사용하여 N 치수로 확장 할 수 있습니다.
Justme0

27
struct Rect
{
    Rect(int x1, int x2, int y1, int y2)
    : x1(x1), x2(x2), y1(y1), y2(y2)
    {
        assert(x1 < x2);
        assert(y1 < y2);
    }

    int x1, x2, y1, y2;
};

bool
overlap(const Rect &r1, const Rect &r2)
{
    // The rectangles don't overlap if
    // one rectangle's minimum in some dimension 
    // is greater than the other's maximum in
    // that dimension.

    bool noOverlap = r1.x1 > r2.x2 ||
                     r2.x1 > r1.x2 ||
                     r1.y1 > r2.y2 ||
                     r2.y1 > r1.y2;

    return !noOverlap;
}

좋은 것! De Morgans 법칙을 적용하면 r1.x1 <= r2.x2 && r2.x1 <= r1.x2 && r1.y1 <= r2.y2 && r2.y1 <= r1.y2가됩니다.
Borzh

23

사각형이 다른 사각형 바깥에 있는지 확인하는 것이 더 쉽습니다.

왼쪽에...

(r1.x + r1.width < r2.x)

또는 오른쪽에 ...

(r1.x > r2.x + r2.width)

또는 위에 ...

(r1.y + r1.height < r2.y)

또는 바닥에 ...

(r1.y > r2.y + r2.height)

두 번째 사각형 중 하나와 충돌 할 수 없습니다. 따라서 사각형이 충돌하는 날씨를 나타내는 부울을 반환하는 함수를 가지려면 논리 OR로 조건을 결합하고 결과를 무시하면됩니다.

function checkOverlap(r1, r2) : Boolean
{ 
    return !(r1.x + r1.width < r2.x || r1.y + r1.height < r2.y || r1.x > r2.x + r2.width || r1.y > r2.y + r2.height);
}

만 터치 할 때 이미 긍정적 인 결과를 얻으려면 "<="및 "> ="로 "<"및 ">"를 변경할 수 있습니다.


3
그리고 드 모건의 법칙을 적용하십시오.
Borzh

6

자신에게 반대되는 질문을하십시오. 두 개의 사각형이 전혀 교차하지 않는지 어떻게 알 수 있습니까? 분명히, 사각형 B의 왼쪽에 완전히있는 사각형 A는 교차하지 않습니다. 또한 A가 완전히 오른쪽에 있다면. 마찬가지로 A가 B보다 높거나 B보다 완전히 낮을 경우와 유사합니다. 다른 경우 A와 B가 교차합니다.

다음은 버그가있을 수 있지만 알고리즘에 대해 확신합니다.

struct Rectangle { int x; int y; int width; int height; };

bool is_left_of(Rectangle const & a, Rectangle const & b) {
   if (a.x + a.width <= b.x) return true;
   return false;
}
bool is_right_of(Rectangle const & a, Rectangle const & b) {
   return is_left_of(b, a);
}

bool not_intersect( Rectangle const & a, Rectangle const & b) {
   if (is_left_of(a, b)) return true;
   if (is_right_of(a, b)) return true;
   // Do the same for top/bottom...
 }

bool intersect(Rectangle const & a, Rectangle const & b) {
  return !not_intersect(a, b);
}

6

다음과 같이 사각형의 위치와 크기를 정의했다고 가정합니다.

여기에 이미지 설명을 입력하십시오

내 C ++ 구현은 다음과 같습니다.

class Vector2D
{
    public:
        Vector2D(int x, int y) : x(x), y(y) {}
        ~Vector2D(){}
        int x, y;
};

bool DoRectanglesOverlap(   const Vector2D & Pos1,
                            const Vector2D & Size1,
                            const Vector2D & Pos2,
                            const Vector2D & Size2)
{
    if ((Pos1.x < Pos2.x + Size2.x) &&
        (Pos1.y < Pos2.y + Size2.y) &&
        (Pos2.x < Pos1.x + Size1.x) &&
        (Pos2.y < Pos1.y + Size1.y))
    {
        return true;
    }
    return false;
}

위의 주어진 그림에 따른 함수 호출 예 :

DoRectanglesOverlap(Vector2D(3, 7),
                    Vector2D(8, 5),
                    Vector2D(6, 4),
                    Vector2D(9, 4));

if블록 내부의 비교 는 다음과 같습니다.

if ((Pos1.x < Pos2.x + Size2.x) &&
    (Pos1.y < Pos2.y + Size2.y) &&
    (Pos2.x < Pos1.x + Size1.x) &&
    (Pos2.y < Pos1.y + Size1.y))
                   
if ((   3   <    6   +   9    ) &&
    (   7   <    4   +   4    ) &&
    (   6   <    3   +   8    ) &&
    (   4   <    7   +   5    ))

3

Java API에서 수행되는 방법은 다음과 같습니다.

public boolean intersects(Rectangle r) {
    int tw = this.width;
    int th = this.height;
    int rw = r.width;
    int rh = r.height;
    if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
        return false;
    }
    int tx = this.x;
    int ty = this.y;
    int rx = r.x;
    int ry = r.y;
    rw += rx;
    rh += ry;
    tw += tx;
    th += ty;
    //      overflow || intersect
    return ((rw < rx || rw > tx) &&
            (rh < ry || rh > ty) &&
            (tw < tx || tw > rx) &&
            (th < ty || th > ry));
}

C ++에서는 부호있는 정수 오버플로가 정의되지 않았기 때문에 오버플로에 대한 테스트가 작동하지 않습니다.
Ben Voigt

2

문제에서 사각형이 임의의 회전 각도에있을 때의 수학에 연결됩니다. 그러나 질문의 ​​각도에 대한 비트를 이해하면 모든 사각형이 서로 직각이라는 것을 해석합니다.

오버랩 공식의 영역을 아는 일반적인 사항은 다음과 같습니다.

예제를 사용하여 :

   12 34 5 6

1 + --- + --- +
   | |   
2 + A + --- + --- +
   | | B |
3 + + + --- + --- +
   | | | | |
4 + --- + --- + --- + --- + +
               | |
5 + C +
               | |
6 + --- + --- +

1) 모든 x 좌표 (좌우 모두)를 목록으로 수집 한 다음 정렬하고 중복을 제거하십시오.

1 3 4 5 6

2) 모든 y 좌표 (위와 아래 모두)를 목록으로 수집 한 다음 정렬하고 중복을 제거하십시오.

12 34 6

3) 고유 x 좌표 사이의 갭 수 * 고유 y 좌표 사이의 갭 수로 2D 배열을 만듭니다.

4 * 4

4) 모든 사각형을이 격자에 페인트하여 발생하는 각 셀의 수를 증가시킵니다.

   1 3 4 5 6

1 + --- +
   | 1 | 0 0 0
2 + --- + --- + --- +
   | 1 | 1 | 1 | 0
3 + --- + --- + --- + --- +
   | 1 | 1 | 2 | 1 |
4 + --- + --- + --- + --- +
     0 0 | 1 | 1 |
6 + --- + --- +

5) 사각형을 칠할 때 오버랩을 쉽게 가로 챌 수 있습니다.


2
struct Rect
{
   Rect(int x1, int x2, int y1, int y2)
   : x1(x1), x2(x2), y1(y1), y2(y2)
   {
       assert(x1 < x2);
       assert(y1 < y2);
   }

   int x1, x2, y1, y2;
};

//some area of the r1 overlaps r2
bool overlap(const Rect &r1, const Rect &r2)
{
    return r1.x1 < r2.x2 && r2.x1 < r1.x2 &&
           r1.y1 < r2.y2 && r2.x1 < r1.y2;
}

//either the rectangles overlap or the edges touch
bool touch(const Rect &r1, const Rect &r2)
{
    return r1.x1 <= r2.x2 && r2.x1 <= r1.x2 &&
           r1.y1 <= r2.y2 && r2.x1 <= r1.y2;
}

1

좌표를 픽셀의 위치를 ​​나타내는 것으로 생각하지 마십시오. 그것들을 픽셀 사이에 있다고 생각하십시오. 이렇게하면 2x2 사각형의 영역이 9가 아닌 4가되어야합니다.

bool bOverlap = !((A.Left >= B.Right || B.Left >= A.Right)
               && (A.Bottom >= B.Top || B.Bottom >= A.Top));

1

가장 쉬운 방법은

/**
 * Check if two rectangles collide
 * x_1, y_1, width_1, and height_1 define the boundaries of the first rectangle
 * x_2, y_2, width_2, and height_2 define the boundaries of the second rectangle
 */
boolean rectangle_collision(float x_1, float y_1, float width_1, float height_1, float x_2, float y_2, float width_2, float height_2)
{
  return !(x_1 > x_2+width_2 || x_1+width_1 < x_2 || y_1 > y_2+height_2 || y_1+height_1 < y_2);
}

우선 컴퓨터에서 좌표계가 거꾸로되어 있다는 사실을 명심하십시오. x 축은 수학과 동일하지만 y 축은 아래쪽으로 증가하고 위쪽으로 갈수록 감소합니다. 직사각형이 중심에서 그려지는 경우. x1 좌표가 x2보다 큰 widht의 절반을 더한 경우 반은 서로 접촉한다는 뜻입니다. 같은 방식으로 높이의 절반 아래로 내려갑니다. 충돌합니다 ..


1

두 직사각형이 직사각형 A와 직사각형 B라고 가정 해 봅시다. 중심을 A1과 B1 (A1과 B1의 좌표를 쉽게 찾을 수 있음)으로 설정하고 높이를 Ha와 Hb, 너비는 Wa와 Wb, dx는 A1과 B1 사이의 너비 (x) 거리와 dy는 A1과 B1 사이의 높이 (y) 거리입니다.

이제 A와 B가 겹칠 수 있다고 말할 수 있습니다.

if(!(dx > Wa+Wb)||!(dy > Ha+Hb)) returns true

0

C # 버전을 구현했으며 C ++로 쉽게 변환됩니다.

public bool Intersects ( Rectangle rect )
{
  float ulx = Math.Max ( x, rect.x );
  float uly = Math.Max ( y, rect.y );
  float lrx = Math.Min ( x + width, rect.x + rect.width );
  float lry = Math.Min ( y + height, rect.y + rect.height );

  return ulx <= lrx && uly <= lry;
}

2
훈련 된 눈에는 이것이 Rectangle의 확장 클래스라는 것을 분명히 알았지 만 실제로 그렇게 할 수있는 경계 나 코드는 제공하지 않았습니다. 당신이 그렇게했거나 그것이 당신의 방법이 어떻게 사용되어야하는지 설명하고 변수가 실제로 그들의 목적 / 의도를 이해하기 위해 따르는 사람에게 충분한 이름을 가진다면 보너스 포인트가 좋을 것입니다.
tpartee

0

나는 매우 쉬운 해결책이 있습니다

x1, y1 x2, y2, l1, b1, l2를 각각의 좌표와 길이 및 너비로 설정하십시오.

조건을 고려하십시오 ((x2

이제이 사각형이 겹치는 유일한 방법은 x1, y1의 대각선이 다른 사각형 안에 있거나 x2, y2의 대각선이 다른 사각형 안에있을 경우입니다. 정확히 위의 조건을 의미합니다.


0

A와 B는 두 개의 직사각형입니다. C는 덮는 사각형입니다.

four points of A be (xAleft,yAtop),(xAleft,yAbottom),(xAright,yAtop),(xAright,yAbottom)
four points of A be (xBleft,yBtop),(xBleft,yBbottom),(xBright,yBtop),(xBright,yBbottom)

A.width = abs(xAleft-xAright);
A.height = abs(yAleft-yAright);
B.width = abs(xBleft-xBright);
B.height = abs(yBleft-yBright);

C.width = max(xAleft,xAright,xBleft,xBright)-min(xAleft,xAright,xBleft,xBright);
C.height = max(yAtop,yAbottom,yBtop,yBbottom)-min(yAtop,yAbottom,yBtop,yBbottom);

A and B does not overlap if
(C.width >= A.width + B.width )
OR
(C.height >= A.height + B.height) 

가능한 모든 경우를 처리합니다.


0

이것은 Java Programming-Comprehensive Edition 소개 책의 연습 3.28에서 발췌 한 것입니다. 이 코드는 두 사각형이 함몰되어 있는지, 하나의 사각형이 다른 사각형 안에 있는지, 다른 사각형 안에 있는지 여부를 테스트합니다. 이러한 조건 중 어느 것도 충족되지 않으면 두 개가 겹칩니다.

** 3.28 (형상 : 사각형 두 개) 사용자에게 두 사각형의 중심 x, y 좌표, 너비 및 높이를 입력하라는 메시지를 표시하고 두 번째 사각형이 첫 번째 사각형 안에 있는지 또는 첫 번째 사각형과 겹치는지를 결정하는 프로그램을 작성합니다. 그림 3.9와 같이. 모든 사례를 다루기 위해 프로그램을 테스트하십시오. 다음은 샘플 실행입니다.

r1의 중심 x, y 좌표, 너비 및 높이를 입력합니다 : 2.5 4 2.5 43 r2의 중심 x, y 좌표, 너비 및 높이를 입력합니다 : 1.5 5 0.5 3 r2는 r1 안에 있습니다

r1의 중심 x, y 좌표, 너비 및 높이를 입력합니다. 1 2 3 5.5 r2의 중심 x, y 좌표, 너비 및 높이를 입력합니다. 3 4 4.5 5 r2가 r1과 겹칩니다.

r1의 중심 x, y 좌표, 너비 및 높이를 입력하십시오. 1 2 3 3 r2의 중심 x, y 좌표, 너비 및 높이를 입력하십시오. 40 45 3 2 r2가 r1과 겹치지 않습니다.

import java.util.Scanner;

public class ProgrammingEx3_28 {
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    System.out
            .print("Enter r1's center x-, y-coordinates, width, and height:");
    double x1 = input.nextDouble();
    double y1 = input.nextDouble();
    double w1 = input.nextDouble();
    double h1 = input.nextDouble();
    w1 = w1 / 2;
    h1 = h1 / 2;
    System.out
            .print("Enter r2's center x-, y-coordinates, width, and height:");
    double x2 = input.nextDouble();
    double y2 = input.nextDouble();
    double w2 = input.nextDouble();
    double h2 = input.nextDouble();
    w2 = w2 / 2;
    h2 = h2 / 2;

    // Calculating range of r1 and r2
    double x1max = x1 + w1;
    double y1max = y1 + h1;
    double x1min = x1 - w1;
    double y1min = y1 - h1;
    double x2max = x2 + w2;
    double y2max = y2 + h2;
    double x2min = x2 - w2;
    double y2min = y2 - h2;

    if (x1max == x2max && x1min == x2min && y1max == y2max
            && y1min == y2min) {
        // Check if the two are identicle
        System.out.print("r1 and r2 are indentical");

    } else if (x1max <= x2max && x1min >= x2min && y1max <= y2max
            && y1min >= y2min) {
        // Check if r1 is in r2
        System.out.print("r1 is inside r2");
    } else if (x2max <= x1max && x2min >= x1min && y2max <= y1max
            && y2min >= y1min) {
        // Check if r2 is in r1
        System.out.print("r2 is inside r1");
    } else if (x1max < x2min || x1min > x2max || y1max < y2min
            || y2min > y1max) {
        // Check if the two overlap
        System.out.print("r2 does not overlaps r1");
    } else {
        System.out.print("r2 overlaps r1");
    }

}
}

0
bool Square::IsOverlappig(Square &other)
{
    bool result1 = other.x >= x && other.y >= y && other.x <= (x + width) && other.y <= (y + height); // other's top left falls within this area
    bool result2 = other.x >= x && other.y <= y && other.x <= (x + width) && (other.y + other.height) <= (y + height); // other's bottom left falls within this area
    bool result3 = other.x <= x && other.y >= y && (other.x + other.width) <= (x + width) && other.y <= (y + height); // other's top right falls within this area
    bool result4 = other.x <= x && other.y <= y && (other.x + other.width) >= x && (other.y + other.height) >= y; // other's bottom right falls within this area
    return result1 | result2 | result3 | result4;
}

0

직사각형 x, y, w, h 또는 x0, y0, x1, x1 대신 직사각형 데이터에 중심점과 반 크기를 사용하는 사용자의 경우 다음과 같이 수행 할 수 있습니다.

#include <cmath> // for fabsf(float)

struct Rectangle
{
    float centerX, centerY, halfWidth, halfHeight;
};

bool isRectangleOverlapping(const Rectangle &a, const Rectangle &b)
{
    return (fabsf(a.centerX - b.centerX) <= (a.halfWidth + b.halfWidth)) &&
           (fabsf(a.centerY - b.centerY) <= (a.halfHeight + b.halfHeight)); 
}

0
struct point { int x, y; };

struct rect { point tl, br; }; // top left and bottom right points

// return true if rectangles overlap
bool overlap(const rect &a, const rect &b)
{
    return a.tl.x <= b.br.x && a.br.x >= b.tl.x && 
           a.tl.y >= b.br.y && a.br.y <= b.tl.y;
}

0

사각형이 겹치면 겹침 영역이 0보다 큽니다. 이제 겹침 영역을 찾으십시오.

그것들이 겹치면 겹침 -rect의 왼쪽 가장자리가 max(r1.x1, r2.x1)되고 오른쪽 가장자리는입니다 min(r1.x2, r2.x2). 오버랩의 길이는min(r1.x2, r2.x2) - max(r1.x1, r2.x1)

따라서이 영역은 다음과 같습니다.

area = (max(r1.x1, r2.x1) - min(r1.x2, r2.x2)) * (max(r1.y1, r2.y1) - min(r1.y2, r2.y2))

그렇다면 area = 0겹치지 않습니다.

간단하지 않습니까?


3
이것은 겹침 (문제)에서 작동하지만 교차점에서는 정확히 교차하지 않으면 교차하지 않습니다.
랜스 로버츠

이 코드를 시도했지만 전혀 작동하지 않습니다. 전혀 겹치지 않더라도 양수를 얻습니다.
Brett

@Brett : 그렇습니다. 두 음수의 곱은 양수이기 때문입니다.
Ben Voigt

@ BenVoigt, 문제는 겹침이 없을 때 함수가 0을 반환하지 않는다는 것입니다. 내 의견으로는 매우 불분명했지만 예,이 기능에서 영역> 0 만 받았습니다.
Brett

부동 소수점 숫자로 작업하는 경우 일반적으로 숫자를 비교하기 전에 빼기와 다른 산술을 사용하는 것이 좋습니다. 특히 정확한 값과 비교 해야하는 경우-이 경우 0입니다. 이론적으로는 작동하지만 실제로는 작동하지 않습니다.
maja


-1

사각형이 서로 접촉하거나 겹치는 지 알아내는 Java 코드

...

for ( int i = 0; i < n; i++ ) {
    for ( int j = 0; j < n; j++ ) {
        if ( i != j ) {
            Rectangle rectangle1 = rectangles.get(i);
            Rectangle rectangle2 = rectangles.get(j);

            int l1 = rectangle1.l; //left
            int r1 = rectangle1.r; //right
            int b1 = rectangle1.b; //bottom
            int t1 = rectangle1.t; //top

            int l2 = rectangle2.l;
            int r2 = rectangle2.r;
            int b2 = rectangle2.b;
            int t2 = rectangle2.t;

            boolean topOnBottom = t2 == b1;
            boolean bottomOnTop = b2 == t1;
            boolean topOrBottomContact = topOnBottom || bottomOnTop;

            boolean rightOnLeft = r2 == l1;
            boolean leftOnRight = l2 == r1;
            boolean rightOrLeftContact = leftOnRight || rightOnLeft;

            boolean leftPoll = l2 <= l1 && r2 >= l1;
            boolean rightPoll = l2 <= r1 && r2 >= r1;
            boolean leftRightInside = l2 >= l1 && r2 <= r1;
            boolean leftRightPossiblePlaces = leftPoll || rightPoll || leftRightInside;

            boolean bottomPoll = t2 >= b1 && b2 <= b1;
            boolean topPoll = b2 <= b1 && t2 >= b1;
            boolean topBottomInside = b2 >= b1 && t2 <= t1;
            boolean topBottomPossiblePlaces = bottomPoll || topPoll || topBottomInside;


            boolean topInBetween = t2 > b1 && t2 < t1;
            boolean bottomInBetween = b2 > b1 && b2 < t1;
            boolean topBottomInBetween = topInBetween || bottomInBetween;

            boolean leftInBetween = l2 > l1 && l2 < r1;
            boolean rightInBetween = r2 > l1 && r2 < r1;
            boolean leftRightInBetween = leftInBetween || rightInBetween;

            if ( (topOrBottomContact && leftRightPossiblePlaces) || (rightOrLeftContact && topBottomPossiblePlaces) ) {
                path[i][j] = true;
            }
        }
    }
}

...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.