凹型メッシュを一連の凸型メッシュに分解する


10

2つの理由で、凹型メッシュを凸型メッシュのセットに分解できるようにしたいと思います。

  1. 透明なレンダリング
  2. 物理図形

三角形のセット(凹)を入力として受け取り、いくつかの三角形のセット(凸)を出力するアルゴリズムはありますか?元のメッシュのパーツ間の穴を埋めないようにしてください。

私はすでに小さなアイデアに出くわしました。すべての凹型エッジを見つけ、エッジループに沿ってメッシュを分割します。私は正しい軌道に乗っていますか?これをどのように実装できますか?


「凹/凸」メッシュとは何ですか?メッシュが三角形ネットワークを意味する場合、それは凸状の三角形のセットです。それとも、3Dオブジェクトの量について話しているのですか?多面体かな?
Ivan Kuckir 2013

@IvanKuckirメッシュ、または多面体も凹面/凸面にすることができ、定義はほぼ同じです。たとえば、多面体の内部を2回以上交差する直線はありません。
congusbongus 2013

回答:


11

私はあなたが正しい軌道に乗っていると思いますが、最適かつ/または効率的なアルゴリズムを考え出すことは別の問題です:それは難しい問題です。ただし、学問的な関心がない限り、十分なソリューションで十分な場合があります。

まず、独自のソリューションを思いつくことに関心がない場合、CGALには凸多面体分解のアルゴリズムが既に含まれています。http//doc.cgal.org/latest/Convex_decomposition_3/index.html

次にメソッドについて。3Dの多くの問題と同様に、理解しやすい2Dの問題を検討すると役立つことがよくあります。2Dの場合、タスクは反射頂点を識別し、その反射頂点から新しいエッジ(および場合によっては新しい頂点)を作成してポリゴンを2つに分割し、反射頂点がなくなるまで(したがって、すべての凸形のポリゴンになるまで)続行します。 )。

反射頂点

J. Mark Keilによるポリゴン分解には、次のアルゴリズム(最適化されていない形式)が含まれています。

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

基本的に、すべての可能なパーティションを徹底的に比較し、生成された対角要素が最も少ないパーティションを返します。この意味で、それはやや力ずくで最適でもあります。

「見栄えのよい」分解、つまり細長い分解ではなく、よりコンパクトな形状を生成する分解が必要な場合は、Mark Ba​​yazitによって生成された分解を検討することもできます。基本的には、反射頂点を反対側の最良の頂点、通常は別の反射頂点に接続しようとすることで機能します。

バヤジットの新しい頂点 バヤジットは別の反射頂点に接続します

欠点の1つは、Steinerポイント(既存のエッジに存在しないポイント)を作成することにより、「より良い」分解を無視することです。

2つのシュタイナーポイントを使用したクローバー分解

3Dの問題も同様です。反射頂点の代わりに、「ノッチエッジ」を識別します。素朴な実装は、ノッチエッジを特定し、すべての多面体が凸状になるまで多面体に対して平面カットを繰り返し実行することです。チェックアウトバーナード・チャゼルによって:「最悪の場合、最適なアルゴリズム下限と凸多面体のパーティションを」詳細については。

ノッチ付き多面体

このアプローチは、最悪の場合、指数関数的な数の多面体を生成する可能性があることに注意してください。これは、次のようなケースが退化する可能性があるためです。

多くのノッチ付き多面体

しかし、重要なメッシュがある場合(でこぼこの表面を考えてください)、とにかく結果が良くありません。複雑なメッシュにこれを使用する必要がある場合は、事前に多くの単純化を行いたいと思うでしょう。


6

表面Sの正確な凸分解を計算することはNP困難な問題であり、通常は多数のクラスターを生成します。これらの制限を克服するために、正確な凸制約が緩和され、代わりにSの近似凸分解が計算されます。ここでの目標は、最小数のクラスターでメッシュ三角形のパーティションを決定することであり、各クラスターの凹面がユーザー定義のしきい値よりも低いことを確認します。

正確な凸分解と近似凸分解

次の近似凸分解ライブラリを確認してください。https//code.google.com/p/v-hacd/ http://sourceforge.net/projects/hacd/


0

ここにあなたを助けることができるいくつかのコードがあります。これはJavaなので、C ++に変換する必要があります。

ここにもあなたを助けることができる別の記事があります


1
こんにちはMasked Rebel。リンクのみの回答はお勧めしません。URLが変更されたり、リソースが利用できなくなったりすると、リンクに完全に依存する回答が、将来のユーザーのためのソリューションから完全に空になる可能性があります。読者が深くクリックする前であっても、回答がそのままで問題を解決するためのガイドを提供できる限り、クレジットとさらに読むためのリンクを提供することは素晴らしいことです。この回答を編集して、少なくともリンク先のソリューションがどのように機能するかの概要を含めてください。
DMGregory

@DMGregory自分ではできない答えを削除してください。

答えは必ずしも削除を必要としているわけではありません。編集して情報を追加するだけで、すばらしい回答が得られます。
DMGregory

@DMGregoryしかし、それはこの投稿の別の回答の複製になります。私は他の答えを編集してそこに私の情報を入れます。

そもそもこの答えを共有したときに、何か新しいことがあったと感じたと思います。リンクしたコードを、既存の回答のカーボンコピーではない方法で説明できることは間違いありません。ただし、削除したい場合は、デスクトップバージョンのサイトで削除するためのリンクを利用できます。
DMGregory
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.