Nothing
#' Build an igraph from a triangular surface mesh
#'
#' Extracts unique edges from triangular faces, computes Euclidean edge weights,
#' and returns an igraph graph object suitable for geodesic distance
#' computation.
#'
#' @param vertices Numeric matrix (n x 3) of vertex coordinates.
#' @param faces Integer matrix (m x 3) of face indices (1-indexed).
#'
#' @return An `igraph` graph object with weighted edges.
#'
#' @references
#' Markello RD et al. (2022) Nature Methods 19:1472-1480.
#' doi:10.1038/s41592-022-01625-w
#'
#' @examples
#' vertices <- matrix(
#' c(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1),
#' nrow = 4, byrow = TRUE
#' )
#' faces <- matrix(c(1L, 2L, 3L, 2L, 3L, 4L), nrow = 2, byrow = TRUE)
#' g <- make_surf_graph(vertices, faces)
#' @export
make_surf_graph <- function(vertices, faces) {
if (!is.matrix(vertices) || ncol(vertices) != 3) {
cli::cli_abort("{.arg vertices} must be a matrix with 3 columns.")
}
if (!is.matrix(faces) || ncol(faces) != 3) {
cli::cli_abort("{.arg faces} must be a matrix with 3 columns.")
}
edges <- rbind(
faces[, c(1, 2)],
faces[, c(2, 3)],
faces[, c(1, 3)]
)
edges <- t(apply(edges, 1, sort))
edges <- unique(edges)
weights <- sqrt(rowSums((vertices[edges[, 1], ] - vertices[edges[, 2], ])^2))
igraph::graph_from_edgelist(edges, directed = FALSE) |>
igraph::set_edge_attr("weight", value = weights)
}
#' Compute geodesic distances on a surface mesh
#'
#' Builds a graph from a triangular mesh and computes shortest-path (Dijkstra)
#' distances between vertices.
#'
#' @param vertices Numeric matrix (n x 3) of vertex coordinates.
#' @param faces Integer matrix (m x 3) of face indices (1-indexed).
#' @param source_vertices Optional integer vector of source vertex indices.
#' If `NULL`, computes the full n x n distance matrix.
#'
#' @return Numeric distance matrix. If `source_vertices` is provided, returns
#' a `length(source_vertices) x n` matrix; otherwise an `n x n` matrix.
#'
#' @references
#' Markello RD et al. (2022) Nature Methods 19:1472-1480.
#' doi:10.1038/s41592-022-01625-w
#'
#' @examples
#' vertices <- matrix(
#' c(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1),
#' nrow = 4, byrow = TRUE
#' )
#' faces <- matrix(c(1L, 2L, 3L, 2L, 3L, 4L), nrow = 2, byrow = TRUE)
#' get_surface_distance(vertices, faces)
#' @export
get_surface_distance <- function(vertices, faces, source_vertices = NULL) {
g <- make_surf_graph(vertices, faces)
if (is.null(source_vertices)) {
igraph::distances(g, algorithm = "dijkstra")
} else {
igraph::distances(g, v = source_vertices, algorithm = "dijkstra")
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.