我正在使用Mathematica连接外部程序。我正在为外部程序创建一个输入文件。它将几何数据从Mathematica生成的图形转换为预定义的格式。这是一个Geometry的例子。
可以在Mathematica中以多种方式描述几何体。以下是一种费力的方式。
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]
这将以GraphicsComplex
格式生成MMA所需的3D几何体。
此几何体被描述为我的外部程序的以下输入文件。
# 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
现在我从这个外部程序的文档中得到的描述非常简短。我在这里引用它。
我们在名为One.obj的文件中使用3D CAD模型,并在MMA中正确导出。
cd = Import["One.obj"]
输出是MMA Graphics3D
对象
现在,我可以轻松访问几何数据,因为MMA会在内部读取它们。
{ver1, pol1} = cd[[1]][[2]] /. GraphicsComplex -> List;
MyPol = pol1 // First // First;
Graphics3D[GraphicsComplex[ver1,MyPol],Axes-> True]
ver1
和pol1
中包含的顶点和多边形信息,并将其写入文本文件中,如上面的输入文件示例所述。在这种情况下,我们只有 ID2 类型(三角形)面板。很抱歉这么长的帖子,但它是我试图解决很长一段时间的难题。希望你们中的一些专家可能有正确的见解来破解它。
BR
答案 0 :(得分:5)
Q1和Q2非常简单,您可以在问题中删除“挑战”标签。第三季度可以使用一些澄清。
Q1
edges = cd[[1, 2, 1]];
polygons = cd[[1, 2, 2, 1, 1, 1]];
更新Q1
主要问题是找到每个多边形的邻居。以下是:
(* 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 *)
您可以使用here所述的低级输出函数输出这些函数。我会把细节留给你(这是我对你的挑战)。
<强> 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}]
]
]
该区域已签署BTW,因此您可能需要使用Abs
。
<强> CORRECTION 强>
上述区域功能仅适用于 2D 中的一般多边形。对于 3D 中三角形的区域,可以使用以下内容:
ClearAll[polygonArea];
polygonArea[pts_List?(Length[#] == 3 &)] :=
Norm[Cross[pts[[2]] - pts[[1]], pts[[3]] - pts[[1]]]]/2