這是一組結構化的3D points。現在我們可以使用這些點作爲節點形成BSpline
。修改由ParametricPlot3D生成的Graphics3D對象
dat=Import["3DFoil.mat", "Data"]
fu=BSplineFunction[dat]
在這裏,我們可以做一個ParametricPlot3D
與這些觀點。
pic=ParametricPlot3D[fu[u,v],{u, 0, 1}, {v, 0, 1}, Mesh -> All, AspectRatio ->
Automatic,PlotPoints->10,Boxed-> False,Axes-> False]
問題
如果我們仔細看一下3D幾何出來,我們可以看到,它是中空結構的樣條。該孔出現在對稱輪廓的兩側。我們如何完美(不可見!)填補這個洞,並創建一個統一的Graphics3D
對象,其中兩側的孔修補。
我能夠弄到什麼如下。孔沒有完全修補。
最近我問了太多問題,我很抱歉。但是如果你們中的任何一位感興趣,我希望你們能幫上忙。
更新
這裏是貝利薩留法的問題。它生成三角形幾乎忽略不計的區域。
dat = Import[NotebookDirectory[] <> "/3DFoil.mat", "Data"];
(*With your points in "dat"*)
fd = [email protected]@dat;
check = ParametricPlot3D[{BSplineFunction[dat][u, v],
BSplineFunction[{dat[[1]], [email protected][[1]]}][u, v],
BSplineFunction[{dat[[fd]], [email protected][[fd]]}][u, v]}, {u, 0,
1}, {v, 0, 1}, Mesh -> All, AspectRatio -> Automatic,
PlotPoints -> 10, Boxed -> False, Axes -> False]
輸出這裏
Export[NotebookDirectory[]<>"myres.obj",check];
cd=Import[NotebookDirectory[]<>"myres.obj"];
middle=
check[[1]][[2]][[1]][[1(* Here are the numbers of different Graphics group*)]][[2,1,1,1]];
sidePatch1=check[[1]][[2]][[1]][[2]][[2,1,1,1]];
sidePatch2=check[[1]][[2]][[1]][[3]][[2,1,1,1]];
有三種Graphics
組其餘都是空的。現在讓我們看看這些組中三角形的面積。
polygonArea[pts_List?
(Length[#]==3&)]:=Norm[Cross[pts[[2]]-pts[[1]],pts[[3]]-pts[[1]]]]/2
TriangleMaker[{a_,b_,c_}]:={vertices[[a]],vertices[[b]],vertices[[c]]}
tring=Map[polygonArea[TriangleMaker[#]]&,middle];
tring//Min
對於中間大組輸出是
0.000228007
因此,這是一個允許的三角測量。但對於補丁我們得到零區域。
Map[polygonArea[TriangleMaker[#]] &, sidePatch1] // Min
Map[polygonArea[TriangleMaker[#]] &, sidePatch2] // Min
任何出路belisarius?
我的部分解決方案
首先下載包從Wolfram archive簡化複雜的多邊形。
fu = BSplineFunction[dat];
pic =(*ParametricPlot3D[fu[u,v],{u,0,1},{v,0,1},Mesh->None,
AspectRatio->Automatic,PlotPoints->25,Boxed->False,Axes->False,
BoundaryStyle->Red]*)
ParametricPlot3D[fu[u, v], {u, 0, 1}, {v, 0, 1}, Mesh -> None,
AspectRatio -> Automatic, PlotPoints -> 10, Boxed -> False,
Axes -> False, BoundaryStyle -> Black];
bound = [email protected][Normal[pic], Line[pts_] :> pts, Infinity];
corners = Flatten[Table[fu[u, v], {u, 0, 1}, {v, 0, 1}], 1];
nf = Nearest[bound -> Automatic]; {a1, a2} =
[email protected]@(nf /@ corners);
sets = {bound[[2 ;; a1]], bound[[a1 ;; a2]],bound[[a2 ;; a2 + a1]]};
CorrectOneNodeNumber = Polygon[sets[[{1, 3}]]][[1]][[1]] // Length;
CorrectOneNodes1 =
Polygon[sets[[{1, 3}]]][[1]][[1]]; CorrectOneNodes2 =
Take[Polygon[sets[[{1, 3}]]][[1]][[2]], CorrectOneNodeNumber];
<< PolygonTriangulation`SimplePolygonTriangulation`
ver1 = CorrectOneNodes1;
ver2 = CorrectOneNodes2;
triang1 = SimplePolygonTriangulation3D[ver1];
triang2 = SimplePolygonTriangulation3D[ver2];
Show[Graphics3D[{PointSize[Large], Point[CorrectOneNodes1]},Boxed -> False,
BoxRatios -> 1], Graphics3D[{PointSize[Large], Point[CorrectOneNodes2]},
Boxed -> False, BoxRatios -> 1],
Graphics3D[GraphicsComplex[ver1, Polygon[triang1]], Boxed -> False,
BoxRatios -> 1],
Graphics3D[GraphicsComplex[ver2, Polygon[triang2]], Boxed -> False,
BoxRatios -> 1]]
我們在這裏得到很好的三角形。
picfin=ParametricPlot3D[fu[u,v],{u,0,1}, {v,0,1},Mesh->All,AspectRatio->Automatic,PlotPoints->10,Boxed->False,Axes->False,BoundaryStyle->None];pic3D=Show[Graphics3D[GraphicsComplex[ver1,Polygon[triang1]]],picfin,Graphics3D[GraphicsComplex[ver2,Polygon[triang2]]],Boxed->False,Axes->False]
現在,這隻有一個問題。這裏不管PlotPoints
總是出現四個三角形,只有與任何其他相鄰三角形共享一條邊。但是我們希望所有的三角形至少與其他小箭頭共享兩個邊。如果我們使用belisarius方法,會發生這種情況。但是它會創建太小的三角形,我的面板解算器會拒絕它顯示爲零面積的混雜紋。
可以在這裏檢查我的方法的問題。這裏我們將使用Sjoerd的解決方法。
Export[NotebookDirectory[]<>"myres.obj",pic3D];
cd=Import[NotebookDirectory[]<>"myres.obj"];
polygons=(cd[[1]][[2]]/.GraphicsComplex-> List)[[2]][[1]][[1,1]];
pt=(cd[[1]][[2]]/.GraphicsComplex-> List)[[1]];
vertices=pt;
(*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]
(*Build a neighborhood list*)
triangleNeigbours=Table[Flatten[Position[relations[[i]],1]],{i,triangleEdges//Length}];
trires=Table[Flatten[{polygons[[i]],triangleNeigbours[[i]]}],{i,1,[email protected]}];
Cases[Cases[trires,x_:>Length[x]],4]
輸出顯示總是有四個三角形與其他人共享一條邊。
{4,4,4,4}
在belisarius方法的情況下,我們沒有看到這種情況發生,但我們得到的數字爲零的三角形區域。
BR
查看http://reference.wolfram.com/mathematica/TetGenLink/tutorial/Overview.html。它是專爲這種東西 –
@belisarius我已經使用TetGenLink,但它並不意味着這一點。它製作四面體實體網格。我需要一個表面網格。我實際上想要使用Mathematica生成的曲面網格。但是需要獲得由Graphics3D或GraphicsComplex定義的實體。我已經編寫了代碼來完成剩下的工作。它運作良好。但是我在這裏首先不能修補這個洞。最後TetGen不是一個解決方案。 – PlatoManiac
如果您有(例如)只有四個頂點,那麼您如何獲得一個解決方案,其中「所有三角形至少與其他三角形共享兩條邊」? –