web-dev-qa-db-ja.com

寛容なライセンスを持つ堅牢で高速な複雑なポリゴン(穴あり)三角形分割c / c ++ライブラリ

私はオープンソースゲーム Bitfighter の開発者です。次のSOポストに従って、ゲーム内AI(ロボット)で使用するメッシュゾーン生成に優れた「三角形」ライブラリを使用しました:

穴のあるポリゴンの三角形分割

しかし、Debian向けにゲームをパッケージ化したいと思ったとき、小さな問題に遭遇しました。「Triangle」ライブラリを使用すると、ゲームが「非フリー」と見なされます。

私たちは「Triangle」ライブラリのパフォーマンスに非常に満足しており、実際にそれをあきらめたくありません。ただし、ライセンスの問題に対処することも好きではありません。したがって、堅牢性と速度の点で「トライアングル」に匹敵する、適切に許可されたライセンスの代替品を見つけるための探求に着手しました。

私たちは、大きく複雑な領域を三角形に分割するためのCまたはC++ライブラリを探しています。これは、任意の方法で配置されたあらゆる種類の不規則なポリゴンや穴を処理できます。堅牢性は私たちの主要なニーズであり、速度と同じくらい重要です。

poly2tri を見つけましたが、一致するエッジを持つポリゴンを処理できないというバグがあります。

いくつかのライブラリを見つけましたが、すべてが何らかの問題に苦しんでいるようです。遅すぎるか、ホールを処理しないか、またはいくつかのバグに苦しんでいます。現在 polypartition をテストしており、期待しています。

優れた「トライアングル」ライブラリに代わる最良の選択肢は何ですか?ただし、許容ライセンスがありますか?

16
raptor

解決策を見つけました。結局、それは poly2tri であり、優れた Clipper ライブラリを使用して、入力にいくつかの小さなアルゴリズムを追加しました。

プロセスは次のとおりです。

  1. NonZero巻線のユニオンを使用して、すべての穴をクリッパーに通します(これは、内側の穴が外側の穴とは反対の方向に巻かれていることを意味します)。クリッパーはまた、イプシロン内での繰り返しのない、すっきりとした入力ポイントを保証します。
  2. 私たちの穴を、反時計回りと時計回りに巻かれた穴にフィルターします。時計回りの穴は、その穴が遠回りであること、および三角形化する必要がある別の同心領域が内部にあることを意味しました
  3. Poly2triを使用して、外側の境界と検出された時計回りの各ポリゴンを三角形分割し、残りの穴を境界の1つで見つかった場合はpoly2triへの入力として使用します。

結果:poly2triはTriangleとほぼ同じくらい速く三角形化するようであり、これまでのところ、投げたすべてのものに対して非常に堅牢です。

興味のある方は コードの変更はこちら

更新

堅牢性を追加したクリッパーからpoly2triへのコードを、ここで始めた別のライブラリーに引き出そうとしました: clip2tri

18
raptor

小さな補足として:

私は最近、窓枠を家の壁にカットするために、複雑なポリゴンクリッパーと三角形分割機を実装する必要がありました。

Vattiクリッパーの結果に満足している間、poly2triで使用されているDelaunay三角形分割は重すぎて、壁の重心座標に沿ってウィンドウフレームをスムーズにドラッグできませんでした。頭を少し引っかいた後、穴を操作するために、この非常に単純な三角形をだましてしまいました。

http://wiki.unity3d.com/index.php?title=Triangulator

私が行ったのは、壁面を水平に最短のクリッピングポリの高さで細分割することでした。私の場合、それらは常に長方形ですが、そうである必要はありません。とにかく、それはクリッパーが通常または凹状のポリゴンでのみ動作するように強制するため、より安価な三角測量法で回避できます。

これが機能していることを示すスクリーンショットです。

https://www.dropbox.com/sh/zbzpvlkwj8b9gl3/sIBYCqa8ak

お役に立てれば。

1
Rob Bantin

CGALの2D Triangulationsパッケージをご覧ください。穴のあるポリゴンを三角形分割する例を here に示します。パッケージのライセンスはGPLv3 +です。

必要に応じて、このパッケージのみを抽出するのはそれほど難しくないことに注意してください。

1
sloriot