Matlab计算错误的曲面法线?

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回答得到的结果:

在此输入图像描述

mag*_*ter 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
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似乎无法保持面片的正确方向。