0

필자는 화면에서 객체 간의 충돌을 확인하는 데 사용할 함수가 두 가지 있습니다.이 함수는 많이 실행될 것이므로 최대한 효율적으로 실행하고 싶습니다. 그들은 현재 상당히 엉망으로 보이기 때문에 당신의 도움을 얻을 수 있는지 궁금합니다. 이것은 실제로 객체에서 호출 될 수있는 기능입니다 : 다음과 같이 충돌 감지 개선

내 기능

bool ScreenObject::intersects(ScreenObject & a,ScreenObject & b) { 
    if(inter(a,b)) 
     return true; 
    else 
     return inter(b,a); 
} 

이 간입니다 :

bool inter(ScreenObject & a,ScreenObject & b) { 
    if(a->getsx()>b->getsx()) { 
     if(a->getsx()<b->getSxmax()) { 
      if(a->getsy()>b->getsy())) { 
       if(a->getsy<b->getSymax()) { 
        return true; 
       } 
      } else { 
       if(b->getsy()>a->getsy())) { 
        if(b->getsy<a->getSymax()) { 
         return true; 
        } 
       } 
      } 
     } 
    } 
    return false; 
} 

getsx/getsy 최소 값을 반환 x/y (즉, 객체의 왼쪽 아래 모서리)의 getSxmax/getSymax는 최대 값을 반환합니다. 내 질문은이 코드를 더 나은 방법으로 만드는 것인가하는 것이다.

+0

개체의 모양은 무엇입니까? 예를 들어, 한 오브젝트가 볼록하고 다른 오브젝트가 오목한 경우 오히려 최소 또는 최대를 확인하면 오 탐지 긍 정적을 반환 할 수 있습니다. – kaisernahid

+0

이 경우 대다수의 오브젝트는 직사각형입니다. 그러나 그렇지 않은 오브젝트가있을 것입니다. 오브젝트를 체크하는 방법을 설명 할 수 있습니까? 오브젝트와 일치하는 좌표를 확인해야합니다. 그러나 더 좋은 방법이 있다면 설명해주십시오. – user2673108

+2

이 gamedev.se 주제를 한번보세요 : http://gamedev.stackexchange.com/questions/586/what-is-the-fastest-way-to-work- out-2d-bounding-box-intersection – rkhayrov

답변

1

당신 말이 맞습니다. 이것은 꽤 지저분합니다.

typedef struct range { int min, max; } RANGE; 
typedef struct bb { RANGE x, y; } BOUNDING_BOX; 

키 조작이 disjointness이다 그 대상물 (A)을 결정함으로써 한 차원 더 오버랩 B. 양쪽에 놓여 없어야 있다는 것을 발견한다 : 각 객체의 구형 정도를 추적 할 : 물론 충돌의

bool disjoint(BOUNDING_BOX *a, BOUNDING_BOX *b) { 
    return disjoint(&a->x, &b->x) || disjoint(&a->y, &b->y); 
} 

가 LOGICA입니다 :

bool disjoint(RANGE *a, RANGE *b) { return b->max < a->min || b->min > a->max; } 

이제 우리는 2D에는 중복이없는 찾기 위해이 두 번 사용할 수 있습니다 적어도 직사각형 객체에 대해 분리 된 보완.

다른 모양의 경우에도 직사각형 범위를 사용하여 대부분의 충돌 테스트 비용을 없앨 수 있습니다. 익스텐트가 분리되어 있으면 충돌이없는 것입니다. 만약 연결이 끊어지지 않았다면 일반적인 폴리곤의 충돌에 대해 더 비싼 테스트를 수행해야합니다. 몇 가지 기본 정보 here이 있습니다. 그러나이 주제에 대한 몇 가지 큰 책이 있습니다.

@DanielKO는 C 규칙을 좋아하지 않지만 누가이 질문에 대해 OO보다 더 간결하게 표현하고 있지만,

class Extent { 
    public: 
    bool isDisjointWithRespectTo(Extent &other) { 
     return max < other.min || other.min > max; 
    } 
    private: 
    int min, max; 
} 

class BoundingBox { 
    public: 
    bool isDisjointWithRespectTo(BoundingBox &other) { 
     return x.isDisjointWithRespectTo(other.x) || y.isDisjointWithRespectTo(other.y); 
    } 
    bool intersectsWith(BoundingBox &other) { return !isDisjointWithRespectTo(other); } 
    private: 
    Extent x, y; 
} 

생성자가 minmax가 제대로 두 버전에 정렬되어 있는지 확인해야합니다 또한 생성자와 다른 상용구를 생략.

+1

신의 사랑을 위해서 다른 모든 사람들과 마찬가지로 적절한 교차 테스트를 통해 축 정렬 바운딩 박스 클래스를 작성하십시오. OOP는 간단한 개념을 간단한 읽을 수있는 코드로 만들기 위해 정확하게 존재합니다. – DanielKO

+0

@ 대니얼 코 (DanielKO) 이것은 당신에게 당신의 신을 불러 일으킬 필요성을 느낀 그러한 스트레스를 불러 일으켰습니다. OP는 테스트를 정렬하는 방법을 묻는 것이므로, 완전한 클래스를 작성하는 것이 아니라 분리 테스트를 보여주는 코드 조각을 제공하는 것이 나의 의도였습니다. – Gene

+0

OOP에 관한 질문에는 C++이라는 태그가 붙어 있으므로 언어로 제공되는 툴을 사용하는 것이 적절합니다. 경계 상자는 상당히 직관적 인 개념입니다 (C 버전에서 'Extent'라고 부르지 말고 간격을 의미하는 데 다시 사용하십시오. 이름이 중요 함), 명시 적으로 표현하는 것이 좋습니다. 'ScreenObject'는 간격의 쌍이 아니라 경계 상자를 가질 것입니다 (이는 합당한 구현 세부 사항입니다). – DanielKO