Matlab计算错误的曲面法线?

时间:2014-09-22 15:10:55

标签: matlab plot lighting

我有一个很大的FEM模型,从那里我可以得到"表面"对于模型,比如说定义FEM模型表面的元素和顶点。为了绘图目的(好的情节总是一个胜利!)我想很好地绘制它。我的方法就是使用

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

注意:我需要edgecolor none,因为这是4D数据,不同的FEM有不同的三角测量,如果边缘被绘制,用户将会头晕。

enter image description here

然而,这将输出一个非常纯红色的一切,这是不好的(因为它不能显示图形的复杂性,这是肺部,注意细节)。

因此我决定使用ligthing:

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

但同样,这并不完全正确。实际上,似乎Matlab没有正确计算补丁nromals。

enter image description here

我的假设是,补丁并非总是逆时针定义,因此一些法线会走向错误的方向。然而,这是不容易检查的事情。

任何人都有类似的问题,或者我应该怎样解决这个问题,以便在这里绘制一个漂亮的表面?

修改

只是为了摇动绘图,这是用@magnetometer回答得到的结果:

enter image description here

1 个答案:

答案 0 :(得分: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

如果你的FEM模型没有给你向外指向的法线,一种方法可能是使用例如重建表面。一种外壳算法,可以为您提供向外指向的法线或正确定向的补丁。

编辑: 由于你没有法线,我想到的唯一解决方案就是重建表面。 This implementation of the crust algorithm过去对我有用。您所需要做的就是:

[FacesNew,NormalsNew]=MyRobustCrust(Vertices);

如果我没记错的话,FacesNew还没有逆时针方向,但你可以使用我上面发布的SortFaces算法来纠正这个问题,因为你现在已经正确定向了面法线,即运行:

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

如果你使用Matlab的reducepatch(例如reducedmodel=reducepatch(fullmodel,reduction);)来减少顶点的数量,你将不得不重新重建表面,因为reducepatch似乎没有保持正确补丁的方向。