如何在特殊曲面网格中对边进行排序

Pla*_*iac 0 wolfram-mathematica mesh

这是一个功能,使用了几天前我问过的问题答案的建议.让我们在Mathematica中创建一个Graphics3D对象.我从这里使用这个3D几何数据.

cd = Import[NotebookDirectory[] <> "withwake.obj"];
vertices = cd[[1, 2, 1]];
polygons = Flatten[cd[[1, 2, 2, 1]] /. Polygon -> List, 2];
Graphics3D[GraphicsComplex[vertices, Polygon[polygons]]]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

对于每个多边形,我们创建一个指向其顶点的数字列表,然后是指向每个边连接到的多边形的数字.重要的是要注意表面正常; 定义面板的节点顺序应为逆时针.通过右手规则,如果手指弯曲以跟随编号,拇指将显示应指向"向外"几何的法线向量.

如果Graphics3D对象中的所有多边形都是三角形,则此函数会创建此类列表.

EdgeSorting[vertices_, polygons_] := 
Block[{triangleEdges, singleEdges, edgesNeighbors, relations, n, n1,
 n2, trires, triangleNeigbours, TriangleMaker, polygonArea, tring},
(*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*)
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];
Print[MatrixPlot[relations]];
(*Build a neighborhood list*)
triangleNeigbours = 
Table[Flatten[Position[relations[[i]], 1]], {i, 
  triangleEdges // Length}];
trires = 
Table[Flatten[{polygons[[i]], triangleNeigbours[[i]]}], {i, 1, 
  Length@polygons}];
TriangleMaker[{a_, b_, c_}] := {vertices[[a]], vertices[[b]], 
 vertices[[c]]};
{trires}
];
Run Code Online (Sandbox Code Playgroud)

我不完全理解这个功能的工作方式.我无法理解如何实现以下目标.

  1. 对于每个三角形四边形,如何形成前面提到的列表.
  2. 远离3D水翼的刨床称为尾翼板.对于每个尾迹四边形面板/多边形,我们需要形成一个指向其顶点的数字列表,后跟指向两个多边形的数字,它共享其唯一的边缘,将尾侧四边形面板/多边形与主水翼几何结构连接起来.

Hei*_*ike 5

要创建所有多边形及其邻居的列表,您可以执行以下操作:

neighbours[polygons_] := {#, 
  Flatten@Position[polygons, 
    a_List /; Length[Intersection[a, #]] == 2]} & /@ polygons;
Run Code Online (Sandbox Code Playgroud)

然后neighbours[polygons]创建一个列表,其中i-th条目包含polygons[[i]]和邻居的索引polygons[[i]].

对于问题的第二部分,你可以做类似的事情

wake[polygons_] := 
 Module[{edges, boundaries, wakelist, body}, 
  edges[polylist_] := Flatten[Map[Partition[#, 2, 1, 1] &, polylist], 1];
  boundaries = Cases[Tally[
     edges[polygons], (Sort[#1] == Sort[#2]) &], {a_, b_} /; b == 1 :> a];
  wakelist = 
   DeleteDuplicates[
    Map[Cases[polygons, a_ /; (Length[Intersection[a, #]] == 2)][[1]] &,
      boundaries]];
  {#, Flatten@Position[polygons, a_List /; (Length[Intersection[#, a]] == 2 && 
          Not[MemberQ[wakelist, a]])]} & /@ wakelist]
Run Code Online (Sandbox Code Playgroud)

wake,如果多边形包含没有任何相邻多边形的边,则将其视为尾迹面板.我不知道这是否总是有效,但它似乎适用于问题中的示例.

编辑 要分割尾迹和体多边形中的多边形的完整列表,您可以执行类似的操作

split[polygons_] := Module[{edges, boundaries, wakelist}, 
   edges[polylist_] := Flatten[Map[Partition[#, 2, 1, 1] &, polygons], 1];
   boundaries = Cases[Tally[edges[polygons], 
       (Sort[#1] == Sort[#2]) &], {a_, b_} /; b == 1 :> a];
   wakelist = DeleteDuplicates[Map[Cases[polygons, 
        a_ /; (Length[Intersection[a, #]] == 2)][[1]] &, boundaries]];
   {wakelist, Complement[polygons, wakelist]}];
Run Code Online (Sandbox Code Playgroud)

然后split[polygons]将生成两个子列表的列表.第一个子列表包含属于唤醒的所有多边形,第二个子列表包含属于主体的所有多边形.由于split已经将唤醒与身体分开,我们可以wake根据改写

wake2[wakelist_, bodylist_] := {#, Flatten@Position[bodylist,
      a_List /; (Length[Intersection[#, a]] == 2)]} & /@ wakelist
Run Code Online (Sandbox Code Playgroud)

然后找到身体多边形的列表加上它们的邻居的索引,以及唤醒多边形的列表加上你可以做的邻近身体多边形的索引

{wakepols, bodypols} = split[polygons];
bodylist = neighbours[bodypols];
wakelist = wake[wakepols, bodypols];
Run Code Online (Sandbox Code Playgroud)

请注意,在两个多边形的指数bodylistwakelist现指的是多边形的bodypols,不鸡舍的完整列表,polygons.