QuadTree: chỉ lưu trữ điểm, hoặc khu vực?


9

Tôi đang phát triển một góc phần tư để theo dõi các vật thể chuyển động để phát hiện va chạm. Mỗi đối tượng có hình dạng giới hạn, giả sử chúng là tất cả các vòng tròn. (Đây là một trò chơi 2D từ trên xuống)

Tôi không chắc chỉ lưu trữ vị trí của từng đối tượng hay toàn bộ hình dạng giới hạn.

Nếu làm việc với các điểm, việc chèn và phân chia là dễ dàng, bởi vì các đối tượng sẽ không bao giờ trải rộng trên nhiều nút. Mặt khác, một truy vấn gần cho một đối tượng có thể bỏ lỡ các va chạm, vì nó sẽ không tính đến kích thước của các đối tượng. Làm thế nào để tính toán vùng truy vấn khi bạn chỉ có điểm?

Va chạm giữa các đối tượng từ các nút lân cận

Nếu làm việc với các vùng, làm thế nào để xử lý một đối tượng kéo dài nhiều nút? Có nên chèn nó vào nút cha gần nhất chứa hoàn toàn nó, ngay cả khi điều này vượt quá khả năng của nút không?

Nút nào nên chứa đối tượng màu đỏ?

Cảm ơn.

Câu trả lời:


4

Nếu lưu trữ các đối tượng mở rộng (các vùng) trong một góc phần tư, đối tượng nên được tham chiếu từ tất cả các nút lá mà nó chạm vào. Tôi sẽ không cố gắng tìm ra tổ tiên ít phổ biến nhất và lưu trữ nó ở đó, bởi vì khi đó, một vật thể nhỏ vượt qua ranh giới cấp cao sẽ kết thúc ở một nút rất cao và phải được kiểm tra chống lại mọi thứ khác trong đó , nút cấp cao khi bạn thực hiện các truy vấn va chạm và tương tự.

Tuy nhiên, bạn cũng phải cẩn thận vì các vật thể lớn cuối cùng có thể được tham chiếu từ nhiều nút, khiến chúng đắt tiền khi cập nhật và khiến chúng bị kiểm tra lại nhiều lần vì va chạm, v.v. Tùy thuộc vào trường hợp sử dụng của bạn có thể đáng để sử dụng một số loại heuristic để lưu trữ các vật thể lớn ở mức cao hơn trong cây, nhưng điều này sẽ làm phức tạp các thuật toán, vì vậy tôi có thể không bận tâm trừ khi bạn xác định rằng đó thực sự là một vấn đề hiệu năng trong trường hợp cụ thể của bạn.

Tương tự, để truy vấn một vùng, truy vấn sẽ xem xét tất cả các nút lá mà vùng truy vấn chạm vào.

Về cơ bản, chúng sử dụng cùng một thuật toán, đó là bắt đầu với một vùng và đẩy nó xuống qua cây để tìm các nút lá mà nó chạm vào. Đó là một giao dịch sâu đầu tiên, nhưng tại mỗi nút, bạn có thể cắt tỉa bất kỳ đứa trẻ nào không chạm vào khu vực. Bạn sẽ cần duy trì một ngăn xếp để theo dõi vị trí của bạn trong giao dịch.


Cảm ơn, điều này có ý nghĩa. Chắc chắn, việc xử lý các đối tượng nút chéo sẽ chậm hơn các đối tượng hoàn toàn bên trong một nút, nhưng tôi không thể thấy bất kỳ cách nào xung quanh đó. Tôi có thể tăng dung lượng nút để giữ phân mảnh xuống, nhưng điều này sẽ tăng số lượng đối tượng có trong phát hiện va chạm. Tôi sẽ chơi xung quanh với điều đó để tìm sự cân bằng tốt.
alekop

4

Bạn phải lưu trữ nó trong nút nhỏ nhất chứa hoàn toàn nó - ngay cả khi điều này vượt quá khả năng (sử dụng một thùng chứa có thể thay đổi kích thước).


2

Tôi sẽ thêm nhận xét này dưới dạng nhận xét để trả lời câu trả lời của @Nathan Reed, ngoại trừ nó quá lớn để trở thành một nhận xét và có lẽ trong mọi trường hợp xứng đáng là một câu trả lời riêng biệt.

Chúng tôi đã làm chính xác những gì được đề xuất trong câu trả lời của anh ấy, và trên thực tế có bình luận trong nguồn liên kết đến trang này. Đối với hầu hết các phần, nó đã hoạt động rất tốt, ngoại trừ cứ hai hoặc ba tháng một lần, chúng tôi lại mất một máy chủ ngẫu nhiên không phản hồi do thời gian truy vấn tìm kiếm quá lớn.

Nguyên nhân cốt lõi của vấn đề khiến tôi chú ý trong khi kiểm tra hiệu năng để thử và tìm hiểu nguyên nhân gây ra sự cố này. Nó chỉ có thể là một mối quan tâm nếu bạn cho phép các đối tượng chồng chéo. Trong trò chơi của chúng tôi, chúng tôi làm, và trong trường hợp xấu nhất, đôi khi nó dẫn đến hiệu suất tăng đột biến.

Chúng tôi có một trường hợp cạnh trong đó khoảng 100 đối tượng, tất cả đều có các đĩa giới hạn, được nhóm lại rất gần nhau. Điều đó dẫn đến vấn đề tăng đột biến rất sâu trong cây, bởi vì chúng ta đã đến điểm mà các vật thể lớn hơn diện tích được bao phủ bởi các nút tứ giác, vì vậy mỗi đối tượng mới xuất hiện trong nhiều nút, dẫn đến sự phân chia lớn của cây, do đó, ném tuyết vấn đề ngoài tầm kiểm soát.

Điểm nổi bật của việc này là nếu bạn cho phép các vùng đối tượng chồng lên nhau, hãy theo dõi chặt chẽ mọi thứ nếu bạn có được các cụm đối tượng chặt chẽ, để đảm bảo cây của bạn không bị quá sâu.

Giải pháp tôi hiện đang nghiên cứu là lưu trữ các đối tượng dưới dạng các điểm và sau đó khi thực hiện tìm kiếm, hãy tăng giới hạn của hình chữ nhật tìm kiếm theo bán kính tối đa được lưu trữ trong cây. Điều đó sẽ phù hợp với chúng tôi, vì cây là tìm kiếm vượt qua đầu tiên, sau đó chúng tôi thực hiện kiểm tra phạm vi dựa trên vòng tròn thực sự, cùng với một vài kiểm tra tiêu chí khác, do đó, các cảnh báo sai sẽ được lọc ra.

Số dặm thực tế của bạn có thể thay đổi.

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.