1

私は外部プログラムをMathematicaとインターフェースさせています。外部プログラムの入力ファイルを作成しています。Mathematicaで生成されたグラフィックスからのジオメトリデータを事前定義されたフォーマットに変換することについてです。これがジオメトリの例です。

図1

図1

ジオメトリはMathematicaでさまざまな方法で記述できます。面倒な方法の1つは次のとおりです。

dat={{1.,-1.,0.},{0.,-1.,0.5},{0.,-1.,-0.5},{1.,-0.3333,0.},{0.,-0.3333,0.5},
{0.,-0.3333,-0.5},{1.,0.3333,0.},{0.,0.3333,0.5},{0.,0.3333,-0.5},{1.,1.,0.},
{0.,1.,0.5},{0.,1.,-0.5},{10.,-1.,0.},{10.,-0.3333,0.},{10.,0.3333,0.},{10.,1.,0.}};

Show[ListPointPlot3D[dat,PlotStyle->{{Red,PointSize[Large]}}],Graphics3D[{Opacity[.8],
Cyan,GraphicsComplex[dat,Polygon[{{1,2,5,4},{1,3,6,4},{2,3,6,5},{4,5,8,7},{4,6,9,7},
{5,6,9,8},{7,8,11,10},{7,9,12,10},{8,9,12,11},{1,2,3},{10,12,11},{1,4,14,13},
{4,7,15,14},{7,10,16,15}}]]}],AspectRatio->GoldenRatio]

これにより、必要な3DジオメトリGraphicsComplexがMMAの形式で生成されます。 ここに画像の説明を入力してください

このジオメトリは、私の外部プログラムの次の入力ファイルとして記述されています。

# GEOMETRY
# x y z [m]
NODES 16
1. -1. 0.
0. -1. 0.5
0. -1. -0.5
1. -0.3333 0.
0. -0.3333 0.50. -0.3333 -0.5
1. 0.3333 0.
0. 0.3333 0.5
0. 0.3333 -0.5
1. 1. 0.
0. 1. 0.5
0. 1. -0.5
10. -1. 0.
10. -0.3333 0.
10. 0.3333 0.
10. 1. -0.
# type node_id1 node_id2 node_id3 node_id4  elem_id1 elem_id2 elem_id3 elem_id4
PANELS 14
1 1 4 5 2 4 2 10 0
1 2 5 6 3 1 5 3 10
1 3 6 4 1 2 6 10 0
1 4 7 8 5 7 5 1 0
1 5 8 9 6 4 8 6 2
1 6 9 7 4 5 9 3 0
1 7 10 11 8 8 4 11 0
1 8 11 12 9 7 9 5 11
1 9 12 10 7 8 6 11 0
2 1 2 3 1 2 3
2 10 12 11 9 8 7
10 4 1 13 14 1 3
10 7 4 14 15 4 6
10 10 7 15 16 7 9
# end of input file

今、私がこの外部プログラムのドキュメントから持っている説明はかなり短いです。ここで引用しています。


  1. 最初のキーワードNODESは、ノードの総数を示します。この行の後には、コメントや空の行はありません。次の行は、x、y、zの3つのノード座標で構成され、行数はノード数と同じである必要があります。
  2. 次のキーワードはPANELで、パネルの数を示します。その後、各パネルを定義する線があります。最初の整数はパネルタイプを定義します
  3. ID 1四辺形パネル–4つのノードと4つの隣接するパネルによって定義されます。隣接するパネルは、同じ側面(ノードのペア)を共有するパネルであり、速度と圧力の計算に必要です(方法1および2)。欠落しているネイバー(たとえば、後縁近くのパネルの場合)は、値0で埋められます(図1を参照)。
  4. ID 2三角形のパネル–は、3つのノードと3つの隣接するパネルによって定義されます。
  5. ID 10ウェイクパネル–は、4つのノードと、後縁に配置された2つの(隣接する)パネル(ウェイクパネルがクッタ条件を適用しているパネル)で定義された四辺形パネルです。
  6. パネルタイプ1および2は、入力ファイルのタイプ10の前に定義する必要があります。注意すべき重要な点は、表面の法線です。パネルを定義するノードの順序は反時計回りである必要があります。右手の法則により、指が番号付けに従うように曲げられている場合、親指は「外側」のジオメトリを指す法線ベクトルを示します。

チャレンジ!!

One.objというファイルに3DCADモデルが含まれており、MMAで正常にエクスポートされます。

cd = Import["One.obj"]

出力はMMAGraphics3Dオブジェクト ですここに画像の説明を入力してください

これで、MMAが内部でジオメトリデータを読み取るため、ジオメトリデータに簡単にアクセスできます。

{ver1, pol1} = cd[[1]][[2]] /. GraphicsComplex -> List;
MyPol = pol1 // First // First;
Graphics3D[GraphicsComplex[ver1,MyPol],Axes-> True]

ここに画像の説明を入力してください

  1. 上記の入力ファイルの例で説明されているように、に含まれている頂点とポリゴン情報を使用して、テキストファイルに書き込むver1方法。pol1この場合、ID2タイプ(三角形)のパネルのみがあります。
  2. Mathematicaの三角測量を使用して、この3Dオブジェクトの表面積を見つける方法。MMAで表面積を計算できる組み込み関数はありますか?
  3. 今すぐウェイクパネルやID10タイプの要素を作成する必要はありません。三角形の要素のみを含む入力ファイルで問題ありません。

長い投稿で申し訳ありませんが、私が長い間解決しようとしているパズルです。あなたの専門家の何人かがそれをクラックするための正しい洞察を持っているかもしれないことを願っています。

BR

4

1 に答える 1

5

Q1 と Q2 は簡単なので、質問の「挑戦」というラベルを外すことができます。Q3は、いくつかの説明を使用できます。

Q1

edges = cd[[1, 2, 1]];

polygons = cd[[1, 2, 2, 1, 1, 1]];

第 1 四半期の更新

主な問題は、各ポリゴンの隣接を見つけることです。以下はこれを行います:

(* Split every triangle in 3 edges, with nodes in each edge sorted *)
triangleEdges = (Sort /@ Subsets[#, {2}]) & /@ polygons;

(* Generate a list of edges *)
singleEdges = Union[Flatten[triangleEdges, 1]];

(* Define a function which, given an edge (node number list), returns the bordering  *)
(* triangle numbers. It's done by working through each of the triangles' edges       *)
ClearAll[edgesNeighbors]
edgesNeighbors[_] = {};
MapIndexed[(
   edgesNeighbors[#1[[1]]] = Flatten[{edgesNeighbors[#1[[1]]], #2[[1]]}];
   edgesNeighbors[#1[[2]]] = Flatten[{edgesNeighbors[#1[[2]]], #2[[1]]}];
   edgesNeighbors[#1[[3]]] = Flatten[{edgesNeighbors[#1[[3]]], #2[[1]]}];
   ) &, triangleEdges
];

(* Build a triangle relation table. Each '1' indicates a triangle relation *)
relations = ConstantArray[0, {triangleEdges // Length, triangleEdges // Length}];
Scan[
  (n = edgesNeighbors[##]; 
     If[Length[n] == 2, 
        {n1, n2} = n; 
        relations[[n1, n2]] = 1;  relations[[n2, n1]] = 1];
   ) &, singleEdges
]

MatrixPlot[relations]

三角関係

(* Build a neighborhood list *)
triangleNeigbours = 
    Table[Flatten[Position[relations[[i]], 1]], {i,triangleEdges // Length}];

(* Test: Which triangles border on triangle number 1? *)
triangleNeigbours[[1]]

(* ==> {32, 61, 83} *)

(* Check this *)
polygons[[{1, 32, 61, 83}]]

(* ==> {{1, 2, 3}, {3, 2, 52}, {1, 3, 50}, {19, 2, 1}} *)
(* Indeed, they all share an edge with #1 *)

ここで説明する低レベル出力関数を使用して、これらを出力できます。詳細はあなたに任せます(それがあなたへの私の挑戦です)。

Q2
翼の面積は、個々のポリゴンの合計面積です。個々の面積は次のように計算できます。

ClearAll[polygonArea];
polygonArea[pts_List] :=
 Module[{dtpts = Append[pts, pts[[1]]]},
   If[Length[pts] < 3, 
      0, 
      1/2 Sum[Det[{dtpts[[i]], dtpts[[i + 1]]}], {i, 1, Length[dtpts] - 1}]
   ]
 ]

この Mathworld ページに基づいています。

この領域は BTW で署名されているため、 を使用することをお勧めしますAbs

訂正
上記の面積関数は、2Dの一般的なポリゴンに対してのみ使用できます。3Dの三角形の面積については、以下を使用できます。

ClearAll[polygonArea];
polygonArea[pts_List?(Length[#] == 3 &)] := 
    Norm[Cross[pts[[2]] - pts[[1]], pts[[3]] - pts[[1]]]]/2
于 2011-09-14T20:51:14.680 に答える