Mengurai mesh cekung menjadi satu set mesh cembung


10

Saya ingin dapat mendekomposisi mesh cekung menjadi satu set mesh cembung karena 2 alasan:

  1. Render transparan
  2. Bentuk fisik

Apakah ada algoritma yang mengambil seperangkat segitiga (cekung) sebagai input dan menghasilkan sejumlah set segitiga (cembung)? Saya ingin tidak mengisi lubang di antara bagian-bagian dari jaring asli.

Saya sudah menemukan ide kecil: temukan semua tepi cekung, dan bagi jerat di sepanjang tepi loop. Apakah saya di jalur yang benar? Bagaimana saya bisa menerapkan ini?


Apa itu mesh "cekung / cembung"? Jika mesh berarti jaringan segitiga, maka itu hanya seperangkat segitiga, yang cembung. Atau apakah Anda berbicara tentang volume objek 3D? Mungkin polyhedron?
Ivan Kuckir

@IvanKuckir Jerat, atau polyhedra, dapat juga cekung / cembung, dan definisinya hampir sama. Misalnya, tidak ada garis lurus yang akan memotong bagian dalam polyhedron lebih dari sekali.
congusbongus

Jawaban:


11

Saya akan mengatakan Anda berada di jalur yang benar, tetapi menghasilkan algoritma yang optimal dan / atau efisien adalah masalah lain: ini masalah yang sulit. Namun, kecuali minat Anda bersifat akademis, solusi yang cukup baik mungkin sudah cukup.

Pertama, jika Anda tidak tertarik untuk membuat solusi Anda sendiri, CGAL sudah memiliki algoritma untuk dekomposisi cembung polyhedra: http://doc.cgal.org/latest/Convex_decomposition_3/index.html

Sekarang untuk metodenya; seperti banyak masalah dalam 3D, sering kali membantu untuk mempertimbangkan masalah 2D yang lebih mudah dipahami. Untuk 2D, tugasnya adalah mengidentifikasi simpul refleks, dan membagi poligon menjadi dua dengan menciptakan tepi baru (dan mungkin simpul baru) dari simpul refleks, dan melanjutkan sampai Anda dibiarkan tanpa simpul refleks (dan karenanya semua poligon cembung) ).

simpul refleks

Dekomposisi Polygon oleh J. Mark Keil berisi algoritma berikut (dalam bentuk yang tidak dioptimalkan):

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

Pada dasarnya ini secara ekstensif membandingkan semua partisi yang mungkin, dan mengembalikan yang memiliki diagonal paling sedikit. Dalam hal ini agak kasar dan optimal juga.

Jika Anda menginginkan dekomposisi yang “lebih bagus”, yaitu yang menghasilkan bentuk yang lebih padat daripada yang memanjang, Anda juga dapat mempertimbangkan yang ini dibuat oleh Mark Bayazit , yang serakah (karenanya jauh lebih cepat) dan terlihat lebih bagus tetapi memiliki beberapa kekurangan. Ini pada dasarnya bekerja dengan mencoba menghubungkan simpul refleks ke yang terbaik yang berlawanan dengannya, biasanya ke simpul refleks lain:

bayazit simpul baru bayazit terhubung ke verteks refleks lain

Salah satu kekurangannya adalah ia mengabaikan dekomposisi "lebih baik" dengan membuat poin Steiner (poin yang tidak ada pada edge yang ada):

dekomposisi semanggi menggunakan dua titik steiner

Masalah dalam 3D bisa serupa; alih-alih simpul refleks, Anda mengidentifikasi "takik tepi". Implementasi yang naif adalah mengidentifikasi takik tepi, dan melakukan pemotongan bidang pada polyhedron berulang kali sampai semua polyhedra cembung. Lihat "Partisi Cembung Polyhedra: Algoritma Optimal Terikat Bawah dan Terburuk" oleh Bernard Chazelle untuk detail lebih lanjut.

polyhedron dengan takik

Perhatikan bahwa pendekatan ini dapat menghasilkan kasus terburuk sejumlah sub-polyhedra yang eksponensial. Ini karena Anda dapat memiliki kasus degenerasi seperti ini:

banyak polyhedron berlekuk

Tetapi jika Anda memiliki mesh non-sepele (pikirkan permukaan bergelombang), Anda akan mendapatkan hasil yang buruk. Sangat mungkin Anda ingin melakukan banyak penyederhanaan sebelumnya, jika Anda perlu menggunakan ini untuk jerat yang rumit.


6

Menghitung dekomposisi cembung yang tepat pada permukaan S adalah masalah NP-hard dan biasanya menghasilkan banyak cluster. Untuk mengatasi keterbatasan ini, kendala konvexity yang tepat dapat dilonggarkan dan dekomposisi perkiraan cembung dari S malah dihitung. Di sini, tujuannya adalah untuk menentukan partisi dari segitiga mesh dengan jumlah cluster minimal, sambil memastikan bahwa setiap cluster memiliki konkavitas yang lebih rendah daripada ambang batas yang ditentukan pengguna.

Dekomposisi cembung yang tepat vs. perkiraan dekomposisi cembung

Lihat perkiraan perpustakaan dekomposisi cembung berikut: https://code.google.com/p/v-hacd/ http://sourceforge.net/projects/hacd/


0

Berikut ini beberapa kode yang dapat membantu Anda. Ini dalam java sehingga Anda harus mengubahnya ke c ++.

Di sini juga ada artikel lain yang bisa membantu Anda


1
Hai Pemberontak Bertopeng, jawaban tautan saja tidak disarankan di sini. Jika URL pernah berubah atau sumber daya menjadi tidak tersedia, ia dapat meninggalkan jawaban yang sepenuhnya bergantung pada tautan yang sepenuhnya kosong dari solusi untuk pengguna di masa mendatang. Sangat bagus untuk memberikan tautan kredit & bacaan lebih lanjut, selama jawaban Anda masih bisa berdiri sendiri dan memberikan panduan untuk menyelesaikan masalah bahkan sebelum pembaca mengklik lebih dalam. Silakan pertimbangkan untuk mengedit jawaban ini untuk menyertakan setidaknya garis besar yang luas tentang bagaimana solusi yang Anda tautkan berfungsi.
DMGregory

@DMGregory Harap hapus jawaban yang saya tidak bisa.

Jawabannya belum tentu perlu dihapus. Hanya mengeditnya untuk memasukkan lebih banyak informasi dapat membuatnya menjadi jawaban yang bagus.
DMGregory

@DMGregory tetapi kemudian itu akan menjadi duplikat dari jawaban lain pada posting ini. Saya hanya akan mengedit jawaban yang lain dan menaruh info saya di sana.

Saya kira Anda merasa Anda memiliki sesuatu yang baru untuk ditambahkan ketika Anda membagikan jawaban ini di tempat pertama. Saya tidak ragu bahwa Anda dapat menjelaskan kode yang Anda tautkan dengan cara yang bukan merupakan salinan karbon dari jawaban yang ada. Jika Anda lebih suka menghapusnya, tautan untuk melakukannya tersedia untuk Anda di versi desktop situs tersebut.
DMGregory
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.