Phân tách lưới lõm thành một tập hợp các lưới lồi


10

Tôi muốn có thể phân hủy một lưới lõm thành một tập hợp các lưới lồi vì 2 lý do:

  1. Kết xuất trong suốt
  2. Hình dạng vật lý

Có một thuật toán lấy một tập hợp các hình tam giác (lõm) làm đầu vào và đầu ra một số bộ hình tam giác (lồi) không? Tôi muốn nó không điền vào các lỗ giữa các phần của lưới ban đầu.

Tôi đã bắt gặp một ý tưởng nhỏ: tìm tất cả các cạnh lõm và chia các mắt lưới dọc theo các vòng cạnh. Có phải tôi đang trên đường ray bên phải không? Làm thế nào tôi có thể thực hiện điều này?


Lưới "lõm / lồi" là gì? Nếu lưới có nghĩa là mạng tam giác, thì nó chỉ là một tập hợp các hình tam giác, là lồi. Hay bạn đang nói về khối lượng của các vật thể 3D? Có lẽ đa diện?
Ivan Kuckir

@IvanKuckir Lưới, hoặc khối đa diện, cũng có thể là lõm / lồi, và định nghĩa là khá giống nhau. Ví dụ, không có đường thẳng nào sẽ giao nhau với phần bên trong của khối đa diện nhiều lần.
congusbongus

Câu trả lời:


11

Tôi muốn nói rằng bạn đang đi đúng hướng, nhưng đưa ra một thuật toán tối ưu và / hoặc hiệu quả là một vấn đề khác: đó là một vấn đề khó khăn. Tuy nhiên, trừ khi sở thích của bạn là học thuật, một giải pháp đủ tốt có thể đủ.

Đầu tiên, nếu bạn không quan tâm đến việc đưa ra giải pháp của riêng mình, CGAL đã chứa thuật toán phân rã đa diện lồi: http://doc.cgal.org/latest/Convex_decysis_3/index.html

Bây giờ cho phương pháp; Giống như nhiều vấn đề trong 3D, thường hữu ích khi xem xét vấn đề 2D dễ hiểu hơn. Đối với 2D, nhiệm vụ là xác định các đỉnh phản xạ và chia đa giác thành hai bằng cách tạo một cạnh mới (và có thể là các đỉnh mới) từ đỉnh phản xạ đó và tiếp tục cho đến khi bạn không còn các đỉnh phản xạ (và do đó đa giác lồi ).

đỉnh phản xạ

Phân tích đa giác của J. Mark Keil chứa thuật toán sau (ở dạng không được tối ưu hóa):

diags = decomp(poly)
    min, tmp : EdgeList
    ndiags : Integer
    for each reflex vertex i
        for every other vertex j
            if i can see j
                left = the polygon given by vertices i to j
                right = the polygon given by vertices j to i
                tmp = decomp(left) + decomp(right)
                if(tmp.size < ndiags)
                    min = tmp
                    ndiags = tmp.size
                    min += the diagonal i to j
    return min

Về cơ bản, nó so sánh triệt để tất cả các phân vùng có thể, và trả về một phân vùng có ít đường chéo nhất được tạo ra. Theo nghĩa này, nó có phần mạnh mẽ và tối ưu.

Nếu bạn muốn phân tách "đẹp hơn", đó là các phân tách tạo ra hình dạng nhỏ gọn hơn là hình thon dài, bạn cũng có thể xem xét phân tách này do Mark Bayazit sản xuất , tham lam (do đó nhanh hơn nhiều) và trông đẹp hơn nhưng có một vài khuyết điểm. Về cơ bản, nó hoạt động bằng cách cố gắng kết nối các đỉnh phản xạ với đỉnh tốt nhất đối diện với nó, điển hình là một đỉnh phản xạ khác:

Bayazit đỉnh mới bayazit kết nối với một đỉnh phản xạ khác

Một trong những thiếu sót là nó bỏ qua các phân tách "tốt hơn" bằng cách tạo các điểm Steiner (các điểm không tồn tại trên một cạnh hiện có):

phân tách cỏ ba lá bằng cách sử dụng hai điểm steiner

Vấn đề trong 3D có thể tương tự; thay vì các đỉnh phản xạ, bạn xác định "các cạnh notch". Việc thực hiện ngây thơ sẽ là xác định các cạnh notch và thực hiện cắt mặt phẳng trên khối đa diện nhiều lần cho đến khi tất cả các khối đa diện đều lồi. Kiểm tra "Phân vùng lồi của khối đa diện: Thuật toán tối ưu trường hợp thấp nhất và trường hợp xấu nhất" của Bernard Chazelle để biết thêm chi tiết.

khối đa diện có notch

Lưu ý rằng phương pháp này có thể tạo ra trường hợp xấu nhất theo số mũ đa diện. Điều này là do bạn có thể có những trường hợp thoái hóa như thế này:

nhiều khối đa diện

Nhưng nếu bạn có một lưới không tầm thường (nghĩ bề mặt gập ghềnh), dù sao bạn cũng sẽ nhận được kết quả kém. Rất có khả năng bạn sẽ muốn thực hiện nhiều đơn giản hóa trước đó, nếu bạn cần sử dụng điều này cho các mắt lưới phức tạp.


6

Việc tính toán phân tách lồi chính xác của bề mặt S là một vấn đề khó NP và thường tạo ra một số lượng lớn các cụm. Để khắc phục những hạn chế này, ràng buộc độ lồi chính xác có thể được nới lỏng và thay vào đó, một phép phân tách lồi gần đúng của S được tính toán. Ở đây, mục tiêu là xác định một phân vùng của các tam giác lưới với số lượng cụm tối thiểu, trong khi đảm bảo rằng mỗi cụm có độ lõm thấp hơn ngưỡng do người dùng xác định.

Phân rã lồi chính xác so với phân rã lồi gần đúng

Kiểm tra các thư viện phân tách lồi gần đúng sau đây: https://code.google.com.vn/p/v-hacd/ http://sourceforge.net/projects/hacd/


0

Đây là một số mã có thể giúp bạn. Nó có trong java nên bạn sẽ phải chuyển đổi nó thành c ++.

Đây cũng là một bài viết có thể giúp bạn


1
Hi Masked Rebel, câu trả lời chỉ liên kết được khuyến khích ở đây. Nếu URL thay đổi hoặc tài nguyên không khả dụng, nó có thể để lại câu trả lời phụ thuộc hoàn toàn vào liên kết hoàn toàn trống rỗng các giải pháp cho người dùng trong tương lai. Thật tuyệt khi cung cấp liên kết cho tín dụng & đọc thêm, miễn là câu trả lời của bạn vẫn có thể tự đứng vững và cung cấp hướng dẫn để giải quyết vấn đề ngay cả trước khi người đọc nhấp sâu hơn. Vui lòng xem xét chỉnh sửa câu trả lời này để bao gồm ít nhất một phác thảo rộng về cách giải pháp bạn liên kết với hoạt động.
DMGregory

@DMGregory Vui lòng xóa câu trả lời Tôi không thể tự mình.

Câu trả lời không nhất thiết là cần phải xóa. Chỉ cần chỉnh sửa nó để bao gồm một số thông tin có thể làm cho nó một câu trả lời tuyệt vời.
DMGregory

@DMGregory nhưng sau đó nó sẽ là một bản sao của câu trả lời khác trên bài đăng này. Tôi sẽ chỉ chỉnh sửa câu trả lời khác và đặt thông tin của tôi ở đó.

Tôi đoán bạn cảm thấy bạn có một cái gì đó mới để thêm khi bạn chia sẻ câu trả lời này ở nơi đầu tiên. Tôi không nghi ngờ rằng bạn có thể giải thích mã bạn đã liên kết theo cách không phải là bản sao của câu trả lời hiện có. Nếu bạn muốn xóa nó đi, liên kết để làm như vậy có sẵn cho bạn trên phiên bản máy tính để bàn của trang web.
DMGregory
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.