find_roi_boundaries | R Documentation |
This function identifies the boundaries between regions of interest (ROIs) on a surface mesh. It supports multiple methods for boundary detection, including using faces, midpoints of edges, centroids of faces, edge vertices, and edge faces.
find_roi_boundaries(vertices, faces, vertex_id, boundary_method = "midpoint")
vertices |
A numeric matrix of vertex coordinates (n_vertices x 3). |
faces |
An integer matrix of face indices (n_faces x 3). Indices are 1-based. |
vertex_id |
An integer vector of ROI IDs for each vertex (length n_vertices). |
boundary_method |
A character string specifying the boundary detection method.
Options are |
This function identifies the boundaries between different regions of interest (ROIs) on a surface mesh. The algorithm works by analyzing the connectivity between vertices and faces with different ROI assignments.
The input must satisfy the following conditions:
'vertices' is a non-empty numeric matrix with three columns.
'faces' contains vertex indices between '1' and 'nrow(vertices)'.
'vertex_id' has length equal to 'nrow(vertices)'.
The boundary detection process follows these general steps:
Identify all edges in the mesh from the face definitions
Determine which edges cross between different ROIs
For each ROI, find connected components of boundary edges
Trace the boundary path for each component using graph theory algorithms
The different boundary_method
options produce different boundary representations:
"faces"
Simply identifies faces that contain vertices from multiple ROIs.
"midpoint"
Creates boundaries using midpoints of edges between different ROIs. This produces smooth boundaries that run between vertices.
"centroid"
Creates boundaries using centroids of faces along the boundary. This produces boundaries that run through the centers of triangular faces.
"edge_vertices"
Uses the actual vertices on ROI boundaries. This produces boundaries that follow the original mesh vertices.
"edge_faces"
Complex method that follows face relationships. This can produce more detailed boundaries but may be less stable.
The function relies on graph theory algorithms to find and trace boundary paths,
using adjacency matrices and shortest path algorithms to ensure boundaries form
complete cycles around each ROI component.
The structure of the return value depends on boundary_method
:
"faces"
boundary
is a logical vector marking boundary
faces. Other entries in the list are NULL
.
"midpoint"
boundary
contains coordinate matrices traced
through edge midpoints and boundary_verts
gives the vertex pairs used.
"centroid"
Boundaries are matrices of face centroid coordinates;
boundary_verts
is NULL
.
"edge_vertices"
Boundaries follow original vertices and the
indices are stored in boundary_verts
.
"edge_faces"
Similar to "edge_vertices"
but based on
face relationships; both boundary
and boundary_verts
are lists.
Example structure returned by the "faces"
method:
list( boundary = logical(n_faces), boundary_roi_id = NULL, roi_components = NULL, boundary_verts = NULL )
Example for path-based methods:
list( boundary = list(matrix(nrow, 3), ...), boundary_roi_id = integer(), roi_components = integer(), boundary_verts = list(matrix(nrow, 2), ...) )
A list containing:
boundary
The boundaries of the ROIs. The format depends on boundary_method
.
boundary_roi_id
A vector indicating to which ROI each boundary belongs.
roi_components
For each ROI, indicates how many components make it up.
boundary_verts
Vertices defining the boundaries, depends on boundary_method
.
# Create a simple toy mesh: a cube with 8 vertices and 12 triangular faces
# Define vertices (corners of a cube)
vertices <- matrix(c(
0, 0, 0, # vertex 1
1, 0, 0, # vertex 2
1, 1, 0, # vertex 3
0, 1, 0, # vertex 4
0, 0, 1, # vertex 5
1, 0, 1, # vertex 6
1, 1, 1, # vertex 7
0, 1, 1 # vertex 8
), ncol = 3, byrow = TRUE)
# Define faces (12 triangular faces making a cube)
faces <- matrix(c(
# bottom face (z=0)
1, 2, 3,
1, 3, 4,
# top face (z=1)
5, 6, 7,
5, 7, 8,
# front face (y=0)
1, 2, 6,
1, 6, 5,
# back face (y=1)
3, 4, 8,
3, 8, 7,
# left face (x=0)
1, 4, 8,
1, 8, 5,
# right face (x=1)
2, 3, 7,
2, 7, 6
), ncol = 3, byrow = TRUE)
# Define two ROIs: vertices 1-4 in ROI 1, vertices 5-8 in ROI 2
# This creates a boundary between the bottom half and top half of the cube
vertex_id <- c(1, 1, 1, 1, 2, 2, 2, 2)
# Find the boundaries between ROIs using midpoint method
boundary_result <- find_roi_boundaries(
vertices = vertices,
faces = faces,
vertex_id = vertex_id,
boundary_method = "midpoint"
)
# The result contains:
# - boundary: List of coordinate matrices for each boundary
# - boundary_roi_id: ROI ID for each boundary
# - roi_components: Number of components per ROI
# - boundary_verts: Vertices used to define each boundary
# To visualize (if rgl package is installed):
if (requireNamespace("rgl", quietly = TRUE)) {
# Plot the mesh
mesh <- rgl::tmesh3d(
vertices = t(vertices),
indices = t(faces),
homogeneous = FALSE
)
rgl::open3d()
rgl::shade3d(mesh, col = vertex_id)
# Plot the boundary
for (i in seq_along(boundary_result$boundary)) {
boundary_coords <- boundary_result$boundary[[i]]
rgl::lines3d(
boundary_coords[,1],
boundary_coords[,2],
boundary_coords[,3],
col = "black",
lwd = 3
)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.