2011/11/19

C++ で Delaunay 分割(ただし2次元)

ちょっと学業の方が忙しくなってしまい、ウェブログを放置していました……。

忘れていたわけじゃないんだよ。ただちょっとモチベーションが足りなかっただけ。

今日は、某所(CG 系の研究室)で需要がありそうだったので、以前 Processing で書いていた Delaunay 分割を C++ で実装し直してみる事にしました。
ただし、C++ はものすごく苦手なので、ちょっと残念なソースになってしまっています。 ⇒ 11月20日追記:もうちょっと内部実装がマシになりました

ソースコード上部の「view plain」という文字をクリックするとコピペ用の窓が出ますので、使いたい方はご自由にどうぞ。



【アルゴリズム部分(Delaunay2d.h)】

【テスト用の GUI (Main.cpp)】



テスト用の GUI プログラムの方は、思いっきり Windows 依存です。

ただ、Delaunay 分割のアルゴリズムは完全に分離してあるので、他の環境で使いたい場合は Delaunay2d.h だけを持っていって、表示部はがんばって自分で作れば OK です。

肝心の使い方は以下の通りです(Main.cpp のコールバック関数内に実際のサンプルがあります)。
  1. 頂点リスト(std::list オブジェクト)を宣言します。
  2. 先ほどの頂点リストに、適当な頂点オブジェクトを格納します。
  3. 三角形リスト(std::list オブジェクト)を宣言します。
  4. Tercel::Delaunay2d::getDelaunayTriangles() 関数を呼びます。
このとき、getDelaunayTriangles() の第一引数に頂点リストの『参照』を、第2引数には三角形リストの『ポインタ』を渡します。

一見すると奇妙な仕様ですが、関数内で中身が変更されるオブジェクトに関してはポインタ渡し、そうでないものは参照渡しで構文を使い分けているためです。

特に関数を呼び出す側(ここでは Main.cpp )から見ると、参照渡しは値渡しのように見えるため、関数の中でオブジェクトが変更されないような印象になります。

Delaunay 分割された結果は三角形リストに格納されます。三角形(Tercel::Triangle 構造体)は、メンバに頂点(Tercel::Vertex オブジェクト)のポインタを保持します。ここでは、最初に作った頂点リストの要素を参照する形になります。

ですので、頂点リストの要素を削除した場合、三角形の頂点は不正なポインタになってしまう事に注意する必要があります。

0 件のコメント:

コメントを投稿

ひとことどうぞφ(・ω・,,)