Các lựa chọn thay thế phân vùng không gian 2D cho băm không gian và tứ giác


11

Tôi đã cố gắng thực hiện một thuật toán phân vùng không gian trong trò chơi của mình, nhưng cả băm không gian và tứ giác không phải là thứ tôi đang tìm kiếm.

Kích thước cấp độ của tôi không có giới hạn (chỉ giới hạn Int32). Tôi cần một thuật toán phân vùng không gian không cần "Độ rộng cấp độ" và "Độ cao cấp độ".

Tôi có nhiều vật thể chuyển động. Tôi cần thuật toán đủ nhanh để hỗ trợ hơn 500 đối tượng.

Bất kỳ thay thế?

Câu trả lời:


13

Cây động

Box2D là một công cụ được tối ưu hóa tốt được thiết kế bởi một lập trình viên vật lý / trò chơikinh nghiệm . Ban đầu Box2D đã sử dụng lưới băm yêu cầu chiều cao và chiều rộng cố định.

Khi Erin nâng cấp lên một thuật toán broadphase tốt hơn, anh ấy đã đi với btDbvt của Nathanael Presson. Đây là broadphase được sử dụng bởi Bullet Vật lý. Erin đã sửa đổi và tối ưu hóa thuật toán cho 2d.

Bạn có thể đọc phần ghi đè mức siêu cao trong hướng dẫn sử dụng Box2D (§4.11 hoặc tìm kiếm Cây động).

Đây là một ngoại lệ từ tài liệu mã (rất tốt vì nó không phải là một phần của API công khai).

Một cây AABB động rộng, lấy cảm hứng từ btDbvt của Nathanael Presson. Cây động sắp xếp dữ liệu trong cây nhị phân để tăng tốc các truy vấn như truy vấn âm lượng và phôi tia. Lá là proxy với AABB. Trong cây, chúng tôi mở rộng AABB proxy bằng b2_fatAABBFactor để AABB proxy lớn hơn đối tượng khách. Điều này cho phép đối tượng khách di chuyển với số lượng nhỏ mà không kích hoạt cập nhật cây.

Các nút được gộp chung và có thể định vị lại, vì vậy chúng tôi sử dụng các chỉ mục nút thay vì con trỏ.

Sự hiểu biết của tôi về thuật toán của Dynamic Tree là thế này. Cây động là sự giao thoa giữa cây nhị phân avl cổ điển và cây tứ giác. Hiệu ứng kết thúc là một hình tứ giác chỉ chia đôi một nút và đường phân chia không cố định (hai nửa không có kích thước bằng nhau như một cây tứ giác). AVL xuất hiện bởi vì quadree với các phần tách động có thể suy giảm về cơ bản là một danh sách (O (n) tốc độ tra cứu). AVL được sử dụng để cân bằng lại các cấp độ để đảm bảo tốc độ tra cứu O lg (N).

Tốt nhất trong tất cả các mã là MIT, vì vậy hãy thoải mái sao chép / dẫn xuất / không biết xấu hổ-ăn cắp / v.v.


Trông ... phức tạp! Tôi sẽ xem xét nó, mặc dù. Ai đó đề nghị tôi sử dụng kỹ thuật "quét và cắt tỉa" hoặc "sắp xếp và quét" nhưng tôi không thể tìm thấy bất cứ điều gì về việc triển khai C # hoặc .NET. Tôi đã tìm thấy một ví dụ c ++ nhưng nó khó hiểu và nó không hoạt động (dù sao tôi cũng đã cố gắng thực hiện nó). Bạn có nghĩ rằng SAP sẽ dễ thực hiện hơn không? Có triển khai .NET không?
Vittorio Romeo

8

Điều này rất gần với một câu hỏi tương tự được hỏi ở đây trên Gamedev, nhưng vì bạn quan tâm đến hiệu suất và không lưu trữ tệp, có lẽ câu trả lời của tôi sẽ có ích hơn cho bạn. Tôi sẽ bao gồm phần lớn của nó ở đây cho đầy đủ, nhưng câu trả lời ban đầu cung cấp thêm một chút chiều sâu nếu bạn muốn xem xét nó.

Tôi gặp phải một vấn đề tương tự và quyết định tạo cấu trúc của riêng mình để xử lý dữ liệu. Nó dựa một cách lỏng lẻo vào một góc phần tư, nhưng có khả năng mở rộng vô hạn (ít nhất là lớn bằng Int) theo mọi hướng. Nó được thiết kế để xử lý dữ liệu dựa trên lưới được mở rộng từ một điểm trung tâm, giống như Minecraft hiện nay. Đó là không gian hiệu quả trong bộ nhớ, và rất nhanh.

Mã của tôi có thể được tìm thấy ở đây . Mã này đã hoàn tất, được kiểm tra (đơn vị và kiểm tra tải) và khá tối ưu. Tuy nhiên, các hoạt động bên trong chưa được ghi chép quá rõ, nhưng tất cả các phương pháp công khai đều có thể sử dụng được. Nếu bất cứ ai quyết định dùng thử, hãy liên hệ với tôi với câu hỏi hoặc nhận xét.


1

Khi làm việc với một số lượng tương đối nhỏ (<vài nghìn) đối tượng nhỏ (hầu hết các đối tượng không đủ lớn để có khả năng va chạm với nhiều đối tượng khác) Tôi thấy rằng một danh sách đơn giản các hộp giới hạn được sắp xếp theo trục x (AABBs) hoạt động khá tốt Tôi chỉ đặt các đối tượng vào một danh sách, sau đó mỗi khung sau khi di chuyển các đối tượng, tôi sắp xếp nhanh danh sách theo giá trị x, sau đó thực hiện một lần qua danh sách kiểm tra độ gần của AABB. Đối với mỗi đối tượng, tôi kiểm tra nó với các đối tượng phía trước nó trong danh sách cho đến khi tôi đến cuối danh sách hoặc một đối tượng nằm ngoài phạm vi x; nghĩa là, giá trị x của cạnh trái là> x giá trị của cạnh phải của đối tượng được kiểm tra. Về cơ bản, nó tự động phân chia không gian thành các lát có kích thước đôi khi chồng chéo, AABB-x. Nó '


0

Có lẽ thuật toán r-tree là những gì bạn đang tìm kiếm.

Tôi làm việc thực sự tốt cho hình học tĩnh, nhưng bạn cũng có thể sử dụng nó để di chuyển các đối tượng bằng cách loại bỏ và thêm các đối tượng tại các vị trí mới của chúng.


Tôi đã thử triển khai C # và hiệu suất quá tệ khi "xóa và thêm đối tượng ở vị trí mới".
Vittorio Romeo

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.