mesh_face_normals - Calculate face surface normals [normals,unit_normals,origins] = mesh_face_normals(FV) FV.vertices - vertices of mesh, Nx3 Cartesian XYZ FV.faces - triangulation of vertices (Mx3 matrix) normals - face surface normals (Mx3 matrix) unit_normals - normalized normals! origins - the point at the center of each face When calculating the surface normal, this function assumes the convention that the vertices are given in FV.faces in clockwise order: 1 /\ / \ e2/ \e1 / \ / \ /__________\ 3 2 We then define edge1 (e1) from vertex1 to vertex2 and edge2 (e2) from vertex1 to vertex3. The cross product of these two edge vectors gives the surface normal. The direction of the normal is either into the page or out of the page, depending on the order of the cross product, edge1 x edge2 = -1 * ( edge2 x edge1 ) So, the order of the vertex points, the direction of the edge vectors and their cross products are very important if you want a particular direction. In this function, we assume that the vertices of each face are given in clockwise order, when viewed from the "outside". The resulting surface normals are oriented "outward". Here is an example of how to view them: figure Hp = patch('faces',FV.faces,'vertices',FV.vertices,... 'facecolor',[.7 .7 .7],'facealpha',0.8,'edgecolor',[.8 .8 .8]); camlight('headlight','infinite'); daspect([1 1 1]); axis vis3d; axis off material dull; hold on [faceNormals,faceNormalsUnit,centroids] = mesh_face_normals(FV); quiver3(centroids(f,1),centroids(f,2),centroids(f,3),... faceNormals(f,1),faceNormals(f,2),faceNormals(f,3));
0001 function [faceNormals,unit_faceNormals,centroids] = mesh_face_normals(FV) 0002 0003 % mesh_face_normals - Calculate face surface normals 0004 % 0005 % [normals,unit_normals,origins] = mesh_face_normals(FV) 0006 % 0007 % FV.vertices - vertices of mesh, Nx3 Cartesian XYZ 0008 % FV.faces - triangulation of vertices (Mx3 matrix) 0009 % 0010 % normals - face surface normals (Mx3 matrix) 0011 % unit_normals - normalized normals! 0012 % 0013 % origins - the point at the center of each face 0014 % 0015 % When calculating the surface normal, this function assumes the convention 0016 % that the vertices are given in FV.faces in clockwise order: 0017 % 0018 % 1 0019 % /\ 0020 % / \ 0021 % e2/ \e1 0022 % / \ 0023 % / \ 0024 % /__________\ 0025 % 3 2 0026 % 0027 % We then define edge1 (e1) from vertex1 to vertex2 and edge2 (e2) from 0028 % vertex1 to vertex3. The cross product of these two edge vectors gives 0029 % the surface normal. The direction of the normal is either into the 0030 % page or out of the page, depending on the order of the cross product, 0031 % 0032 % edge1 x edge2 = -1 * ( edge2 x edge1 ) 0033 % 0034 % So, the order of the vertex points, the direction of the edge vectors 0035 % and their cross products are very important if you want a particular 0036 % direction. 0037 % 0038 % In this function, we assume that the vertices of each face are given in 0039 % clockwise order, when viewed from the "outside". The resulting surface 0040 % normals are oriented "outward". Here is an example of how to view them: 0041 % 0042 % figure 0043 % Hp = patch('faces',FV.faces,'vertices',FV.vertices,... 0044 % 'facecolor',[.7 .7 .7],'facealpha',0.8,'edgecolor',[.8 .8 .8]); 0045 % camlight('headlight','infinite'); daspect([1 1 1]); axis vis3d; axis off 0046 % material dull; hold on 0047 % [faceNormals,faceNormalsUnit,centroids] = mesh_face_normals(FV); 0048 % quiver3(centroids(f,1),centroids(f,2),centroids(f,3),... 0049 % faceNormals(f,1),faceNormals(f,2),faceNormals(f,3)); 0050 % 0051 0052 0053 % $Revision: 1.1 $ $Date: 2004/11/12 01:32:35 $ 0054 0055 % 0056 % Licence: GNU GPL, no implied or express warranties 0057 % History: 04/2004, Darren.Weber_at_radiology.ucsf.edu 0058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0059 0060 tic; 0061 fprintf('...calculating face surface normals...'); 0062 0063 nface = size(FV.faces,1); 0064 0065 faceNormals = zeros(nface,3); 0066 unit_faceNormals = faceNormals; 0067 centroids = faceNormals; 0068 0069 for f = 1:nface, 0070 0071 vertex_index1 = FV.faces(f,1); 0072 vertex_index2 = FV.faces(f,2); 0073 vertex_index3 = FV.faces(f,3); 0074 0075 vertex1 = FV.vertices(vertex_index1,:); 0076 vertex2 = FV.vertices(vertex_index2,:); 0077 vertex3 = FV.vertices(vertex_index3,:); 0078 0079 % If the vertices are given in clockwise order, when viewed from the 0080 % outside, then following calculates the "outward" surface normals. 0081 0082 edge_vector1 = vertex2 - vertex1; 0083 edge_vector2 = vertex3 - vertex1; 0084 0085 faceNormals(f,:) = cross( edge_vector2, edge_vector1 ); 0086 0087 magnitude = vector_magnitude(faceNormals(f,:)); 0088 0089 unit_faceNormals(f,:) = faceNormals(f,:) / magnitude; 0090 0091 0092 % Now find the midpoint between all vertices 0093 a = (vertex1 + vertex2) ./ 2; 0094 b = (vertex2 + vertex3) ./ 2; 0095 c = (vertex3 + vertex1) ./ 2; 0096 0097 % Now find the centroid length of the medians 0098 centroids(f,:) = b + ( (vertex1 - b) ./3 ); 0099 0100 end 0101 0102 t=toc; 0103 fprintf('done (%5.2f sec).\n',t); 0104 0105 return