6

私は現在、C++とOpenglを使用してマーチングキューブを実装するプログラムを書いています。

ただし、私の最良の参照はhttp://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/からのみです。

Webでは、提供されているコードはCで記述されています。
ここでの私の問題は、triTableとedgeTable
、およびそれらがどのように関連しているかを理解していないことです。

誰かが私に説明を手伝ったり、アルゴリズムをコードに変換する方法を教えてもらえますか?

4

1 に答える 1

12

これらのテーブルは、サーフェスをテッセレートする方法を見つけるために使用されます。

最初の表は、補間に必要なエッジを示しています。2 番目の表は、テッセレーションの方法、つまり立方体の内部にどの三角形を作成する必要があるかを示しています。

ちょっとした例:

頂点 1 と 2 が iso レベルより下にあり、cubeindex が 3 であると仮定しましょう。

交差点全体がくさびのように見えるはずです。

考えてみると、エッジの値を補間する必要があります: 0 と 9 、および 2 と 10 です。これをビットフィールドに入力すると、「エッジが交差していますか?」に対応する各ビットが対応します。次のような結果になります。

10 9 8 7 6 5 4 3 2 1 エッジ
 1 1 0 0 0 0 1 0 1 0 交差?

そうでしょう?

これは正確にバイナリの edgeTable[3] からの値です;) 0x30A = 1100001010

これで、アイソレベルに合わせてこれらのエッジ上のポイントを線形補間する関数を作成できます。これらのポイントは、このセル内のサーフェスになります。

しかし、このセル/サーフェスをテッセレートする方法は?

triTable[3] を調べると、笑顔が顔に忍び寄るはずです :)

コメントの残りの困惑の声明の後に追加: ;-)

マーチング キューブの機能: 点光源が 1 つある暗い部屋があるとします。これは、スカラー強度値の体積光強度フィールドの中心です。ポイント (x,y,z) に移動して、そこで強度を測定できます (例: 3 カンデラ)。

ここで、特定の光強度を持つすべてのポイントを通るサーフェスをレンダリングしたいと考えています。この等値面が点光源の周りの球のように見えると想像できます。それが、マーチング キューブが私たちに提供してくれることを願っています。

部屋のすべてのポイントを実行し、すべてのポイントを大まかな iso 値を持つ頂点としてマークすると、アルゴリズム的に非常に複雑になり、頂点の数が膨大になります。何らかの形でテッセレートする必要があります。

そのため、最初のマーチング キューブは、ボリューム全体を同じサイズのキューブに分割します。基礎となるデータにある種の基礎となる離散性がある場合、その倍数が使用されます。それ以外のケースはめったにないので、ここでは説明しません。たとえば、2mx5mx5m の部屋に密度 1mm のグリッドを配置します。

5mm×5mm×5mmの立方体を使用しています。それらを実行すると、はるかに安くなるはずです。

いくつかの立方体のエッジが等値面と交差していることを想像できます。これらは興味深いものです。このコードはそれらを識別します。

キューブインデックス = 0;
   もし (grid.val[0]

cubeindex が 0 のままの場合、この特定の立方体は等値面と交差しません。cubeindex が > 0 の場合、等値面がこの立方体を通過することがわかり、その中にある等面の一部をレンダリングしたいとします。

これを頭の中でイメージしてください。 交差する立方体の例については、 http://en.wikipedia.org/wiki/Marching_cubesを参照 してください。

簡単に取得できる頂点は、立方体の端にある頂点です。等値の位置を見つけ、そこに頂点を配置するために、2 つのコーナー ポイント間を直線的に補間するだけです。しかし、どのエッジが交差していますか??? それが edgeTable[cubeindex] の情報です。これは、補間された点を頂点として xyz 点の配列 vertlist[] に格納する、すべての if を含む大きなコードです。この作品には次のように書かれています。

ビットフィールドを取得 = edgeTable[cubeindex]
 エッジ 1 がビットフィールドでマークされている場合 (ビットフィールドでビット 1 が 1 に設定されている)
    vertlist[0] = 補間されたポイント、エッジ 1 のどこか
... 等々。

頂点でいっぱいの配列ができましたが、それらを三角形に接続するにはどうすればよいでしょうか? それはtritableが提供する情報です。

残りは、私が上で説明したこととほぼ同じです。

問題が解決しない場合は、問題の原因となっているコードについて具体的に教えてください。

于 2009-04-22T11:18:17.013 に答える