Phân chia không gian trục căn chỉnh: Chia không gian thành các hình chữ nhật ngẫu nhiên?


11

Tôi cần một phương pháp để phân chia không gian 3d thành các hình dạng hộp được căn chỉnh theo trục ngẫu nhiên. Hiện tại tôi đang phân chia không gian 2d cho mục đích thử nghiệm. Cách tiếp cận ngay lập tức nhất mà tôi đã đưa ra là xác định một hình chữ nhật có kích thước (1, 1) và sau đó phân chia đệ quy tất cả các hình chữ nhật hiện có thành hai hình chữ nhật không đều xen kẽ giữa trục X và Y.

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

Vấn đề ở đây là rõ ràng. Cách tiếp cận này dẫn đến các đường kéo dài (đánh dấu màu đỏ)

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

Những gì tôi muốn là một cái gì đó hữu cơ hơn (tôi bao gồm một ví dụ)

Xem, không có đường thẳng dài từ trên xuống dưới hoặc trái sang phải.

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

Hạn chế duy nhất là tôi có thể muốn giới hạn kích thước tối thiểu của hình chữ nhật mà không ảnh hưởng đến độ chi tiết của kích thước. tức là nếu trực tràng nhỏ nhất là 1 cm vuông so với giây nhỏ nhất thì không nên là 2 đơn vị vuông.

Vì vậy, lý tưởng là thuật toán phải đáp ứng cả ba ràng buộc sau:

  1. Hình chữ nhật không nhỏ vô cùng.
  2. Kích thước Rect không nhân bội của kích thước trực tràng nhỏ nhất. tức là nếu trực tràng nhỏ nhất là 3 đơn vị vuông hơn các đơn vị lớn hơn không bị hạn chế là 6, 9, 12 và tiếp theo là các đơn vị vuông và thay vào đó có thể là 3,2 hoặc 4,7 cho vấn đề đó).
  3. Thuật toán chạy trong thời gian đa thức (cần tính toán nhanh).

Câu trả lời:


12

Cách tiếp cận bạn phác thảo rất đơn giản và hữu ích, nhưng phải chịu đựng những tạo tác khủng khiếp như được hiển thị. Tránh nó Bạn cần một thuật toán tăng trưởng song song; đối với mô hình một luồng, cách tiếp cận vòng tròn như sau:

  1. Đặt ngẫu nhiên các điểm khác nhau trong không gian bản đồ của bạn. Bình thường hóa phân phối của chúng (tránh phân cụm xấu xí) bằng phân phối Gaussian hoặc bằng cách áp dụng thuật toán thư giãn lặp để di chuyển các điểm được đặt ngẫu nhiên cách xa nhau, theo thư giãn Lloyd cho Biểu đồ Voronoi . Những điểm này đại diện cho trọng tâm của phòng tương lai của bạn.
  2. (Song song / Lặp lại vòng tròn cho tất cả các phòng) Từ mỗi điểm, phát triển 4 đỉnh ra ngoài (một phòng hình chữ nhật), di chuyển từ điểm trung tâm trên mỗi lần lặp toàn cầu (bạn có thể phát triển các phòng khác nhau ở các tốc độ khác nhau ở mỗi trục thay vì cùng một tất cả, và xem làm thế nào điều này bật ra - có thể cho một kết quả hữu cơ / đa dạng hơn). Tại một số điểm, một số hình chữ nhật của bạn sẽ bắt đầu áp vào nhau. Tại thời điểm đó, hạn chế sự tăng trưởng trong trục đó, đảm bảo các cạnh liền kề của hai phòng được chạm chính xác và di chuyển.
  3. Lặp lại bước 2, tăng dần mỗi phòng, cho đến khi tất cả sự tăng trưởng bị hạn chế bởi các phòng liền kề hoặc giới hạn của bản đồ.
  4. Điều này vẫn sẽ để lại một số khoảng trống. Vấn đề bây giờ trở thành một trong việc định vị và làm cho các phòng ra khỏi không gian không bị chiếm đóng. Trong thực tế, nếu không gian bên dưới của bạn là một lưới (được lập chỉ mục số nguyên) (và mọi lần lặp tăng trưởng đều khớp với lưới đó), thì điều này sẽ dễ xử lý hơn nhiều, vì bạn có thể duy trì danh sách các ô lưới bị chiếm dụng và không sử dụng: Khi bạn ' đã đặt và phát triển tất cả các phòng của bạn, tìm kiếm trong danh sách không có người cho các không gian riêng biệt bao gồm các nhóm các ô liền kề. Vì nhiều không gian không được sử dụng sẽ có hình dạng không phải hình chữ nhật, bạn sẽ cần chọn một ô ngẫu nhiên từ bên trong không gian không phải hình chữ nhật đó và phát triển nó thành kích thước tối đa giống như bạn đã làm với các phòng ở bước 2. Lặp lại trong không nói không gian hình chữ nhật, cho đến khi nó được lấp đầy hoàn toàn.
  5. Lặp lại bước 4 cho đến khi bản đồ của bạn được chiếm 100%.

Đây là lời khuyên tốt. Nhược điểm là nó có thể không làm gì để bảo vệ tôi khỏi những giáo phái nhỏ bé vô cùng. Tôi cần một số cách để hạn chế mức độ nhỏ và lớn như thế nào. Hiện tại tôi đang trong quá trình làm việc theo phương pháp khác. Tôi sẽ so sánh kết quả và cập nhật.
AturSams

@ArthurWulfWhite Sau đó, câu hỏi của bạn chưa được chỉ định và nên được cập nhật. Kích thước phòng tối thiểu của bạn được xác định bởi độ phân giải ô bản đồ của bạn; do đó, nếu bạn làm cho hạt thô đủ để chứa kích thước phòng tối thiểu, sau đó bạn có thể điều chỉnh trục trên cơ sở điểm nổi, trả lại giao diện hữu cơ hơn.
Kỹ sư

Bạn nói đúng! Tôi nghĩ rằng tôi đã viết phần đó. Nhưng tôi không có. Tôi xin lỗi vì sai lầm này. Có, tôi biết về kích thước lưới. Một căn phòng chỉ có thể nhỏ như lưới cho phép.
AturSams

OK - hy vọng bạn tìm thấy một giải pháp phù hợp. BTW Tôi có nghĩa là "điều chỉnh đường lưới", không phải "điều chỉnh trục".
Kỹ sư

1
Thật ra tôi đang làm một cái gì đó chính xác như thế dựa trên các khái niệm mà bạn nghĩ tôi. Tôi sẽ đăng kết quả ở đây là tốt.
AturSams

2

Như bạn có thể thấy, tôi đã xoay sở để thoát khỏi thế giới của những cổ vật này. Ý tưởng rất giống nhau.

  1. Chia không gian 2d thành một lưới không đồng nhất. Nếu hai dòng quá gần, loại bỏ một.
  2. Chọn một hình chữ nhật ngẫu nhiên, kiểm tra xem nó đã được sửa đổi trên trục-y (về chiều cao) chưa và nếu hàng xóm trực tiếp của nó được sửa đổi trên trục-y. Cả hai tôi đều không được sửa đổi, yêu cầu họ đàm phán lại phân khúc giữa họ (người này sẽ tặng một số không gian cho người kia).
  3. Thực hiện tương tự như ở bước 2 chỉ lần này trên trục khác.
  4. Lặp lại quá trình cho đến khi bạn sửa đổi càng nhiều càng tốt.

Lưới không đồng nhất (1):

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

Đàm phán trên trục x (2):

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

Đàm phán trên trục y (3):

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

Kết quả (4):

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

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


Điều này được lấy cảm hứng lỏng lẻo từ cái nhìn sâu sắc từ @Nick Wiggill
AturSams

2
Người ta có thể cải thiện hơn nữa về điều này bằng cách hợp nhất ngẫu nhiên các nhóm n * m liền kề thành một hình chữ nhật duy nhất. Điều này che giấu lưới bên dưới vẫn có thể nhìn thấy trong đầu ra ở trên. Đàm phán với các hình chữ nhật lớn hơn này bây giờ phải hoạt động trên tất cả các ô dọc theo một trong các cạnh của nó.
DMGregory

ĐỒNG Ý. Vẫn còn rất nhiều ranh giới colinear, tôi sẽ làm việc thêm, nhưng thật tốt là bạn đã tìm thấy giải pháp của mình! Vui mừng được hỗ trợ.
Kỹ sư

@DMGregory Tôi đã xem xét điều này nhưng tôi muốn tỷ lệ giữa các nhóm nhỏ và các nhóm lớn được thống nhất phần nào. Nếu đây là một kết cấu hoặc một cấp độ, tôi chắc chắn sẽ làm điều đó (Thực tế có một ví dụ trước đó làm điều đó).
AturSams

@NickWiggill Tôi hoàn toàn có thể loại bỏ các dòng colinear. Nó chỉ là một vấn đề của việc điều chỉnh thuật toán. Phải có một cách để cải thiện nó hơn nữa (cập nhật với biến thể gần đây nhất)
AturSams
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.