# Spectral Mesh Flattening¶


This tour explores 2D flattening of 3D surfaces using spectral methods.

In [2]:
addpath('toolbox_signal')


## Spectral Mesh Flattening¶

Mesh flattening finds 2D locations that minimize a variational energy with a non-degenracy constraint (for instance maximal variance).

For the Dirichlet energy (Sobolev norm), the resulting location are described by the first eigenvectors of the Laplacian.

This method is refered to as "Laplacian eigenmaps" in manifold learning, see:

The advantage over fixed boundary harmonic parameterization is that the boundary of the flattened domain is not fixed, but the drawback is that the parameterization is not guaranteed to be valid (bijective).

In [3]:
name = 'nefertiti';
options.name = name;
n = size(vertex,2);


Display it.

In [4]:
clf;
plot_mesh(vertex,faces, options);


Compute the mesh Laplacian matrix.

In [5]:
options.symmetrize = 1;
options.normalize = 0;
L = compute_mesh_laplacian(vertex,faces,'conformal',options);


Compute the eigenvalues and eigenvectors

In [6]:
[U,S] = eig(full(L)); S = diag(S);
[S,I] = sort(S,'ascend'); U = U(:,I);


The vertex positions are the eigenvectors 2 and 3.

In [7]:
vertexF = U(:,2:3)';


Use translation / rotation to align the parameterization.

In [8]:
icenter = 88;
irotate = 154;
vertexF = vertexF - repmat(vertexF(:,icenter), [1 n]);
theta = -pi/2+atan2(vertexF(2,irotate),vertexF(1,irotate));
vertexF = [vertexF(1,:)*cos(theta)+vertexF(2,:)*sin(theta); ...
-vertexF(1,:)*sin(theta)+vertexF(2,:)*cos(theta)];


Display the flattened mesh.

In [9]:
clf;
plot_mesh(vertexF,faces);


Exercise 1

Perform the same flattening, but with the combinatorial Laplacian.

In [10]:
exo1()

In [11]:
%% Insert your code here.


## Geodesic Embedding (Isomap)¶

Another (nonlinear) embedding can be computed by minimizing the geodesic distortion between points on the surface and points over the parameterized domain.

First we compute the geodesic distance on the mesh using the Fast Marching algorithm.

In [12]:
D = zeros(n);
for i=1:n
D(:,i) = perform_fast_marching_mesh(vertex,faces,i);
end


Enforce symmetry.

In [13]:
D = (D+D')/2;


Compute the centered matrix.

In [14]:
J = eye(n) - ones(n)/n;
W = -J*(D.^2)*J;


Diagonalize the centered matrix.

In [15]:
[U,S] = eig(W);
S = diag(S);
[S,I] = sort(S,'descend'); U = U(:,I);


Display the decay of the eigenvalues. If the mesh was isometric to the plane, then only the two largest eigenvalues would be non zero.

In [16]:
clf;
hh = plot(S(1:30), '.-'); axis('tight');
set(hh, 'LineWidth', 2);