Phát hiện va chạm OBB vs OBB


20

Giả sử bạn có hai Đối tượng Hộp Bounding, mỗi đối tượng lưu trữ các đỉnh hiện tại của hộp trong một vectơ với tất cả các đỉnh của đối tượng được xoay và dịch tương ứng với một trục chung.

Đây là một hình ảnh để minh họa vấn đề của tôi:

Làm thế nào tôi có thể tìm ra nếu hai OBB chồng chéo bất kỳ liên kết nào để giúp giải thích giải pháp cho vấn đề sẽ được hoan nghênh. Không có gì quá phức tạp xin vui lòng ...

Câu trả lời:


16

Một OBB là một thân tàu lồi. Một thân tàu lồi là một hình dạng 3D không có "vết nứt" trên bề mặt của nó. Mỗi "vết sưng" (đỉnh) trên thân lồi nhô ra ngoài , không bao giờ hướng vào trong. Nếu bạn cắt một mặt phẳng qua thân tàu lồi, bạn sẽ nhận được (chỉ một) đa giác lồi. Nếu bạn ở trong thân tàu lồi và bắn tia laser hướng ra ngoài, bạn sẽ chỉ đấm qua bề mặt thân tàu một lần (không bao giờ hai lần).

Phép thử Định lý trục tách có thể được sử dụng để phát hiện sự va chạm của vỏ lồi. Bài kiểm tra SAT rất đơn giản. Nó hoạt động trong 2D và 3D. Mặc dù các hình ảnh dưới đây sẽ ở dạng 2D, nhưng chúng có thể dễ dàng được áp dụng cho 3D.

Khái niệm

Đây là khái niệm chính bạn đang sử dụng với SAT:

  • Hai hình chỉ giao nhau nếu chúng trùng nhau khi "chiếu" lên mọi trục bình thường của cả hai hình .

"Phép chiếu" của hình trên vectơ 1D trông như thế này (cái mà tôi gọi là "nghiền")

Một hình với các câu màu đỏ và một trục

nhập mô tả hình ảnh ở đây

"Chiếu hình tới trục" có nghĩa là thả vuông góc từ mỗi điểm trên hình chỉ để hạ cánh trên trục. Bạn có thể nghĩ về điều này như "nghiền nát" các điểm bằng một bàn tay tập hợp mọi thứ và vuông góc nghiền nó xuống trục.

nhập mô tả hình ảnh ở đây

Những gì bạn còn lại với: Điểm trên một trục

nhập mô tả hình ảnh ở đây

SAT nói:

Để 2 thân tàu lồi giao nhau, chúng phải chồng lên nhau trên mọi trục (trong đó mọi hình bình thường trên một trong hai hình đều được tính là một trục chúng ta phải kiểm tra).

Lấy 2 hình dạng sau:

nhập mô tả hình ảnh ở đây

Bạn thấy chúng không giao nhau, vì vậy hãy thử một vài trục để hiển thị là sự trùng lặp không xảy ra.

Cố gắng bình thường hàng đầu của hình ngũ giác:

nhập mô tả hình ảnh ở đây

Đây là những phạm vi. Họ làm chồng chéo lên nhau.

nhập mô tả hình ảnh ở đây

Hãy thử bên trái của hình chữ nhật. Bây giờ chúng không trùng nhau trong trục này, do đó KHÔNG CÓ TƯƠNG TÁC.

nhập mô tả hình ảnh ở đây

Thuật toán:

Đối với mỗi khuôn mặt bình thường trên cả hai hình dạng:

  • Tìm phạm vi tối thiểu và tối đa (giá trị lớn nhất và nhỏ nhất) của hình chiếu của tất cả các điểm góc đỉnh của cả hai hình trên trục đó
  • Nếu chúng không trùng nhau, không có giao lộ .

Và đó thực sự là nó. Mã để làm cho SAT hoạt động rất ngắn và đơn giản.

Dưới đây là một số mã trình bày cách thực hiện phép chiếu trục SAT:

void SATtest( const Vector3f& axis, const vector<Vector3f>& ptSet, float& minAlong, float& maxAlong )
{
  minAlong=HUGE, maxAlong=-HUGE;
  for( int i = 0 ; i < ptSet.size() ; i++ )
  {
    // just dot it to get the min/max along this axis.
    float dotVal = ptSet[i].dot( axis ) ;
    if( dotVal < minAlong )  minAlong=dotVal;
    if( dotVal > maxAlong )  maxAlong=dotVal;
  }
}

Mã gọi:

// Shape1 and Shape2 must be CONVEX HULLS
bool intersects( Shape shape1, Shape shape2 )
{
  // Get the normals for one of the shapes,
  for( int i = 0 ; i < shape1.normals.size() ; i++ )
  {
    float shape1Min, shape1Max, shape2Min, shape2Max ;
    SATtest( normals[i], shape1.corners, shape1Min, shape1Max ) ;
    SATtest( normals[i], shape2.corners, shape2Min, shape2Max ) ;
    if( !overlaps( shape1Min, shape1Max, shape2Min, shape2Max ) )
    {
      return 0 ; // NO INTERSECTION
    }

    // otherwise, go on with the next test
  }

  // TEST SHAPE2.normals as well

  // if overlap occurred in ALL AXES, then they do intersect
  return 1 ;
}

bool overlaps( float min1, float max1, float min2, float max2 )
{
  return isBetweenOrdered( min2, min1, max1 ) || isBetweenOrdered( min1, min2, max2 ) ;
}

inline bool isBetweenOrdered( float val, float lowerBound, float upperBound ) {
  return lowerBound <= val && val <= upperBound ;
}

Hullinator thực hiện bài kiểm tra SAT cho thân tàu lồi
bobobobo

giải thích tuyệt vời! cảm ơn. Tôi nghĩ rằng bạn có thể có một lỗi đánh máy trong dòng: "để cho phép thử một vài trục đến chương trình là sự chồng chéo không xảy ra.", Bởi vì sau đó bạn tiến hành cho ví dụ nơi họ làm chồng chéo. cảm ơn lần nữa

Bạn không cần phải làm các bài kiểm tra cho tất cả các sản phẩm chéo của quy tắc? Bài viết này geometrictools.com/Documentation/DAVECollisionDetection.pdf nói như vậy.
iNFINITEi

Điều đáng nói là phương pháp SAT cụ thể này chỉ hoạt động ở dạng 2D. Trong 3D, bạn cần nhận được nhiều hơn chỉ là quy tắc của mỗi khuôn mặt. Tuy nhiên, khi bạn có các quy tắc đúng, phần còn lại của quá trình (dự án, so sánh) là hoàn toàn giống nhau.
Vụ kiện của Quỹ Monica

Thực sự rất khó để nói từ hình ảnh 2D của bạn những mũi tên đang đi theo hướng nào.
WDUK

7

Bạn chắc chắn nên tra cứu Định lý trục tách . Nó dành cho các đối tượng lồi. Có một quy tắc: "Nếu hai vật lồi không giao nhau, thì có một mặt phẳng mà hình chiếu của hai vật thể này sẽ không giao nhau".

Bạn có thể tìm thấy một số ví dụ trên wiki . Nhưng nó phức tạp hơn một chút so với trường hợp của bạn.

Một cái gì đó phù hợp hơn cho vấn đề của bạn có thể được tìm thấy ở đây (hai chiếc xe va chạm).


1

Nhiều bài viết SAT .

Bài viết cuối cùng trên trang web này đi kèm với mã hoàn chỉnh, tôi nghĩ đó là trong FLASH, tôi không biết, nhưng tôi đã có chính xác 0 vấn đề khi chuyển đổi nó thành C ++ khi tôi phải sử dụng SAT lần đầu tiên, không nên khó làm tương tự cho các ngôn ngữ khác Điều duy nhất bạn sẽ phải thêm là lưu trữ vectơ dịch chuyển trên mỗi phép tính (nếu đó là phần nhỏ nhất, bạn sẽ hiểu điều này khi bạn tìm hiểu về SAT), mã trong hướng dẫn này không làm điều đó, vì vậy bạn kết thúc với vector tính toán cuối cùng.

http://rocketmandevelopment.com/tag/separation-axis-theorem/

Tốt, hướng dẫn N-Game cũ. Lý thuyết SAT tốt nhất trên web.

http://www.metanetsoftware.com/technique/tutorialA.html


Thật khó chịu khi không ai đăng toàn bộ nguồn làm việc với tất cả các lớp bắt buộc. Tôi đã chuyển mã của anh ấy thành một bản demo của riêng tôi nhưng nó không hoạt động. :( Đây là dự án của tôi cho đến nay nếu có ai có thể giúp tôi gỡ lỗi thì đó là điều tuyệt vời. Link
Joshua Barnett

ý bạn là nó không hoạt động chú ý đến cách bạn lưu trữ các đỉnh của bạn, trong hình ảnh bạn có chúng trong hệ tọa độ cartesian, trong hướng dẫn, anh ta lưu trữ các đỉnh như các vectơ so với tâm (tất cả những gì bạn phải làm là trừ đi tâm từ các đỉnh của chính bạn hoặc xóa các dòng nơi anh ta tự sửa đổi các đỉnh của mình), các chức năng như sản phẩm chấm bạn có thể tự tạo, bạn không cần hướng dẫn cho những người đó, phần còn lại nên được chuyển thẳng, đó không phải là tài liệu sao chép, tìm hiểu SAT trước khi thử thực hiện
dreta

Đây là cách tôi đã triển khai nó: SAT.as , Shape2D.as , Ý của bạn là gì? Tâm của đa giác như (x, y)?
Joshua Barnett

Hiện tại tôi có một hàm getOBB () trả về các đỉnh như chi tiết trong ảnh gốc của tôi. Điều này được tính từ một Vector <b2Vec2> chứa các đỉnh của hình dạng, biến góc và biến vị trí.
Joshua Barnett

vâng, trung tâm, cách mà anh chàng này tạo ra các đa giác của mình bằng cách đưa ra các điểm bù từ trung tâm, idk AS3, nhưng từ những gì tôi thấy bạn chiếu các đỉnh của mình như khi chúng, khi tính toán sản phẩm chấm cố gắng trừ đi tâm từ các đỉnh (phép trừ vector ), bên cạnh điều này bạn không kiểm tra vectơ tách nào là nhỏ nhất, bạn chỉ lưu trữ cái cuối cùng được tính
dreta
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.