2014-09-22 53 views
5

我有一個很大的有限元模型,我可以從中獲取模型的「表面」,比如定義該有限元模型表面的元素和頂點。爲了繪圖的目的(好的情節總是一場勝利!)我想很好地繪製它。我的做法是隻使用Matlab計算錯誤的表面法線?

lungs.Vertex=vtx; 
lungs.Faces=fcs; 
patch(lungs,'facecolor','r','edgecolor','none') 

注:我需要edgecolor沒有,因爲這是四維的數據和不同的FEM有不同的三角測量,如果邊緣繪製用戶會頭暈。

enter image description here

然而,這將輸出一切都在一個很普通的紅色,這是不是很好(因爲它不能顯示圖形的細節的複雜性,這是肺部,對於細心)。

因此我決定用ligthing:

camlight; camlight(-80,-10); lighting phong; 

但同樣,這是不完全正確的。事實上,似乎補丁的nromals不是由Matlab正確計算的。

enter image description here

我的猜想是,也許補丁並不總是定義逆時針,因此一些法線到錯誤的方向。然而,這不是直接檢查。

任何人都有類似的問題,或ahint我應該怎麼解決這個問題,以便在這裏繪製一個不錯的曲面?

編輯

只是爲了密謀的抖動,這裏是@magnetometer答案得到的結果:

enter image description here

回答

3

如果你的模式,您可以外向型法線,你可以重新排序模型的面,以便Matlab可以正確計算它自己的法線。下面的函數工作,如果你有個三角面和外向型法線:

function [FaceCor,nnew]=SortFaces(Faces,Normals,Vertices) 
FaceCor=Faces; 
nnew=Normals*0; 
for jj=1:size(Faces,1) 
    v1=Vertices(Faces(jj,3),:)-Vertices(Faces(jj,2),:); 
    v2=Vertices(Faces(jj,2),:)-Vertices(Faces(jj,1),:); 

    nvek=cross(v2,v1); %calculate normal vectors 
    nvek=nvek/norm(nvek); 
    nnew(jj,:)=nvek; 
    if dot(nvek,Normals(jj,:))<0 
     FaceCor(jj,:)=[Faces(jj,3) Faces(jj,2) Faces(jj,1)]; 
     nnew(jj,:)=-nvek; 
    end 

end 

如果您的有限元模型不給你向外的法線,一個辦法可能是使用重建例如表面一種地殼算法,可爲您提供外向法線或正確定向的貼片。

編輯: 因爲你沒有法線,唯一能解決的問題就是重建表面。 This implementation of the crust algorithm過去對我來說效果不錯。所有你需要做的是:

[FacesNew,NormalsNew]=MyRobustCrust(Vertices); 

如果我沒有記錯,FacesNew尚未面向逆時針方向,但你可以使用SortFaces算法我上面貼糾正這一點,因爲你現在已經正確導向面法線,即運行:

[FaceCor,~]=SortFaces(FacesNew,NormalsNew,Vertices) 

如果使用Matlab的reducepatch(如reducedmodel=reducepatch(fullmodel,reduction);),以減少頂點的數量,你將不得不再次重構表面,如reducepatch似乎並沒有讓補丁的正確方向。

+0

我絕對沒有法線,那就是問題所在。如果所有的法線都是「外向型」或「內向型」,那麼兩者都不會有任何問題,只需重新調整它們並妥善處理即可。但從圖片看來,有些人進入內部,有些進入了外部,使得製作錯誤。 – 2014-09-23 08:58:07

+0

確實非常非常有趣的功能。但我仍然有問題。我有「面對法線」,但似乎matlab希望「頂點法線」來設置照明。你如何建議我解決這個問題? Vertexnormals =平均值(facenormals_with_that_vertex)? – 2014-09-23 14:53:52

+0

我這樣做,得到了驚人的結果。非常感謝,這是一個非常好的答案。 – 2014-09-23 15:13:16