Thuật toán để xem hai voxels có liên kết với nhau không


11

Tôi đang tìm kiếm một thuật toán tốt cho vấn đề sau: Đưa ra một lưới các voxels 3D (có thể trống hoặc đầy), nếu tôi chọn hai voxels không liền kề, tôi muốn biết liệu chúng có được kết nối với nhau không các voxels khác.

Ví dụ: (để minh họa tình huống trong 2D), trong đó # là một hình vuông đầy:

  1 2 3
a # # #
b # #
c # # #

Nếu tôi chọn a3 và c3, tôi muốn xác định càng nhanh càng tốt nếu chúng được kết nối; nếu có một đường dẫn giữa a3 và c3 qua các pixel được lấp đầy. (Tất nhiên, tình huống thực sự nằm trong lưới voxel 3D.)

Tôi đã xem xét các thuật toán lấp đầy và thuật toán tìm đường, nhưng tôi không chắc nên chọn thuật toán nào. Cả hai đều làm công việc không cần thiết: Lũ lụt cố gắng lấp đầy tất cả các voxels, nhưng điều này là không cần thiết. Các thuật toán tìm đường thường liên quan đến việc tìm đường đi ngắn nhất, điều này cũng không cần thiết. Tôi chỉ cần biết nếu có một con đường.

Tôi nên sử dụng thuật toán nào?

Chỉnh sửa: dựa trên các nhận xét, tôi nghĩ nên thêm vào như sau: nội dung của các voxels không được biết trước và ngoài ra, thuật toán là cần thiết để phát hiện nếu loại bỏ (làm trống) một voxel sẽ khiến nhóm voxel bị phá vỡ thành hai hoặc nhiều nhóm nhỏ hơn.


Trong ví dụ của bạn, một đường dẫn hợp lệ từ a3 đến c3 sẽ như sau : c3->c2->b2->a2->a3?

đúng vậy
Bram Vaessen

Câu trả lời:


12

A * sẽ hoạt động tốt. Tìm đường dẫn là những gì bạn muốn, tìm đường đi ngắn nhất cũng nhanh như vậy (hoặc nhanh hơn) so với tìm bất kỳ đường dẫn nào cả. Trong tình huống này, A * có thể là điểm phù hợp nhất khi bạn có điểm bắt đầu và điểm kết thúc. điều này có nghĩa là bạn có thêm heuristic để tăng tốc tìm kiếm.

Với A * thường là con đường đầu tiên bạn tìm thấy là con đường ngắn nhất, vì vậy nó không phải làm thêm sau khi đã tìm thấy đường dẫn.

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

Đối với một số tối ưu hóa, kiểm tra câu trả lời của tôi ở đây .


Trông giống như nó thực sự bắn về phía trước cho đến khi nó đâm vào bức tường đó sau đó là loại creep
GameDev-er

1
@ GameDev-er Vâng, đó là vì heuristic. Nếu không có chướng ngại vật thì đó sẽ là một cuộc tìm kiếm rất nhanh, gần như một đường thẳng.
MichaelHouse

Với việc sắp xếp tốt hơn các nút, điều này sẽ mở rộng đường dẫn gần nhất đến nút cuối cùng trước tiên. Nếu bạn có cấu trúc dữ liệu nhanh để sắp xếp các nút, hãy sắp xếp chúng theo khoảng cách đến mục tiêu cho đường dẫn trực tiếp nhất.
MichaelHouse

9

Nếu bạn chuẩn bị thực hiện một số xử lý trước và ăn chi phí lưu trữ, thì việc phân vùng các voxels thành các nhóm được kết nối vào thời điểm xây dựng sẽ đưa ra một câu trả lời rõ ràng cho "có đường dẫn nào không". Có một con đường giữa hai voxels nếu chúng nằm trong cùng một nhóm. Vấn đề với điều đó rõ ràng là bạn phải lưu trữ thông tin nhóm ở đâu đó và điều đó phụ thuộc vào cách bố trí dữ liệu của bạn. Nếu bạn đang lưu trữ một danh sách đơn giản, bạn có thể chia nó thành nhiều danh sách, một danh sách cho mỗi nhóm được kết nối không gian. Nếu bạn đang tổ chức ở một số loại BVH, thì có lẽ bạn có thể nhận được một số hiệu quả tương đối tốt nếu bạn có thể nói "tất cả các voxels trong nút này và bên dưới thuộc về nhóm X".

Ngoài ra, bạn có thể thực hiện một số cuộc chia tay không gian và lưu trữ một số voxels 'hub' nhỏ hơn cho mỗi nhóm được kết nối. Sau đó, bạn có thể tìm đường dẫn từ các voxel nguồn và đích của mình đến voxel trung tâm gần nhất của chúng, nên rút ngắn hơn / rẻ hơn để tính toán đường dẫn. Nếu bạn có thể tìm thấy đường dẫn từ voxel đến hub voxel, thì voxel là một phần của nhóm voxel của hub. Với lựa chọn thông minh của các voxels trung tâm đó, bạn có thể giảm thiểu số lượng đường truyền. Ví dụ, một hình cầu có thể chỉ có một voxel trung tâm ở trung tâm của nó, nhưng một nhóm mỏng dài có thể có một voxel trung tâm mỗi voxel X dọc theo chiều dài của nó. Nếu các voxels nguồn và đích của bạn ở cuối chiều dài, chúng chỉ phải đi nhiều nhất là các voxels X để tìm một trung tâm, và mặc dù có thể có một số lượng lớn các voxels giữa đầu và cuối chiều dài,

Tất cả phụ thuộc vào mức độ bệnh lý của các nhóm voxel của bạn: nếu bạn mong đợi một số lượng lớn các nhóm bị ngắt kết nối nhỏ, việc tăng chi phí lưu trữ sẽ vượt trội so với hiệu suất của việc tìm đường. Nếu bạn mong đợi tương đối ít nhóm được kết nối nhưng có cấu trúc liên kết kỳ lạ, thì việc tìm đường ngây thơ có thể rất tốn kém và chi phí lưu trữ và tìm đường tối thiểu là một lựa chọn rẻ hơn nhiều.


1
Đây là câu trả lời đúng, nhưng để thực hiện nó một cách hiệu quả, nó không nên được lưu trữ dưới dạng một danh sách. Thêm một con trỏ vào mỗi voxel trỏ đến "voxel đại diện" của nó, mà bạn đặt bằng thuật toán union-find. Đây là chi phí lưu trữ không đổi trên mỗi voxel và về cơ bản tuyến tính theo số cạnh cho chi phí tính toán.
Neil G

Ý tưởng thú vị, nhưng có hai điều có thể làm phức tạp tình hình. Đầu tiên là nội dung của lưới voxel không được biết trước, vì vậy để tạo ra các voxels trung tâm, tôi cũng cần một thuật toán có thể xác định các voxels nào nên là hub.
Bram Vaessen

1
Vấn đề thứ hai là thuật toán là cần thiết ngay sau khi loại bỏ một voxel, để xác định xem nhóm đó có phải là một phần được chia thành các nhóm nhỏ hơn do loại bỏ voxel đó hay không.
Bram Vaessen

@BramVaessen Nếu bạn đang tìm kiếm tất cả các mối quan hệ kết nối theo cặp - và đặc biệt, cho dù các nhóm 'chia tay' - thì đó là một vấn đề hơi khác so với khả năng tiếp cận (mặc dù khả năng tiếp cận là cách dễ dàng nhất); Tôi khuyến khích thêm chi tiết cụ thể về những gì bạn đang theo dõi cho câu hỏi ban đầu, vì nó có thể cho phép câu trả lời tốt hơn cho "vấn đề đằng sau câu hỏi".
Steven Stadnicki

Để giữ cho nó sạch sẽ, tôi đã hỏi vấn đề ban đầu của mình trong một câu hỏi khác ở đây gamedev.stackexchange.com/questions/50953/ Kẻ
Bram Vaessen

4

Tôi không quen thuộc lắm với voxels, nhưng tôi sẽ tưởng tượng rằng bạn có thể có hiệu suất khá tốt từ việc sử dụng thuật toán tìm kiếm đầu tiên tốt nhất như A *. Vấn đề với việc sử dụng A * trong trường hợp này là phương pháp heuristic thường sử dụng được thiết kế để ưu tiên tìm đường đi ngắn nhất và không chỉ là 'bất kỳ con đường nào' càng nhanh càng tốt.

Bạn có thể có một số may mắn khi sử dụng một heuristic thay thế mở rộng ít nút hơn như

f (p) = g (p) + w (p) * h (p)

trong đó w> = 1. bạn giảm giá trị của 'w' bạn càng tiến gần đến mục tiêu, do đó ưu tiên cao hơn cho chi phí đường dẫn 'g' bạn càng đến gần với voxel mà bạn đang tìm kiếm.

Tôi hi vọng cái này giúp được!

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.