2009-09-10 5 views

答えて

4

GNU Triangulated Surface Librarycan do this for you。サーフェスは閉じなければならないことに注意してください。かなりの3Dモデルではそうはならないでしょう。

自分で実装したい場合は、まずコードを確認します。

+7

これを再実装する場合は、GTSライブラリがLGPLであることに注意してください。したがって、派生的な作業はLGPLまたはGPLでなければなりません。 – Cascabel

-1

私が正しく理解していれば、三角形のサーフェスメッシュが既にあり、3Dソリッドメッシュを生成したいとお考えです。

三角形は、3D内部に四面体要素を使用する必要があることを意味します。サーフェスメッシュをシードとして使用できるoctree auto meshing algorithmを検索する必要があります。

これは、有限要素オートメッシング文献の一般的な問題です。私はそこを見るだろう。

59

Reading this paper実際には非常に簡単な計算です。

トリックは四角形の符号付きボリュームを計算することです - あなたの三角形に基づいて、原点を上に置いてください。音量の記号は、三角形が原点の方向を指しているかどうかによって決まります。 (三角形の法線は、それ自体、あなたはそれが明示的に以下に参照が表示されない理由は、あなたの頂点の順序に依存する。)

は、このすべては、次の簡単な関数に沸く:

public float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3) { 
    var v321 = p3.X*p2.Y*p1.Z; 
    var v231 = p2.X*p3.Y*p1.Z; 
    var v312 = p3.X*p1.Y*p2.Z; 
    var v132 = p1.X*p3.Y*p2.Z; 
    var v213 = p2.X*p1.Y*p3.Z; 
    var v123 = p1.X*p2.Y*p3.Z; 
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123); 
} 

その後、メッシュの体積を計算するためにドライバ:

public float VolumeOfMesh(Mesh mesh) { 
    var vols = from t in mesh.Triangles 
       select SignedVolumeOfTriangle(t.P1, t.P2, t.P3); 
    return Math.Abs(vols.Sum()); 
} 
+1

きわめて洗練されたソリューションです。 – levis501

+0

2001年以前にこれが発見されなかったのはなぜだろうか?それはありましたが、関連性はありませんでしたか? –

+1

Oct 1984、論文「任意の非凸多面体の積分特性を計算するための記号的方法」という論文が出版され、この方法を説明して体積を計算する。 それは多かれ少なかれ些細な方法でもありますので、この情報だけではなく、紙を公開するだけです。 –

14

イップ・フランクKruegersの答えは、そのためにも+1を動作します。ベクタ関数を利用できる場合は、これも使用できます。

public static float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3) 
    { 
     return p1.Dot(p2.Cross(p3))/6.0f; 
    } 

編集が追加されました。もしあなたが不明ならDot()とCross()のために。ほとんどの数学ライブラリにはこれらがあります。 WPFを使用している場合は、Vector3Dクラスの静的メソッドとして実装されます。

public class Vector 
    { 
     ... 

     public float Dot(Vector a) 
     { 
      return this.X * a.X + this.Y * a.Y + this.Z * a.Z; 
     } 

     public Vector Cross(Vector a) 
     { 
      return new Vector(
       this.Y * a.Z - this.Z * a.Y, 
       this.Z * a.X - this.X * a.Z, 
       this.X * a.Y - this.Y * a.X 
      ); 
     } 
     ... 
    } 
+0

おそらくDot()とCross()のポストコードか? (実装するのは簡単ですが、完全性のために)。ところで、@フランククルーガーズの答えはあなたがp1.Dot(p2.Cross(p3))/ 6.0f –

1

上記の方法は球体四面体のような「単純な」オブジェクト(交差する/重なり合う三角形がない)に適しています。複雑な形状の場合は、メッシュを分割して(閉じて)、各セグメントのボリュームを別々に計算することをお勧めします。 これが役立つことを願っています。

+3

を簡略化すると得られるものです。ボリュームが署名されている場合は、センターが内部にある必要はありません – makc

+1

間違った答えです。説明された方法は、交差/重複三角形を持たない任意の複雑な閉じたオブジェクトに対して正しく、中心点の位置に関する要件はない。これは四面体の「ボリューム」が符号付きで代数的に追加されるためです。 – galinette

+0

@galinetteはい、あなたは正しいです。 「単純な」オブジェクトとは、交差/重複する三角形のないオブジェクトを意味していました。メッシュの中心も外側にすることができます。 – imoutidi

関連する問題