And*_*uri 5 matlab plot lighting
我有一个很大的FEM模型,从中我可以得到模型的"表面",比如定义FEM模型表面的元素和顶点.为了绘图目的(好的情节总是一个胜利!)我想很好地绘制它.我的方法就是使用
lungs.Vertex=vtx;
lungs.Faces=fcs;
patch(lungs,'facecolor','r','edgecolor','none')
Run Code Online (Sandbox Code Playgroud)
注意:我需要edgecolor none,因为这是4D数据,并且不同的FEM具有不同的三角测量,如果绘制边缘,则用户将头晕.

然而,这将输出一个非常纯红色的一切,这是不好的(因为它不能显示图的复杂性,这是肺,为细节的细心).
因此我决定使用ligthing:
camlight; camlight(-80,-10); lighting phong;
Run Code Online (Sandbox Code Playgroud)
但同样,这并不完全正确.实际上似乎Matlab没有正确计算补丁nromals.

我的假设是,补丁并不总是逆时针定义,因此一些法线会走向错误的方向.然而,这是不容易检查的事情.
任何人都有类似的问题,或者我应该怎样解决这个问题,以便在这里绘制一个漂亮的表面?
编辑
只是为了摇动绘图,这是@magnetometer回答得到的结果:

如果您的模型为您提供了向外的法线,您可以重新排序模型的面,以便 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
Run Code Online (Sandbox Code Playgroud)
如果您的 FEM 模型没有提供向外的法线,一种方法可能是使用地壳算法来重建表面,该算法可以为您提供向外的法线或正确定向的面片。
编辑:由于没有法线,我想到的唯一解决方案是重建表面。过去,这种地壳算法的实现对我来说效果很好。您需要做的就是:
[FacesNew,NormalsNew]=MyRobustCrust(Vertices);
Run Code Online (Sandbox Code Playgroud)
如果我没记错的话,FacesNew还没有逆时针方向,但是您可以使用SortFaces我上面发布的算法来纠正这一点,因为您现在已经正确定向了面法线,即运行:
[FaceCor,~]=SortFaces(FacesNew,NormalsNew,Vertices)
Run Code Online (Sandbox Code Playgroud)
如果您使用 Matlab reducepatch(例如reducedmodel=reducepatch(fullmodel,reduction);)来减少顶点数量,您将不得不再次重建表面,因为reducepatch似乎无法保持面片的正确方向。