zarquon42b / Rvcg

R-package providing mesh manipulation routines from VCGLIB
Other
25 stars 10 forks source link

Add maxdist parameter to vcgDijkstra #23

Closed dfsp-spirit closed 3 years ago

dfsp-spirit commented 3 years ago

This PR adds the maxdist parameter to the vcgDijkstra function. It allows early termination, and thus speedup, if one is only interested in the distances in a local neighborhood around each query vertex.

Background

The computation of geodesic distances on a mesh is a very expensive computation if ones needs the pairwise distances between all vertices. For a mesh of 160k vertices, this requires running vcgDijkstra 160k times, which takes several hours on my machine. The introduction of the maxdist parameter allows for a considerable speedup, depending on the requested neighborhood size:

library("Rvcg");
library("fsbrain");  # from devtools::install_github("dfsp-spirit/fsbrain", ref="geodesic")
surf = subject.surface(fsaverage.path(T), "fsaverage", hemi="lh", as_tm = TRUE); # load 160k verts brain mesh

# Now compare performance for a single computation over the full mesh versus in a neighborhood of size 50:
microbenchmark::microbenchmark(vcgDijkstra(surf, 1), vcgDijkstra(surf, 1, 50), times=100L);
Unit: milliseconds
                                            expr      min       lq      mean   median       uq      max neval
       vcgDijkstra(surf, 1) 81.11736 85.43365 102.47903 87.97617 94.71902 195.7131  100
 vcgDijkstra(surf, 1, 50) 29.14765 33.18125  44.01884 35.11710 37.59429 120.4902   100

Now reduce the requested neighborhood size further to 15 instead of 50:

microbenchmark::microbenchmark(vcgDijkstra(surf, 1), vcgDijkstra(surf, 1, 15), times=100L)
Unit: milliseconds
                     expr      min       lq     mean   median       uq       max neval
     vcgDijkstra(surf, 1) 76.89238 79.60710 82.71899 80.49687 84.38636 182.16545   100
 vcgDijkstra(surf, 1, 15) 16.25535 18.88795 20.74153 19.89646 22.24358  30.03371   100

Show the distances for the 50 neighborhood:

neigh = vcgDijkstra(surf, 1, 50);
neigh[neigh==0.0] = NA;  # cosmetic change for visualization, NA will be rendered as white
vis.data.on.fsaverage(morph_data_lh = neigh, views="si")

dijkstra_maxdist

zarquon42b commented 3 years ago

Looks great. Thank you.