Hausdorff distance between two triangle meshes

Alec Jacobson

June 23, 2015

weblog/

hausdorff distance

Unless I'm missing something the Hausdorff distance between two triangle meshes will be the maximum over the maximum minimum distance from the vertices of mesh A to the surface of mesh B and the maximum minimum distance from the vertices of mesh B to the surface of mesh A. That is, if p on A and q on B determine the Hausdorff distance between A and B, then it follows that p and/or q is a vertex of A or B respectively. This means you can compute Hausdorff distances easily if you already have a function to compute distances of points (vertices) to a triangle mesh.

So, I've added Hausdorff distance calculation between two meshes to my gptoolbox as the function hausdorff. Above I'm drawing the pair of points that determine the Hausdorff distance between the Cheburashka and the knight. I'm also drawing the intersection curves of these two meshes. Here's how I generate this image:

% compute Hausdorff distance and "determining" pair
[d,pair] = hausdorff(VA,FA,VB,FB);
% Mesh intersection, reindex as a single mesh
[SV,SF,~,J,IM] = selfintersect([VA;VB],[FA;size(VA,1)+FB]);
SF = IM(SF);
% Extract edges along intersection
allE = [SF(:,[2 3]); SF(:,[3 1]); SF(:,[1 2])];
sortallE = sort(allE,2);
[uE,~,IC] = unique(sortallE,'rows');
uE2F = sparse(IC(:),repmat(1:size(SF,1),1,3)',1);
BE = uE(any(uE2F(:,J<=size(FA,1)),2)&any(uE2F(:,J>size(FA,1)),2),:);

% Draw meshes, intersection lines and Hausdorff distance "determiner"
t = tsurf(SF,SV,'CData',1*(J<=size(FA,1)),'EdgeColor','none','FaceAlpha',0.6);
colormap([0.3 0.4 1.0;0.75 0.8 1.0]);axis equal;view(2);
t.SpecularStrength = 0;
t.DiffuseStrength = 0.7;
t.AmbientStrength = 0.3;
hold on;
plot_edges(SV,BE,'LineWidth',2,'Color',[0.7 0.65 0.55]);
p = tsurf([1 2 2],pair,'EdgeColor',[0.9 0.5 0.1],'LineWidth',6);
hold off;

drawnow; 
l = light('Position',[1 -1.5 1.8],'Style','infinite');
ht = add_shadow(t,l);
hp = add_shadow(p,l,'Ground',[0 0 -1 min(SV(:,3))]);
ht.FaceColor = [0.9 0.9 0.9];
hp.FaceColor = ht.FaceColor;
hp.EdgeColor = hp.FaceColor;
hp.LineWidth = p.LineWidth;
apply_ambient_occlusion(t);
set(gcf,'Color','w');
set(gca,'Visible','off');
camproj('persp');
view(-27,6);

Update: I was missing something. The "determiner" points might (at least) be lying on the edges. Consider the two different triangulations of a non-planar quad. For now, consider the libigl and gptoolbox versions of hausdorff distance to be broken. A hopeful patch would be to do in-plane subdivision once, so that there are vertices on all of the edge midpoints, but I'm hesitant to claim that this will fix the problem.

non planar quad