首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数学编程的一个挑战

数学编程的一个挑战
EN

Stack Overflow用户
提问于 2011-09-14 19:21:12
回答 1查看 595关注 0票数 1

我正在与Mathematica接口一个外部程序。我正在为外部程序创建一个输入文件。它是关于将数学生成的图形中的几何数据转换成预定义格式的。这是一个几何的例子。

图1

几何学可以用数学的多种方式来描述。一条艰苦的道路是如下所示。

代码语言:javascript
复制
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]

这将以MMA的GraphicsComplex格式生成所需的三维几何。

此几何描述为我的外部程序的以下输入文件

代码语言:javascript
复制
# 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. 首先,关键字节点声明节点总数。在这一行之后,不应该有注释或空行。下一行由三个值x、y和z节点坐标组成,行数必须与节点数相同。
  2. 下一个关键字是面板,并说明我们有多少面板。在那之后,我们有定义每个面板的线条。第一个整数定义面板类型
  3. ID 1 --四边形面板--由四个节点和四个相邻面板定义。相邻面板是具有相同边(对节点)的面板,用于速度和压力计算(方法1和方法2)。缺少的邻居(例如,后面边缘附近的面板)填充值为0(请参见图1)。
  4. ID 2 --三角形面板--由三个节点和三个相邻面板定义。
  5. ID 10 --尾流面板--是由四个节点定义的四边形面板,两个相邻的面板位于尾流板的后缘(尾流面板适用库塔条件)。
  6. 必须在输入文件中的类型10之前定义面板类型1和2。重要的是要注意的是表面法线;节点的顺序定义面板应该逆时针方向。根据右手规则,如果手指弯曲以跟随编号,拇指将显示应该指向“向外”几何学的法线矢量。

挑战!!

在一个名为One.obj的文件中给出了一个三维CAD模型,并在MMA中导出。

代码语言:javascript
复制
cd = Import["One.obj"]

输出是MMA Graphics3D对象。

现在,当MMA内部读取几何数据时,我可以轻松地访问它们。

代码语言:javascript
复制
{ver1, pol1} = cd[[1]][[2]] /. GraphicsComplex -> List;
MyPol = pol1 // First // First;
Graphics3D[GraphicsComplex[ver1,MyPol],Axes-> True]

  1. 如何使用ver1pol1中包含的顶点和多边形信息,并将它们写入文本文件中,如上面的输入文件示例所述。在这种情况下,我们将只有ID2类型(三角形)面板。
  2. 利用Mathematica三角剖分,如何找到这个三维物体的表面积。在MMA中是否有计算表面积的内建函数?
  3. 现在不需要创建wake面板或ID10类型元素。只包含三角形元素的输入文件将很好。

很抱歉,这么长的帖子,但这是一个谜,我正试图解决很长时间。希望你们中的一些专家能有正确的洞察力来破解它。

BR

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-14 20:51:14

Q1和Q2非常容易,您可以在问题中去掉“挑战性”标签。Q3可能需要一些澄清。

Q1

代码语言:javascript
复制
edges = cd[[1, 2, 1]];

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

更新Q1

主要问题是找出每个多边形的邻域。如下所述:

代码语言:javascript
复制
(* 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]

代码语言:javascript
复制
(* 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

机翼的面积是单个多边形的总和。各地区的计算方法如下:

代码语言:javascript
复制
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中的三角形区域,可以使用以下方法:

代码语言:javascript
复制
ClearAll[polygonArea];
polygonArea[pts_List?(Length[#] == 3 &)] := 
    Norm[Cross[pts[[2]] - pts[[1]], pts[[3]] - pts[[1]]]]/2
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7421791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档