-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmesh_laplacian.m
86 lines (77 loc) · 3.08 KB
/
mesh_laplacian.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function [lap,edge] = mesh_laplacian(vertex,face)
% MESH_LAPLACIAN: Laplacian of irregular triangular mesh
%
% Useage: [lap,edge] = mesh_laplacian(vertex,face)
%
% Returns 'lap', the Laplacian (2nd spatial derivative) of an
% irregular triangular mesh, and 'edge', the linear distances
% between vertices of 'face'. 'lap' and 'edge' are square,
% [Nvertices,Nvertices] in size, sparse in nature.
%
% It is assumed that 'vertex' contains the (x,y,z) Cartesian
% coordinates of each vertex and that 'face' contains the
% triangulation of vertex with indices into 'vertex' that
% are numbered from 1:Nvertices. For information about
% triangulation, see 'help convhull' or 'help convhulln'.
%
% The neighbouring vertices of vertex 'i' is given by:
%
% k = find(edge(i,:));
%
% The math of this routine is given by:
%
% Oostendorp, Oosterom & Huiskamp (1989),
% Interpolation on a triangulated 3D surface.
% Journal of Computational Physics, 80: 331-343.
%
% See also, eeg_interp_scalp_mesh
%
% Licence: GNU GPL, no implied or express warranties
% History: 04/2002, Darren.Weber@flinders.edu.au
% - initial version was inefficient and incorrect
% at one point.
% (c) 04/2002 Robert Oostenveld
% - completely revised/reconstructed code (lapcal.m)
% - agreed to release into eeg_toolbox under GNU GPL
% 04/2002, Darren.Weber@flinders.edu.au
% - modified edge initialization from sparse to
% full matrix and slightly improved speed of
% calculation for edge norms
% - added tic/toc timing report
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nvertex = size(vertex,1);
nface = size(face,1);
fprintf('MESH_LAPLACIAN: Calc Laplacian matrix for %5d vertices...',nvertex);
tic
% the matrix 'edge' is the connectivity of all vertices
edge = zeros(nvertex);
for i=1:nface,
% compute the length of all triangle edges (Diff is [3x3])
Diff = [vertex(face(i,[1 2 3]),:) - vertex(face(i,[2 3 1]),:)];
Norm = sqrt( sum(Diff.^2, 2) );
edge(face(i,1),face(i,2)) = Norm(1);
edge(face(i,2),face(i,3)) = Norm(2);
edge(face(i,3),face(i,1)) = Norm(3);
% make sure that all edges are symmetric
edge(face(i,2),face(i,1)) = Norm(1);
edge(face(i,3),face(i,2)) = Norm(2);
edge(face(i,1),face(i,3)) = Norm(3);
end
% Using edge to identify nearest vertices, calculate
% the Laplacian for an irregular mesh
lap = zeros(nvertex);
for i=1:nvertex,
k = find(edge(i,:)); % the indices of the neighbours
ni = length(k); % the number of neighbours
hi = mean(edge(i,k)); % the average distance to the neighbours
invhi = mean(1./edge(i,k)); % the average inverse distance to the neighbours
lap(i,i) = -(4/hi) * invhi; % Laplacian of vertex itself
lap(i,k) = (4/(hi*ni)) * 1./edge(i,k); % Laplacian of direct neighbours
% Laplacian is zero for all indirect neighbours
% See Oostendorp, Oosterom & Huiskamp (1989, pp. 334-335)
end
edge = sparse(edge);
lap = sparse(lap);
t = toc;
fprintf('done (%6.2f sec).\n',t);
return